Markdown API testing that runs

How runnable Markdown API specs turn request examples into executable contracts, local UI screens, CI checks, and coding-agent context.

Tutorial rqb exec api-docs/

Markdown API testing sounds almost too simple: write the request in Markdown, write the expected response under it, and run the file.

The useful part is not that the file is Markdown. The useful part is that Markdown is the artifact developers already accept in docs, pull requests, and code review. If that same artifact can execute, API examples stop being passive documentation and start catching drift.

Reqbook API runner showing a passed response from a runnable Markdown API spec

Anatomy of a runnable Markdown API contract

A README example is not an API test

Most API docs start with a request example like this:

curl http://localhost:8080/users/123

That example helps once. Then the implementation changes, the example goes stale, and nobody notices until a customer, teammate, or coding agent copies it into a task.

A runnable Markdown API spec keeps the example and the contract together:

# Get user by id

Fetches a single user record by stable user identifier.

## Request

```http
GET {{baseUrl}}/users/:userId
Accept: application/json
```

## Expected response

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

{
  "id": "{{userId}}",
  "email": "ada@example.test"
}
```

## Assertions

- status: 200
- body.id: exists
- body.email: contains @

Now the file is still readable in a browser or pull request, but it can also run:

rqb exec api-docs/apis/users/get-user-by-id.md

The contract has five jobs

A good Markdown API test should do five jobs without becoming hard to read.

SectionJob
Title and introExplain why the endpoint exists.
## RequestProvide the exact method, URL, headers, and body.
## Expected responseDefine the status and stable response shape.
## AssertionsMake the success criteria machine-readable.
## Notes or ## TestsGive humans and agents the edge cases worth checking.

This makes the file useful across roles:

  • Backend developers can run it while changing handlers.
  • Reviewers can inspect it in a pull request.
  • CI can execute it as a smoke test.
  • Coding agents can read it before editing code.
  • New contributors can learn the endpoint without opening a hosted workspace.

Use variables, not hardcoded environments

Markdown API testing becomes reliable when environment details are separated from the spec.

# api-docs/_shared/env.md

## dev

```yaml
baseUrl: http://localhost:8080
userId: usr_demo_123
```

The endpoint can now reference {{baseUrl}} and :userId without hardcoding local URLs into every file:

GET {{baseUrl}}/users/:userId

Secrets stay out of committed Markdown. Put tokens in .env.local, CI secrets, or RQB_* environment variables.

Keep assertions small and stable

The mistake with early API tests is asserting too much. If you assert every field in a large response, the test fails on unrelated metadata changes. If you assert only status == 200, the test catches almost nothing.

Start with stable assertions:

## Assertions

- status: 201
- body.id: exists
- body.status: in [pending_verification, active]
- headers.content-type: contains application/json

That says what must be true without pretending the whole response will never change.

If your team needs stricter contracts, the next product priority in Reqbook is explicit response match modes: shape, strict, and schema. That will let teams choose forgiving documentation checks for early specs and strict JSON/schema checks for critical endpoints.

Run the same Markdown in four places

Once the contract is in api-docs/, the same file supports multiple workflows:

# Catch malformed specs before commit
rqb validate api-docs/

# Execute one endpoint
rqb exec api-docs/apis/users/get-user-by-id.md

# Run a business flow
rqb flow api-docs/flows/signup-login-profile.md

# Open a local browser UI
rqb serve

For local demos and frontend work, recorded expected responses can become a mock API:

rqb mock api-docs --port 4001

That is especially useful for checkout, onboarding, billing, and other flows where frontend or agent work needs a predictable API shape.

How this fits beside Hurl

Hurl is excellent when you want a compact command-line HTTP test runner with plain-text files, captures, assertions, and reports. If your primary need is terse HTTP testing in CI, Hurl is a strong choice.

Reqbook aims at a different center: documentation-first API contracts. The file should be comfortable for a developer to read in a pull request and helpful for an agent to use as context before changing source code.

In practice:

  • Use Hurl when the test is the product.
  • Use Reqbook when the docs, test, PR review, and agent context should be one artifact.

A CI workflow that keeps docs honest

Use validation in every pull request:

- name: Validate Markdown API specs
  run: rqb validate api-docs/

When the backend can run in CI, execute the important flows:

- name: Run onboarding API flow
  run: rqb flow api-docs/flows/signup-login-profile.md --env ci

That makes stale examples visible. If a route changes from 201 to 200, or a response field disappears, the contract has to be updated in the same PR as the code.

Start with one useful journey

Do not convert every endpoint on day one. Pick one journey that matters:

  • signup -> login -> current profile,
  • create cart -> add item -> checkout session,
  • create issue -> add comment -> close issue,
  • create workspace -> invite member -> list members.

Create the endpoint specs, add one flow, run rqb validate, then open rqb serve beside your editor. Once the first journey works, expand from there.

Update contracts when behavior changes

A runnable Markdown API spec should change in the same pull request as the API behavior. If an endpoint intentionally returns a new status code, adds a required field, or removes a response property, update the ## Expected response block and assertions with the implementation.

That is the discipline that makes markdown API testing useful for SEO, docs, agents, and CI at the same time. The article people read is the same artifact the command runs. When the behavior changes, the documentation and test history change with it.

For agent-specific workflows, read API testing for coding agents. For positioning against GUI-first API workflows, read A local-first API workspace for agent workflows or jump to the comparison section.