Home Getting Started Human Spec LLM Spec
Consider LLM-assisted authoring first

For most cases, having an LLM write your spec is faster and produces equally good results. Manual authoring makes sense when you want precise control, are learning the format, or don't have LLM access.

The structure

Every MAPI document has three parts:

  1. Document header — Title, description, and metadata
  2. Global types (optional) — Shared TypeScript interfaces
  3. Capabilities — One section per API operation

The Author Reference Card has the complete format. Keep it open as you write.

MAPI Author Reference Card

Complete format reference — skeletons, patterns, and examples

Fetch this page: https://markdownapi.org/specs/MAPI-AUTHOR.md

Or paste this prompt directly into your LLM chat

Document header

Start with a title (H1), description, and metadata block:

# Your API Name

A clear description of what this API does and who it's for.
One to three sentences is usually enough.

~~~meta
version: 1.0.0
base_url: https://api.example.com/v1
auth: bearer
~~~
Field Required Values
version Yes Semantic version (e.g., 1.0.0)
base_url Yes Root URL for all endpoints
auth Yes bearer, api_key, basic, oauth2, none

Capabilities

Each API operation is a capability. Separate them with ---:

---

## Capability: Create User

~~~meta
id: users.create
transport: HTTP POST /users
~~~

### Intention

Create a new user account. Use this when onboarding a new customer.
The email must be unique; attempting to create a duplicate returns 409.

### Logic Constraints

- Email addresses are case-insensitive and normalized to lowercase
- Password must be at least 8 characters with one number
- If `send_welcome_email` is true, an email is queued (not sent synchronously)

### Input

```typescript
interface CreateUserRequest {
  email: string;           // required, format: email
  password: string;        // required, length: 8-128
  name?: string;           // length: 1-100
  send_welcome_email?: boolean;  // default: true
}
```

### Output

~~~response 200
```typescript
interface User {
  id: string;
  email: string;
  name: string | null;
  created_at: string;  // ISO 8601
}
```
~~~

~~~response 409
```typescript
interface ConflictError {
  error: 'email_exists';
  message: string;
}
```
~~~

> Errors: standard (400, 401, 429, 500)

Transport strings

Pattern Meaning
HTTP GET /path GET request
HTTP POST /path POST request
HTTP GET /path/{id} Path parameter
HTTP POST /path (SSE) Server-Sent Events stream
WS /path WebSocket
INTERNAL Client-side only, no network

Constraint comments

Add constraints as TypeScript comments:

Pattern Example
// required name: string; // required
// range: min-max age: number; // range: 0-150
// length: min-max title: string; // length: 1-200
// default: value page?: number; // default: 1
// format: type email: string; // format: email
Writing good Intentions

Don't just describe what the endpoint does—explain when to use it and why. "Creates a user" is useless. "Create a new user account during customer onboarding. Email must be unique." tells the reader (human or LLM) what they need to know.

Validate your work

After writing, run your spec through validation to catch structural issues before they cause problems.