# daloyjs.dev API reference

This site runs a small public API for coding agents and tools: discovery catalogs, an OAuth token endpoint, the [docs MCP server](/docs/mcp), and a markdown copy of every page. This page is generated from the same OpenAPI 3.1 document the site serves at [`/openapi.json`](/openapi.json), so the reference and the spec cannot drift apart.

**Diagram: How an agent uses the site API**

1. **Discover** - GET /.well-known/api-catalog
2. **Get a token** - POST /oauth/token (client_credentials)
3. **Call** - GET /api/v1 or POST /mcp with Bearer token
4. **Read pages** - GET /md/{path} as markdown

Discovery and markdown pages are public. The versioned API and MCP accept a short-lived docs:read token from the public client_credentials grant; every response carries IETF RateLimit headers.

> [!NOTE]
> **Try it runs in your browser**
> The **Try it** buttons send a same-origin `GET` from this page to this site, only for public operations with no parameters. Nothing you type is sent anywhere, and there is no proxy involved.

## Authentication

Operations marked **Requires a token** need a bearer token, and **Token optional** ones accept one but also answer anonymously. Tokens come from the public `client_credentials` grant: there is no client secret, and the token only grants the read-only `docs:read` scope.

```bash title="Get a token"
curl -X POST https://daloyjs.dev/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'grant_type=client_credentials&scope=docs:read'
```

Versioning, deprecation headers and the sunset policy are covered in [API lifecycle](/docs/api-lifecycle) and [API versioning](/docs/api-versioning).

## Discovery

Catalogs agents should fetch first.

### JSON index of DaloyJS website APIs (v1)

GET `/api/v1` Token optional

The catalog also publishes the whole versioning and deprecation policy under `versioning`, including every surface's status, successor, and sunset date.

#### Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `API-Version` | `"1" \| "v1" \| "1.0" \| "1.0.0"` |  | headerPin the API major. Accepted: 1, v1, 1.0, 1.0.0. Any other value returns 400 unsupported_api_version instead of silently serving a different major. |

#### Responses

- 200 Catalog of machine endpoints on this origin. `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `name` (required) | `string` |  |  |
  | `description` (required) | `string` |  |  |
  | `version` (required) | `string` |  |  |
  | `versioning` | `object` |  |  |
  | `links` (required) | `object` |  |  |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 400 The API-Version request header pinned a major this origin does not serve (code `unsupported_api_version`). `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |
- default RFC 9457 problem+json with an error code and a recovery hint. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/api/v1' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /api/v1`

### Unversioned alias for the current major

GET `/api` Token optional

Permanently redirects to /api/v1 so an agent never pins an unversioned path. The redirect carries rel="successor-version" and rel="latest-version" link relations.

#### Responses

- 308 Permanent redirect to the current major.

  Headers (3)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `Location` | `string` |  | The versioned path, e.g. /api/v1. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Link` | `string` |  | RFC 5829 rel="successor-version" and rel="latest-version". |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/api' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /api`

### DaloyJS website OpenAPI 3.1 document

GET `/openapi.json` Token optional

#### Responses

- 200 This OpenAPI document. `application/json`

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |
- default RFC 9457 problem+json with an error code and a recovery hint. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/openapi.json' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /openapi.json`

### RFC 9727 API catalog linkset

GET `/.well-known/api-catalog` Token optional

#### Responses

- 200 Linkset pointing at OpenAPI and the docs MCP. `application/linkset+json`

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/.well-known/api-catalog' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /.well-known/api-catalog`

### Curated Markdown index of the site for agents

GET `/llms.txt` Token optional

#### Responses

- 200 llms.txt v2 document. `text/plain`

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/llms.txt' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /llms.txt`

## Docs MCP

Read-only Model Context Protocol for the documentation.

### MCP Server Card for the docs MCP server (draft)

GET `/.well-known/mcp/server-card.json` Token optional

Discovery metadata for POST /mcp: transport, protocol version, capabilities, authentication, and the full tool list with input schemas. Follows the draft MCP Server Cards proposal (SEP-1649), which may change before it reaches a released MCP specification.

#### Responses

