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:

---
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

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

WebSocket Events

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

Group endpoints under sections in your syntext.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:

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

Renders as a styled badge:

Parameter Documentation

Request Parameters

Use <ParamField> to document parameters:

<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:

<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:

<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>:

<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:

## 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:

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

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

Complete Example

Here's a full endpoint page:

---
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"
}
}
\`\`\`
Was this page helpful?