Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.markapidown.net/llms.txt

Use this file to discover all available pages before exploring further.

Every API endpoint in MarkApiDown is a single .md file living under api-docs/apis/<resource>/. Open it in any editor, commit it to version control, and review it in a pull request — no proprietary format, no binary blobs. The mad CLI reads these files directly to validate contracts and send real HTTP requests.

File location and naming

Place each endpoint spec at api-docs/apis/<resource>/<method>-<slug>.md. The resource maps to a logical group (e.g. posts, users, orders), and the slug is a short human-readable description of what the endpoint does.
Follow the <method>-<slug>.md naming convention so mad index can regenerate api-docs/README.md automatically and the browser UI can derive the HTTP method badge without parsing the file. Examples: get-post-by-id.md, create-post.md, delete-user.md.
api-docs/
└── apis/
    └── posts/
        ├── get-post-by-id.md
        └── create-post.md

Frontmatter fields

Every spec file opens with a YAML frontmatter block fenced by ---. MarkApiDown parses this block to know how to route and execute the request.

Required fields

resource
string
required
The resource group this endpoint belongs to (e.g. posts, users). Used to organize the browser UI and for tag filtering.
protocol
string
required
Transport protocol. Use http for all standard REST and HTTP APIs.
method
string
required
HTTP method in uppercase: GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS.
path
string
required
The URL path, relative to baseUrl. Use :paramName syntax for path parameters (e.g. /posts/:postId).
version
integer
required
Spec schema version. Always set to 1 for current MarkApiDown specs.

Optional fields

tags
string[]
A list of tags for grouping and filtering in the browser UI (e.g. [posts, read]).
env
string[]
The environments this endpoint is valid for (e.g. [dev, staging]). When omitted, the spec runs against any environment.
auth
string
Authentication strategy. Use none to skip auth, or reference a named auth scheme from mad.md (e.g. bearer).
timeout
integer
Request timeout in milliseconds. Overrides the project-level default in mad.md.
retry
object
Retry configuration. Set attempts (integer) and backoff (fixed or exponential) to automatically retry failed requests.

Sections

After the frontmatter and a short prose description, structure the file using these headings in order.

## Request

Write the outgoing HTTP request as a fenced http code block. The first line is the method and URL. Add headers on subsequent lines, then a blank line, then the body (if any).

## Expected response

Write the full expected HTTP response as a fenced http code block, starting with the status line. MarkApiDown diffs the actual response body against this block and highlights any mismatches in the browser UI.

## Assertions (optional)

List targeted checks that must pass for the execution to succeed. See Assertions for the full operator reference.

## Tests (optional)

An agent-task fenced block containing natural-language instructions for AI agents. The agent executes these steps using the MCP tools.

## Notes (optional)

Free-form markdown for team documentation — context, caveats, and links that help reviewers understand the endpoint.

Annotated GET example

The following spec fetches a single post by its numeric ID. It uses a path parameter (:postId) and reads baseUrl from the environment.
---
resource: posts
protocol: http
method: GET
path: /posts/:postId
tags: [posts, read]
version: 1
env: [dev]
auth: none
timeout: 5000
retry:
  attempts: 0
  backoff: fixed
---
# Get post by id

Fetches a single post by its stable numeric identifier.

## Request

\`\`\`http
GET {{baseUrl}}/posts/:postId
Accept: application/json
\`\`\`

## Expected response

\`\`\`http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "userId": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit"
}
\`\`\`

## Tests

\`\`\`agent-task
- Verify the response status is 200.
- Verify response.body.id equals postId.
- Verify response.body.userId is a positive integer.
- Verify response.body.title is a non-empty string.
\`\`\`

Path parameters

Declare path parameters in the path frontmatter field using the :param prefix. MarkApiDown substitutes the value at runtime from:
  • A matching variable in _shared/env.md for the active environment
  • A --var flag passed on the CLI (e.g. --var postId=42)
  • A value captured by a pipeline step and injected into downstream steps
In the ## Request block, repeat the same :param syntax in the URL path — do not wrap path params in {{ }}:
GET {{baseUrl}}/posts/:postId
{{baseUrl}} is a template variable resolved from the environment. :postId is a path parameter declared in the frontmatter.

Template variables {{variable}}

Use double-curly-brace syntax anywhere in the ## Request block — URL, headers, and body — to inject values from the active environment or from CLI --var flags.
POST {{baseUrl}}/posts
Content-Type: application/json
Authorization: Bearer {{apiToken}}

{
  "userId": {{userId}},
  "title": "Hello world"
}
MarkApiDown resolves {{baseUrl}}, {{apiToken}}, and {{userId}} at execution time using the variable resolution order. Unresolved variables are reported as an error before the request is sent.

POST example with a JSON body

The following spec creates a new post. Notice how {{userId}} in the request body is substituted from the environment, and the ## Expected response block captures only the fields you care about.
---
resource: posts
protocol: http
method: POST
path: /posts
tags: [posts, write]
version: 1
env: [dev]
auth: none
timeout: 5000
retry:
  attempts: 0
  backoff: fixed
---
# Create post

Creates a new post. JSONPlaceholder simulates the create and returns a
fake resource with id 101.

## Request

\`\`\`http
POST {{baseUrl}}/posts
Content-Type: application/json
Accept: application/json

{
  "title": "My new post",
  "body": "Post content goes here.",
  "userId": {{userId}}
}
\`\`\`

## Expected response

\`\`\`http
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": 101
}
\`\`\`

## Tests

\`\`\`agent-task
- Verify the response status is 201.
- Verify response.body.id is a positive integer.
- Verify the request body was echoed back in the response.
\`\`\`
Run mad exec api-docs/apis/posts/create-post.md --env=dev --dry-run to preview the fully resolved request — with all variables substituted and headers rendered — without sending it to the server. This is the fastest way to catch template or path-parameter typos before a real request goes out.