- 200 The Server Card. `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `$schema` (required) | `string<uri>` |  |  |
  | `version` (required) | `string` |  |  |
  | `protocolVersion` (required) | `string` |  |  |
  | `serverInfo` (required) | `object` |  |  |
  | `serverInfo.name` (required) | `string` |  |  |
  | `serverInfo.title` | `string` |  |  |
  | `serverInfo.version` (required) | `string` |  |  |
  | `description` | `string` |  |  |
  | `iconUrl` | `string<uri>` |  |  |
  | `documentationUrl` | `string<uri>` |  |  |
  | `transport` (required) | `object` |  |  |
  | `transport.type` (required) | `"streamable-http"` |  |  |
  | `transport.endpoint` (required) | `string<uri>` |  |  |
  | `capabilities` (required) | `object` |  |  |
  | `authentication` | `object` |  |  |
  | `authentication.required` (required) | `boolean` |  |  |
  | `authentication.schemes` (required) | `string[]` |  |  |
  | `instructions` | `string` |  |  |
  | `tools` | `object[]` |  |  |
  | `tools[].name` (required) | `string` |  |  |
  | `tools[].title` | `string` |  |  |
  | `tools[].description` | `string` |  |  |
  | `tools[].inputSchema` (required) | `object` |  |  |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/.well-known/mcp/server-card.json' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /.well-known/mcp/server-card.json`

### DaloyJS MCP server (JSON-RPC 2.0 over Streamable HTTP)

POST `/mcp` Token optional

Read-only tools: search_docs, get_doc, list_docs. Send JSON-RPC 2.0. GET on this URL returns 405 with a JSON hint. Bearer docs:read is optional.

#### Request body `application/json`

#### Responses

- 200 JSON-RPC result or error envelope. `application/json`

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 400 RFC 9457 problem+json with an error code and a recovery hint. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 405 RFC 9457 problem+json with an error code and a recovery hint. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 413 RFC 9457 problem+json with an error code and a recovery hint. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X POST 'https://daloyjs.dev/mcp' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{}'
```

## OAuth

RFC 8414 authorization server and client_credentials token grant.

### RFC 8414 OAuth 2.0 authorization-server metadata

GET `/.well-known/oauth-authorization-server` Token optional

#### Responses

- 200 Authorization-server metadata JSON. `application/json`

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/.well-known/oauth-authorization-server' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /.well-known/oauth-authorization-server`

### RFC 9728 OAuth 2.0 protected-resource metadata

GET `/.well-known/oauth-protected-resource` Token optional

#### Responses

- 200 Protected-resource metadata, including scopes_supported. `application/json`

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/.well-known/oauth-protected-resource' \
  -H "Authorization: Bearer $TOKEN"
```

Try it

`GET /.well-known/oauth-protected-resource`

### OAuth 2.0 client_credentials token endpoint

POST `/oauth/token`

Public client. Send grant_type=client_credentials and optional scope=docs:read as application/x-www-form-urlencoded. No client_secret.

#### Request body `application/x-www-form-urlencoded`

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `grant_type` (required) | `"client_credentials"` |  |  |
| `scope` | `"docs:read"` |  |  |
| `client_id` | `string` |  |  |

#### Responses

- 200 Access token response (RFC 6749 §5.1). `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `access_token` (required) | `string` |  |  |
  | `token_type` (required) | `"Bearer"` |  |  |
  | `expires_in` (required) | `integer` |  |  |
  | `scope` (required) | `"docs:read"` |  |  |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 400 OAuth error (RFC 6749 §5.2). `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `error` (required) | `string` |  |  |
  | `error_description` (required) | `string` |  |  |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X POST 'https://daloyjs.dev/oauth/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'grant_type=client_credentials&scope=docs:read&client_id=…'
```

### Authorization endpoint (client_credentials only)

GET `/oauth/authorize`

Advertised by the RFC 8414 metadata. This server implements no browser redirect flow, so it answers with an RFC 6749 §4.1.2.1 unsupported_response_type error pointing at the token endpoint. Probes get live JSON rather than an HTML 404.

#### Responses

- 400 OAuth error (RFC 6749 §5.2). `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `error` (required) | `string` |  |  |
  | `error_description` (required) | `string` |  |  |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/oauth/authorize'
```

Try it

`GET /oauth/authorize`

### OAuth 2.0 token introspection (RFC 7662)

POST `/oauth/introspect`

Confirm that a token minted by this origin is still active and which scope it carries. No client authentication: the only issued scope covers public documentation. Unknown or expired tokens return { active: false }.

#### Request body `application/x-www-form-urlencoded`

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `token` (required) | `string` |  |  |
| `token_type_hint` | `"access_token"` |  |  |

#### Responses

- 200 Introspection response (RFC 7662 §2.2). `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `active` (required) | `boolean` |  |  |
  | `scope` | `string` |  |  |
  | `token_type` | `string` |  |  |
  | `iss` | `string` |  |  |
  | `aud` | `string` |  |  |
  | `iat` | `integer` |  |  |
  | `exp` | `integer` |  |  |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 400 OAuth error (RFC 6749 §5.2). `application/json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `error` (required) | `string` |  |  |
  | `error_description` (required) | `string` |  |  |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X POST 'https://daloyjs.dev/oauth/introspect' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'token=…&token_type_hint=access_token'
