---
name: draft-api-docs
description: Use when the user says "draft API docs for {endpoint}" / "human docs for our OpenAPI spec" / "document this endpoint" — reads an OpenAPI spec (openapi.yaml / swagger.json) from the connected code host, or accepts a pasted representative request/response, and writes Stripe-grade human API docs per endpoint with purpose, params table, request body, response body, error codes, curl example, and SDK snippet. Draft only; never invents API behavior.
---

# Draft API Docs

## When to use

- User: "draft API docs for {endpoint}" / "write human docs from our
  OpenAPI spec" / "document the {resource} endpoint" / "docs for the
  `/v1/foo` API".
- Implicit trigger: user pastes a representative request/response
  and asks to turn it into docs.

## Steps

1. **Read engineering context.** Open
   `../head-of-engineering/engineering-context.md`. If missing or
   empty, stop and tell the user:
   > "I need the engineering context doc before I can draft API docs
   > that match your conventions. Run the Head of Engineering's
   > `define-engineering-context` first."

2. **Read config.** `config/docs-home.json` (docs-site conventions
   shape the output file layout) and `config/doc-audience.md` (API
   docs lean developer when audience is "developers building against
   the API").

3. **Resolve the spec.**
   - If the user gave a URL to `openapi.yaml` / `openapi.json` /
     `swagger.json`, fetch it (via `composio search web-search` or
     the code host).
   - If the user named the repo, run `composio search code-hosting`
     and look for the spec at conventional paths: `openapi.yaml`,
     `openapi.json`, `swagger.json`, `api/openapi.yaml`,
     `docs/openapi.yaml`, `spec/openapi.yaml`.
   - If no spec and no connected code host, ask ONE targeted
     question:
     > "Do you have an OpenAPI spec (paste the URL or path), or do
     > you want me to work from a pasted representative
     > request/response? Either works — a spec gets me every
     > endpoint; a paste gets me one."
   - Save resolved `{ owner, repo, specPath }` to `config/repo.json`
     if missing.

4. **Parse the spec** (or the pasted example) and enumerate endpoints
   the user wants documented. If the user named a specific endpoint
   (e.g. `POST /v1/charges`), scope to that one. If the user said
   "all endpoints" and there are > 10, ask: "That's {N} endpoints —
   group by resource (one file per resource) or one file per
   endpoint?"

5. **For each endpoint, write a docs section.** Stripe docs are the
   gold standard — curl-first, field-tables, error-tables. Structure:

   ```markdown
   ## {METHOD} {path}

   {One-sentence purpose. What the endpoint does for the caller.}

   ### Path parameters

   | Name | Type | Required | Description |
   |---|---|---|---|
   | `id` | string | yes | The resource ID. |

   ### Query parameters

   | Name | Type | Required | Default | Description |
   |---|---|---|---|---|
   | `limit` | integer | no | 10 | Max items returned (1-100). |

   ### Headers

   | Name | Required | Description |
   |---|---|---|
   | `Authorization` | yes | `Bearer {api-key}` |

   ### Request body

   ```json
   {
     "name": "Acme Widget",
     "price_cents": 4200
   }
   ```

   | Field | Type | Required | Description |
   |---|---|---|---|
   | `name` | string | yes | Display name of the widget. |
   | `price_cents` | integer | yes | Price in the smallest currency unit. |

   ### Response — `200 OK`

   ```json
   {
     "id": "wgt_abc123",
     "name": "Acme Widget",
     "price_cents": 4200,
     "created_at": "2026-04-22T10:00:00Z"
   }
   ```

   | Field | Type | Description |
   |---|---|---|
   | `id` | string | Unique ID, prefixed `wgt_`. |
   | ... | ... | ... |

   ### Errors

   | Code | When | Example body |
   |---|---|---|
   | `400 Bad Request` | Validation failed | `{ "error": "price_cents must be positive" }` |
   | `401 Unauthorized` | Missing / invalid API key | `{ "error": "auth required" }` |
   | `404 Not Found` | Resource does not exist | `{ "error": "widget not found" }` |

   ### Example — curl

   ```bash
   curl -X POST https://api.example.com/v1/widgets \
     -H "Authorization: Bearer $API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"name":"Acme Widget","price_cents":4200}'
   ```

   ### Example — SDK (if one exists)

   ```ts
   const widget = await client.widgets.create({
     name: "Acme Widget",
     priceCents: 4200,
   });
   ```
   ```

6. **Grounding rules — strict.**
   - Every field, type, and error code comes from the spec or a
     verified example. **Never invent API behavior.** If a field's
     description is missing from the spec, write `UNKNOWN` and add a
     note at the end of the file: "TODO: confirm `{field}` behavior
     with the implementer."
   - If the spec has no example, construct a minimal one from the
     field types and mark it `Example (synthesized)`.
   - If error codes aren't enumerated in the spec, write the common
     HTTP ones from the server type but label as `inferred from
     convention`.

7. **Write** to `api-docs/{endpoint-slug}.md` atomically. Slug is
   kebab of `{resource}-{method}` (e.g. `widgets-create.md`,
   `widgets-list.md`) — or `{resource}.md` if grouping multiple
   endpoints by resource. One file per endpoint OR one file per
   resource depending on step 4.

8. **Append to `outputs.json`** — one entry per file written
   (`type: "api-doc"`, `title: "API — {METHOD} {path}"` or `title:
   "API — {resource}"`, `summary: "{endpoint or resource} docs;
   {N} UNKNOWN fields flagged"`, `status: "draft"`, path,
   timestamps). Read-merge-write atomically.

9. **Summarize to user** — one paragraph: what was drafted, any
   UNKNOWN fields flagged for follow-up, and the path(s). Offer to
   re-run for additional endpoints.

## Hard nos

- **Never invent API behavior.** Missing fields / error codes get
  UNKNOWN + a TODO note. Do not fabricate.
- Never publish to a docs site directly — drafts land at my agent
  root; you paste into your docs tool.
- Never audit without reading `engineering-context.md` first.

## Outputs

- `api-docs/{endpoint-slug}.md` (one per endpoint) OR
  `api-docs/{resource}.md` (one per resource, grouped).
- Appends to `outputs.json` with `{ id, type: "api-doc", title,
  summary, path, status: "draft", createdAt, updatedAt }` per file.
