---
title: API Documentation
description: How to create beautiful API reference documentation with Syntext.
---

# API Documentation

This guide shows how to create structured API reference documentation with individual endpoint pages, grouped navigation, and rich parameter documentation.

## Structure

Syntext recommends organizing API docs with one file per endpoint:

```
docs/
├── api-reference/
│   ├── overview.mdx           # API introduction
│   ├── authentication.mdx     # Auth guide
│   ├── projects/
│   │   ├── list.mdx          # GET /projects
│   │   ├── get.mdx           # GET /projects/{id}
│   │   ├── create.mdx        # POST /projects
│   │   ├── update.mdx        # PATCH /projects/{id}
│   │   └── delete.mdx        # DELETE /projects/{id}
│   ├── builds/
│   │   ├── list.mdx
│   │   ├── get.mdx
│   │   └── trigger.mdx
│   └── search/
│       └── query.mdx
```

## Endpoint Frontmatter

Each endpoint file should include protocol-specific frontmatter:

```mdx
---
title: Create Project
protocol: rest
method: POST
endpoint: /v1/projects
description: "Create a new documentation project"
---
```

### REST Endpoints

| Field | Required | Description |
|-------|----------|-------------|
| `title` | Yes | Page title and sidebar label |
| `protocol` | Yes | Set to `rest` |
| `method` | Yes | HTTP method: `GET`, `POST`, `PATCH`, `DELETE` |
| `endpoint` | Yes | API path (e.g., `/v1/projects/{id}`) |
| `description` | No | Brief description for search results |

### GraphQL Operations

```mdx
---
title: Get Session
protocol: graphql
operation: query
name: GetSession
---
```

### WebSocket Events

```mdx
---
title: Session Connected
protocol: websocket
event: session.connected
direction: server-to-client
---
```

## Navigation with Sections

Group endpoints under sections in your `syntext.json`:

```json
{
  "navigation": [
    {
      "group": "API Reference",
      "pages": [
        "api-reference/overview",
        "api-reference/authentication"
      ]
    },
    {
      "group": "Projects",
      "section": "API Reference",
      "pages": [
        "api-reference/projects/list",
        "api-reference/projects/get",
        "api-reference/projects/create",
        "api-reference/projects/update",
        "api-reference/projects/delete"
      ]
    },
    {
      "group": "Builds",
      "section": "API Reference",
      "pages": [
        "api-reference/builds/list",
        "api-reference/builds/get",
        "api-reference/builds/trigger"
      ]
    }
  ]
}
```

The `section` field nests the group under its parent section in the sidebar.

## Endpoint Component

Use the `<Endpoint>` component to display the method and path:

```mdx
<Endpoint method="POST" path="/v1/projects" />
```

Renders as a styled badge:

<Endpoint method="POST" path="/v1/projects" />

## Parameter Documentation

### Request Parameters

Use `<ParamField>` to document parameters:

```mdx
<ParamField body="name" type="string" required>
  Project display name.
</ParamField>

<ParamField query="page" type="integer" default="1">
  Page number for pagination.
</ParamField>

<ParamField path="projectId" type="string" required>
  The project ID (e.g., `prj_abc123`).
</ParamField>

<ParamField header="X-Request-Id" type="string">
  Optional request tracking ID.
</ParamField>
```

#### ParamField Props

| Prop | Type | Description |
|------|------|-------------|
| `body` | string | Body parameter name |
| `query` | string | Query string parameter name |
| `path` | string | Path parameter name |
| `header` | string | Header name |
| `type` | string | Data type (e.g., `string`, `integer`, `boolean`, `object`) |
| `required` | boolean | Whether the parameter is required |
| `default` | string | Default value |

### Nested Objects

Use `<Expandable>` for nested object properties:

```mdx
<ParamField body="settings" type="object">
  Project settings.

  <Expandable title="properties">
    <ParamField body="settings.aiEnabled" type="boolean" default="true">
      Enable AI assistant.
    </ParamField>

    <ParamField body="settings.searchEnabled" type="boolean" default="true">
      Enable full-text search.
    </ParamField>
  </Expandable>
</ParamField>
```

## Response Documentation