```

### RFC 9728 §3.1 per-resource protected-resource metadata

GET `/.well-known/oauth-protected-resource/{resource}` Token optional

Metadata for one resource on this origin, located by inserting the resource path after the well-known prefix. MCP clients resolve /.well-known/oauth-protected-resource/mcp before attaching a token.

#### Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `resource` (required) | `string` |  | pathResource path without the leading slash. |

#### Responses

- 200 Protected-resource metadata, including scopes_supported. `application/json`

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 404 RFC 9457 problem+json with an error code and a recovery hint. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/.well-known/oauth-protected-resource/{resource}' \
  -H "Authorization: Bearer $TOKEN"
```

## Markdown

Markdown representations of public pages, for agents that would rather not parse HTML.

### Markdown representation of any public page

GET `/md/{path}` Token optional

Also reachable by appending `.md` to a page URL, or by sending `Accept: text/markdown` to the canonical URL. Responses set `Vary: Accept`.

#### Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `path` (required) | `string` |  | pathPage path without the leading slash. |

#### Responses

- 200 Markdown body of the page. `text/markdown`

  Headers (6)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
- 404 No such page. The Markdown body lists recovery entry points. `text/markdown`
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/md/{path}' \
  -H "Authorization: Bearer $TOKEN"
```

### Legacy Markdown handler for cached /docs/*.md destinations

GET `/docs-md/{path}` Token optional Deprecated

Deprecated in favour of /md/docs/{path}. Every response carries an RFC 9745 Deprecation date and RFC 8288 deprecation / successor-version relations. No Sunset date is scheduled; one will be announced at least 180 days ahead. Policy: https://daloyjs.dev/docs/api-lifecycle.

#### Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `path` (required) | `string` |  | pathDocs path without the leading slash. |

#### Responses

- 200 Markdown body of the docs page. `text/markdown`

  Headers (9)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Deprecation` | `string` |  | RFC 9745 structured-field Date marking when this surface was deprecated, e.g. @1756944000. |
  | `Sunset` | `string` |  | RFC 8594 IMF-fixdate for the scheduled retirement. Absent while no retirement is scheduled; never set less than 180 days ahead. |
  | `Link` | `string` |  | RFC 8288 relations: rel="deprecation", rel="sunset", rel="successor-version", rel="latest-version". |
- 404 No such docs page. `text/markdown`

  Headers (9)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Deprecation` | `string` |  | RFC 9745 structured-field Date marking when this surface was deprecated, e.g. @1756944000. |
  | `Sunset` | `string` |  | RFC 8594 IMF-fixdate for the scheduled retirement. Absent while no retirement is scheduled; never set less than 180 days ahead. |
  | `Link` | `string` |  | RFC 8288 relations: rel="deprecation", rel="sunset", rel="successor-version", rel="latest-version". |
- 429 Quota exhausted. Honor Retry-After and retry. RateLimit remaining is 0. `application/problem+json`

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `type` (required) | `string<uri>` |  |  |
  | `title` (required) | `string` |  |  |
  | `status` (required) | `integer` |  |  |
  | `detail` (required) | `string` |  |  |
  | `instance` | `string` |  |  |
  | `code` (required) | `string` |  | Machine-readable error code (snake_case). |
  | `hint` (required) | `string` |  | What the caller should do next to recover. |

  Headers (7)

  | Property | Type | Default | Description |
  | --- | --- | --- | --- |
  | `RateLimit` | `string` |  | IETF RateLimit header (draft-ietf-httpapi-ratelimit-headers). Example: "default";r=119;t=60 |
  | `RateLimit-Policy` | `string` |  | Advertised quota. Default: "default";q=120;w=60 |
  | `RateLimit-Limit` | `integer` |  | Maximum requests per window. |
  | `RateLimit-Remaining` | `integer` |  | Requests remaining in the current window. |
  | `RateLimit-Reset` | `integer` |  | Seconds until the current window resets. |
  | `API-Version` | `"1"` |  | Current URL-path major (1). |
  | `Retry-After` | `integer` |  | Seconds to wait before retrying. |

#### Example request

curl

fetch

```bash
curl -X GET 'https://daloyjs.dev/docs-md/{path}' \
  -H "Authorization: Bearer $TOKEN"
```

---

Source: https://daloyjs.dev/docs/openapi/site-api