Use `<ResponseField>` for response properties:

```mdx
<ResponseField name="data" type="object">
  The response payload.

  <Expandable title="properties">
    <ResponseField name="id" type="string">
      Unique identifier.
    </ResponseField>

    <ResponseField name="name" type="string">
      Display name.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp.
    </ResponseField>
  </Expandable>
</ResponseField>
```

## Code Examples

Include examples in multiple languages using `<CodeGroup>`:

```mdx
<CodeGroup>
\`\`\`bash cURL
curl -X POST https://api.example.com/v1/projects \\
  -H "Authorization: Bearer stx_abc12345_..." \\
  -H "Content-Type: application/json" \\
  -d '{"name": "My Project"}'
\`\`\`

\`\`\`typescript SDK
import { Client } from '@example/sdk'

const client = new Client('stx_abc12345_...')
const project = await client.projects.create({
  name: 'My Project',
})
\`\`\`

\`\`\`python Python
from example import Client

client = Client("stx_abc12345_...")
project = client.projects.create(name="My Project")
\`\`\`
</CodeGroup>
```

## Error Documentation

Document error responses with HTTP status codes and response body examples:

```mdx
## Error Responses

### 400 Bad Request

Returned when required fields are missing or have invalid values.

\`\`\`json
{
  "error": {
    "code": "invalid_request",
    "message": "Required field missing or invalid value",
    "details": {
      "field": "name",
      "issue": "Name is required"
    }
  }
}
\`\`\`

### 404 Not Found

Returned when the resource does not exist.

\`\`\`json
{
  "error": {
    "code": "not_found",
    "message": "Resource does not exist"
  }
}
\`\`\`

### 409 Conflict

Returned when a resource with this identifier already exists.

\`\`\`json
{
  "error": {
    "code": "conflict",
    "message": "Resource with this identifier already exists"
  }
}
\`\`\`

### 429 Too Many Requests

Returned when the rate limit has been exceeded.

\`\`\`json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Try again later.",
    "retryAfter": 60
  }
}
\`\`\`
```

## OpenAPI Import

If you have an OpenAPI spec, Syntext can auto-generate endpoint pages:

```bash
stx generate --openapi ./openapi.json --output docs/api-reference
```

This creates individual MDX files for each endpoint with:
- Frontmatter from operation metadata
- Parameter documentation from schemas
- Example request/response bodies
- Error codes from response definitions

<Note>
Generated pages are fully editable MDX. Add custom content, examples, or notes as needed.
</Note>

## Complete Example

Here's a full endpoint page:

```mdx
---
title: Create Project
protocol: rest
method: POST
endpoint: /v1/projects
description: "Create a new documentation project"
---

# Create Project

Create a new documentation project in your organization.

<Endpoint method="POST" path="/v1/projects" />

## Request Body

<ParamField body="name" type="string" required>
  Project display name.
</ParamField>

<ParamField body="slug" type="string">
  URL-friendly identifier. Auto-generated if not provided.
</ParamField>

<ParamField body="settings" type="object">
  Project settings.

  <Expandable title="properties">
    <ParamField body="settings.aiEnabled" type="boolean" default="true">
      Enable AI assistant.
    </ParamField>
  </Expandable>
</ParamField>

## Response

<ResponseField name="data" type="object">
  The created project.

  <Expandable title="properties">
    <ResponseField name="id" type="string">
      Project identifier.
    </ResponseField>

    <ResponseField name="name" type="string">
      Project name.
    </ResponseField>
  </Expandable>
</ResponseField>

## Example

<CodeGroup>
\`\`\`bash cURL
curl -X POST https://api.example.com/v1/projects \\
  -H "Authorization: Bearer stx_abc12345_..." \\
  -d '{"name": "My Docs"}'
\`\`\`
</CodeGroup>

## Error Responses

### 400 Bad Request

\`\`\`json
{
  "error": {
    "code": "invalid_request",
    "message": "Missing required field: name"
  }
}
\`\`\`

### 409 Conflict

\`\`\`json
{
  "error": {
    "code": "conflict",
    "message": "A project with this slug already exists"
  }
}
\`\`\`
```
