> ## Documentation index
> Fetch the complete documentation index at: https://contextrepo.com/docs/llms.txt
> Use it to find every page before exploring further.

# Endpoints

> Complete REST endpoint reference for prompts, documents, collections, search, progressive disclosure, and reasoning.

Unless an endpoint is explicitly marked public, include an `Authorization` header with every request. See [Authentication](https://contextrepo.com/docs/api/authentication) for details.

## Prompts

### List Prompts

```
GET /v1/prompts
```

**Auth:** `prompts.read`

| Parameter       | Type     | Required | Description                                                                                                                                                                  |
| --------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`         | `number` | No       | Maximum results to return (default: 20, max: 100)                                                                                                                            |
| `cursor`        | `string` | No       | Pagination cursor from a previous response                                                                                                                                   |
| `workspace`     | `string` | No       | Filter by workspace ID                                                                                                                                                       |
| `includePublic` | `string` | No       | Include public prompts (`true` or `false`)                                                                                                                                   |
| `q`             | `string` | No       | Filter by title or description substring                                                                                                                                     |
| `tags`          | `string` | No       | Comma-separated list of tags. Items must match **all** supplied tags (AND semantics). See [Filtering by tags](https://contextrepo.com/docs/api/endpoints#filtering-by-tags). |

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/prompts?limit=10" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": [
    {
      "id": "k57abc123def456",
      "title": "Code Review Prompt",
      "description": "Reviews code for bugs and style issues",
      "content": "Review the following code for potential bugs...",
      "isPublic": false,
      "currentVersion": 2,
      "tags": ["engineering"],
      "stats": { "views": 42, "copies": 7 }
    }
  ],
  "pagination": {
    "cursor": "eyIxIjoiMjAifQ==",
    "hasMore": true
  }
}
```

### Get Prompt

```
GET /v1/prompts/{id}
```

**Auth:** `prompts.read`

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/prompts/k57abc123def456" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": {
    "id": "k57abc123def456",
    "title": "Code Review Prompt",
    "description": "Reviews code for bugs and style issues",
    "content": "Review the following ${language} code:\n\n${code}",
    "variables": [
      { "name": "language", "type": "string" },
      { "name": "code", "type": "string" }
    ],
    "isPublic": false,
    "isArchived": false,
    "currentVersion": 2,
    "tags": ["engineering"],
    "stats": { "views": 42, "copies": 7 }
  }
}
```

### Create Prompt

```
POST /v1/prompts
```

**Auth:** `prompts.write`

| Field         | Type       | Required | Description                                                                                           |
| ------------- | ---------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `title`       | `string`   | Yes      | Prompt title                                                                                          |
| `description` | `string`   | Yes      | Brief description                                                                                     |
| `content`     | `string`   | Yes      | Free-form prompt content. Placeholder notation such as `${variable}` is stored verbatim.              |
| `parameters`  | `object`   | No       | Optional `temperature` and `maxTokens` values                                                         |
| `variables`   | `array`    | No       | Stored variable metadata with name, type (`string`, `number`, or `boolean`), and optional description |
| `workspaceId` | `string`   | No       | Workspace to create the prompt in                                                                     |
| `tags`        | `string[]` | No       | Tags for categorization                                                                               |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/prompts" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Bug Report Template",
    "description": "Generates structured bug reports",
    "content": "Create a bug report for: ${issue_description}"
  }'
```

```json title="Example Response (201 Created)"
{
  "data": {
    "id": "k57xyz789ghi012",
    "title": "Bug Report Template",
    "description": "Generates structured bug reports",
    "content": "Create a bug report for: ${issue_description}",
    "isPublic": false,
    "isArchived": false,
    "currentVersion": 0,
    "tags": [],
    "stats": { "views": 0, "copies": 0 }
  }
}
```

The response includes a `Location` header with the new prompt's URL: `/v1/prompts/{id}`.

Context Repo does not infer variable metadata from the prompt body and does not substitute placeholder values. If `variables` is omitted, the prompt is created with an empty variable array.

### Update Prompt

```
PATCH /v1/prompts/{id}
```

**Auth:** `prompts.write`

Send only the fields you want to change. An update with non-empty `content`, or one that includes `parameters` or `variables`, creates a new version. A title, description, or tags-only update patches the prompt without adding a version.

| Field         | Type       | Required | Description                                                 |
| ------------- | ---------- | -------- | ----------------------------------------------------------- |
| `title`       | `string`   | No       | New title                                                   |
| `description` | `string`   | No       | New description                                             |
| `content`     | `string`   | No       | New content                                                 |
| `parameters`  | `object`   | No       | Updated parameters                                          |
| `variables`   | `array`    | No       | Updated variable definitions                                |
| `tags`        | `string[]` | No       | Replaces the prompt's tag set. Pass `[]` to clear all tags. |
| `changeLog`   | `string`   | No       | Description saved when the update creates a version         |

```bash title="Example Request"
curl -X PATCH "https://api.contextrepo.com/v1/prompts/k57abc123def456" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Review the following ${language} code for bugs, style, and performance:\n\n${code}",
    "changeLog": "Added performance review to scope"
  }'
```

```json title="Example Response"
{
  "data": {
    "id": "k57abc123def456",
    "title": "Code Review Prompt",
    "description": "Reviews code for bugs and style issues",
    "content": "Review the following ${language} code for bugs, style, and performance:\n\n${code}",
    "isPublic": false,
    "isArchived": false,
    "currentVersion": 3,
    "tags": ["engineering"],
    "stats": { "views": 42, "copies": 7 }
  }
}
```

### Delete Prompt

```
DELETE /v1/prompts/{id}
```

**Auth:** `prompts.write`

Returns `200` with body `{ "success": true, "id": "<promptId>" }` on success.

```bash title="Example Request"
curl -X DELETE "https://api.contextrepo.com/v1/prompts/k57abc123def456" \
  -H "Authorization: API-Key gm_your_api_key"
```

### Get Prompt Versions

```
GET /v1/prompts/{id}/versions
```

**Auth:** `prompts.read`

Returns the version history for a prompt in descending order. The `content` field is a preview: at most 200 characters, followed by `...` when the stored content is longer. Use `GET /v1/prompts/{id}` to read the current full content.

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/prompts/k57abc123def456/versions" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": [
    {
      "id": "v_version003",
      "version": 3,
      "content": "Review the following ${language} code for bugs, style, and performance:\n\n${code}",
      "changeLog": "Added performance review to scope",
      "userName": "Alex Chen"
    },
    {
      "id": "v_version000",
      "version": 0,
      "content": "Review the following ${language} code:\n\n${code}",
      "changeLog": "Original version",
      "userName": "Alex Chen"
    }
  ]
}
```

### Restore Prompt Version

```
POST /v1/prompts/{id}/restore
```

**Auth:** `prompts.write`

Restores a prompt to a previous version. This creates a new version entry — it doesn't delete the current content.

| Field       | Type     | Required | Description                                            |
| ----------- | -------- | -------- | ------------------------------------------------------ |
| `versionId` | `string` | Yes      | The version ID to restore (from the versions endpoint) |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/prompts/k57abc123def456/restore" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "versionId": "v_version000" }'
```

```json title="Example Response"
{
  "data": {
    "id": "k57abc123def456",
    "title": "Code Review Prompt",
    "description": "Reviews code for bugs and style issues",
    "content": "Review the following ${language} code:\n\n${code}",
    "isPublic": false,
    "isArchived": false,
    "currentVersion": 4,
    "stats": { "views": 42, "copies": 7 }
  }
}
```

> **Note:** The restore response includes `currentVersion` as the **new** version number created by the restore. Unlike the other prompt endpoints, this response does not include `tags`.

---

## Documents

Every completed document has a canonical `revision`, `contentHash`, and
`lastChangedAt`. Detail and write responses also return:

- `ETag`: a validator for that exact document revision
- `X-ContextRepo-Revision`: the current numeric revision
- `X-ContextRepo-Content-Hash`: the current Markdown hash

Use the exact `ETag` from `GET /v1/documents/{id}` as `If-Match` on a
conditional update, restore, refresh, or coordination-policy change. Don't
construct an ETag from the revision number.

ETags are opaque. The `data.etag` body field is the canonical application
form. Hosted delivery can expose the same document state in the response
header with one exact lowercase `-gzip` suffix and the exact weak prefix `W/`:

```text
W/"doc:<document-id>:rev:<revision>:sha256:<64-lowercase-hex>-gzip"
```

Return the validator unchanged in `If-Match`. Do not add or remove the suffix,
the weak prefix, or any other bytes. A weak canonical validator without
`-gzip` is invalid.

PATCH and restore accept either `If-Match` or body `expectedRevision`.
When both are supplied, their revisions must agree and the header's content
hash is also checked. Managed PATCH and restore additionally require
`Idempotency-Key`, `X-ContextRepo-Lease-Id`, and
`X-ContextRepo-Lease-Fence`. Refresh and coordination-policy operations
retain their existing preconditions. `expectedRevision` must be a nonnegative
safe integer (0 through 9007199254740991).

Retry the identical operation with its original revision, key, payload, and
lease fields. Do not replace the revision or key to recover an uncertain
result. Matching receipts are retained for 24 hours from creation.
Reconcile uncertain operations by reading the document and history before
taking further action. Preserve the original precondition representation on
REST retries too.

Canonical create, update, and restore operations return a compact
acknowledgement:

```json
{
  "data": {
    "id": "d_doc123abc",
    "revision": 3,
    "currentVersion": 3,
    "contentHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "lastChangedAt": 1787702400000,
    "noop": false
  }
}
```

`currentVersion` is a compatibility alias for `revision`. An exact unchanged
write is a **No-op**: it returns `noop: true`, keeps the current revision, and
doesn't add a version-history entry.

### List Documents

```
GET /v1/documents
```

**Auth:** `documents.read`

| Parameter         | Type     | Required | Description                                                                                                                                                                  |
| ----------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`           | `number` | No       | Maximum results (default: 20, max: 100)                                                                                                                                      |
| `cursor`          | `string` | No       | Pagination cursor                                                                                                                                                            |
| `workspace`       | `string` | No       | Filter by workspace ID                                                                                                                                                       |
| `collectionId`    | `string` | No       | Filter by collection ID                                                                                                                                                      |
| `status`          | `string` | No       | Filter by status                                                                                                                                                             |
| `search`          | `string` | No       | Filter by title substring                                                                                                                                                    |
| `includeArchived` | `string` | No       | Include archived documents (`true` or `false`)                                                                                                                               |
| `includeContent`  | `string` | No       | Include document content in response (`true` or `false`, default: `false`)                                                                                                   |
| `tags`            | `string` | No       | Comma-separated list of tags. Items must match **all** supplied tags (AND semantics). See [Filtering by tags](https://contextrepo.com/docs/api/endpoints#filtering-by-tags). |

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/documents?limit=5&includeContent=true" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": [
    {
      "id": "d_doc123abc",
      "title": "API Design Guidelines",
      "status": "completed",
      "isArchived": false,
      "updatedAt": 1710518400000,
      "tags": ["engineering", "standards"],
      "content": "# API Design Guidelines\n\nThis document outlines..."
    }
  ],
  "pagination": {
    "cursor": "eyIxIjoiNSJ9",
    "hasMore": true
  }
}
```

> **Note:** When `includeContent` is `true`, content is truncated to 2,000 characters in list responses. Use the get-document endpoint for document content up to the REST response limit.

### Get Document

```
GET /v1/documents/{id}
```

**Auth:** `documents.read`

| Parameter        | Type     | Required | Description                                                                           |
| ---------------- | -------- | -------- | ------------------------------------------------------------------------------------- |
| `includeContent` | `string` | No       | Include document content fields, subject to the REST response limit (default: `true`) |

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/documents/d_doc123abc" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": {
    "id": "d_doc123abc",
    "title": "API Design Guidelines",
    "status": "completed",
    "isArchived": false,
    "createdAt": 1710432000000,
    "updatedAt": 1710518400000,
    "revision": 2,
    "currentVersion": 2,
    "contentHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "lastChangedAt": 1710518400000,
    "content": "# API Design Guidelines\n\nThis document outlines best practices...",
    "tags": ["engineering", "standards"],
    "sourceType": "scrape",
    "sourceUrl": "https://example.com/api-guidelines",
    "source": {
      "contentHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "lastCheckedAt": 1787529600000,
      "lastChangedAt": 1787184000000
    }
  }
}
```

> **Note:** Optional fields with no value (`sourceUrl`, `source`, `contentHtml`, `rawHtml`, `workspaceId`) are omitted from the response rather than returned as `null`. Document content fields are returned up to the REST response limit; use Deep Search for targeted retrieval from large documents. Within `source`, `contentHash`, `lastCheckedAt`, `lastChangedAt`, and `lastRefreshError` are also optional. Timestamps are epoch milliseconds. A failed refresh adds `lastRefreshError` with `code`, `message`, and `at`; a later successful refresh clears it. Internal refresh-lock fields are never returned.

### Refresh Document from Source

```
POST /v1/documents/{id}/refresh
```

**Auth:** `documents.write` (legacy `documents.scrape` is also accepted)

Re-fetches a completed or failed scraped document from its stored HTTP(S) source URL. Send an empty request body. The response reports whether the source content changed and includes a `Location` header for the document.
For a revisioned document, the `202` response also includes the current
`ETag`, `X-ContextRepo-Revision`, and `X-ContextRepo-Content-Hash` after the
refresh result is applied.

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/documents/d_doc123abc/refresh" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response (202 Accepted)"
{
  "data": {
    "documentId": "d_doc123abc",
    "changed": true
  }
}
```

When `changed` is `true`, Context Repo creates a new document version and starts chunking and embedding the refreshed content in the background. When it's `false`, no version is created, but `source.lastCheckedAt` is updated.

| Status | Meaning                                                                                            |
| ------ | -------------------------------------------------------------------------------------------------- |
| `400`  | The document isn't a refreshable scraped source, or initial processing hasn't finished             |
| `404`  | The document doesn't exist or isn't accessible to the caller                                       |
| `409`  | Another refresh is in progress, or this attempt was superseded by a document edit or newer refresh |
| `429`  | The stricter scrape rate limit was exceeded                                                        |
| `500`  | Fetching or saving the refreshed source failed                                                     |

### Create Document

```
POST /v1/documents
```

**Auth:** `documents.write`

| Field           | Type       | Required | Description                               |
| --------------- | ---------- | -------- | ----------------------------------------- |
| `title`         | `string`   | Yes      | Document title                            |
| `content`       | `string`   | Yes      | Document content (plain text or markdown) |
| `tags`          | `string[]` | No       | Tags for categorization                   |
| `collectionIds` | `string[]` | No       | Collections to add the document to        |
| `workspaceId`   | `string`   | No       | Workspace to create the document in       |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/documents" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Meeting Notes — March 2026",
    "content": "# Key Decisions\n\n- Migrate to v2 API by end of quarter\n- Add webhook support for collections",
    "tags": ["meetings", "planning"]
  }'
```

```json title="Example Response (201 Created)"
{
  "data": {
    "id": "d_newdoc456",
    "revision": 0,
    "currentVersion": 0,
    "contentHash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "lastChangedAt": 1787702400000,
    "noop": false
  }
}
```

### Update Document

```
PATCH /v1/documents/{id}
```

**Auth:** `documents.write`

Send only the fields you want to change. A changed canonical field creates a
new version; an exact unchanged request returns a no-op acknowledgement.

| Field         | Type             | Required | Description                                                   |
| ------------- | ---------------- | -------- | ------------------------------------------------------------- |
| `title`       | `string`         | No       | New title                                                     |
| `content`     | `string`         | No       | New content                                                   |
| `contentHtml` | `string \| null` | No       | HTML version, or `null` to clear it                           |
| `rawHtml`     | `string \| null` | No       | Raw source HTML, or `null` to clear it                        |
| `sourceUrl`   | `string \| null` | No       | Source URL, or `null` to clear it                             |
| `metadata`    | `object`         | No       | Replaces metadata. Pass `{}` to clear it.                     |
| `tags`        | `string[]`       | No       | Replaces the document's tag set. Pass `[]` to clear all tags. |
| `changeLog`   | `string`         | No       | Description of changes (saved in version history)             |

```bash title="Example Request"
curl -X PATCH "https://api.contextrepo.com/v1/documents/d_doc123abc" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H 'If-Match: "doc:d_doc123abc:rev:2:sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"' \
  -H "Idempotency-Key: update-api-guidelines-3" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "# API Design Guidelines (Updated)\n\nRevised to include REST and GraphQL...",
    "changeLog": "Added GraphQL section"
  }'
```

```json title="Example Response"
{
  "data": {
    "id": "d_doc123abc",
    "revision": 3,
    "currentVersion": 3,
    "contentHash": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
    "lastChangedAt": 1787702400000,
    "noop": false
  }
}
```

### Delete Document

```
DELETE /v1/documents/{id}
```

**Auth:** `documents.write`

Returns `200` with body `{ "success": true, "id": "<documentId>" }` on success.

```bash title="Example Request"
curl -X DELETE "https://api.contextrepo.com/v1/documents/d_doc123abc" \
  -H "Authorization: API-Key gm_your_api_key"
```

### Get Document Versions

```
GET /v1/documents/{id}/versions
```

**Auth:** `documents.read`

Returns the version history for a document.

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/documents/d_doc123abc/versions" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": [
    {
      "id": "dv_version001",
      "documentId": "d_doc123abc",
      "version": 2,
      "title": "REST API Reference",
      "content": "# REST API Reference\n\n## GraphQL Section\n\n...",
      "contentHtml": "<h1>REST API Reference</h1><h2>GraphQL Section</h2>...",
      "contentHash": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
      "snapshotCompleteness": "complete",
      "actor": { "kind": "api_key", "displayName": "Docs sync" },
      "origin": "rest",
      "changeLog": "Added GraphQL section",
      "userName": "Alex Chen",
      "createdAt": 1710691200000
    },
    {
      "id": "dv_version000",
      "documentId": "d_doc123abc",
      "version": 1,
      "title": "REST API Reference",
      "content": "# REST API Reference\n\nInitial content...",
      "contentHtml": "<h1>REST API Reference</h1><p>Initial content...</p>",
      "changeLog": "Initial version",
      "userName": "Alex Chen",
      "createdAt": 1710432000000
    }
  ]
}
```

### Restore Document Version

```
POST /v1/documents/{id}/restore
```

**Auth:** `documents.write`

Restores the selected canonical snapshot as a new current revision when it
differs. An exact unchanged restore is a no-op. Complete and synthetic
snapshots restore every canonical field.

| Field       | Type     | Required | Description               |
| ----------- | -------- | -------- | ------------------------- |
| `versionId` | `string` | Yes      | The version ID to restore |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/documents/d_doc123abc/restore" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -H 'If-Match: "doc:d_doc123abc:rev:2:sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"' \
  -H "Idempotency-Key: restore-api-guidelines-2" \
  -d '{ "versionId": "dv_version000" }'
```

```json title="Example Response"
{
  "data": {
    "id": "d_doc123abc",
    "revision": 3,
    "currentVersion": 3,
    "contentHash": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
    "lastChangedAt": 1787702400000,
    "noop": false
  }
}
```

> **Note:** An older `legacy_partial` snapshot preserves fields that weren't recorded
> historically. Its first response and any idempotent replay include
> `warnings: ["LEGACY_PARTIAL_SNAPSHOT"]`.

### Get Document Coordination

```
GET /v1/documents/{id}/coordination
```

**Auth:** `documents.read`

Returns the editing policy (`standard` or `lease_required`), current fence,
visible lease state, and current revision headers. Lease IDs are returned only
to the caller that holds the lease.

### Enable Document Coordination

```
PUT /v1/documents/{id}/coordination
```

**Auth:** `documents.write` (document owner only)

Send an empty body and the current `If-Match` value to enable managed mode.
Managed writers must hold the current lease. The header-based write form is:

```text
If-Match: "<exact ETag from GET>"
Idempotency-Key: <unique retry key>
X-ContextRepo-Lease-Id: <lease ID>
X-ContextRepo-Lease-Fence: <fence number>
```

For PATCH and restore only, body `expectedRevision` can replace `If-Match`;
the key, lease ID, and fence remain required. Refresh still requires `If-Match`.

### Disable Document Coordination

```
DELETE /v1/documents/{id}/coordination
```

**Auth:** `documents.write` (document owner only)

Send the current `If-Match` value. Disabling fails with `409` while an active
lease exists.

### Operate Document Lease

```
POST /v1/documents/{id}/coordination/lease
```

**Auth:** `documents.write`

Every lease request requires `Idempotency-Key`. Acquire sends
`{ "action": "acquire", "ttlMs": 60000 }`. Renew and release send their
action in the body plus `X-ContextRepo-Lease-Id` and
`X-ContextRepo-Lease-Fence`. Successful acquire and renew responses expose
`X-ContextRepo-Lease-Expires-At`.

| Status | Reason                                                       | Recovery                                                                    |
| ------ | ------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `409`  | `LEASE_CONFLICT`, `FENCE_MISMATCH`, or operation in progress | Reload coordination state; don't reuse a stale fence                        |
| `412`  | `REVISION_MISMATCH`                                          | GET the document again and use its exact ETag                               |
| `422`  | `IDEMPOTENCY_KEY_REUSED` or `DOCUMENT_NOT_COORDINATABLE`     | Use a new key for changed inputs, or wait for a complete canonical snapshot |
| `428`  | `PRECONDITION_REQUIRED`                                      | Add the required revision, key, or lease headers                            |

### Scrape URL into Document

```
POST /v1/documents/scrape
```

**Auth:** `documents.write`

Scrapes a webpage and creates a new document from the extracted content using intelligent main-content extraction.

| Field           | Type       | Required | Description                                                                                                                                                         |
| --------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`           | `string`   | Yes      | The URL to scrape (auto-prefixed with `https://` if no protocol is provided)                                                                                        |
| `collectionIds` | `string[]` | No       | Collections to add the resulting document to                                                                                                                        |
| `options`       | `object`   | No       | Extraction options (e.g., `onlyMainContent`, `waitFor`) — see [Documents — Web Scraping](https://contextrepo.com/docs/dashboard/documents#web-scraping) for details |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/documents/scrape" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/blog/api-design-patterns",
    "collectionIds": ["col_collection123"]
  }'
```

```json title="Example Response (202 Accepted)"
{
  "data": {
    "documentId": "d_scraped789"
  }
}
```

> **Note:** Scraping returns `202 Accepted` because extraction happens asynchronously. The document is created and populated in the background. This endpoint has a separate, stricter rate limit than standard CRUD operations.

---

## Collections

### List Collections

```
GET /v1/collections
```

**Auth:** `documents.read`

| Parameter   | Type     | Required | Description                                                                                                                                                                  |
| ----------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`     | `number` | No       | Maximum results (default: 20, max: 100)                                                                                                                                      |
| `cursor`    | `string` | No       | Pagination cursor (base64-encoded offset)                                                                                                                                    |
| `search`    | `string` | No       | Filter by name or description substring                                                                                                                                      |
| `workspace` | `string` | No       | Filter by workspace ID                                                                                                                                                       |
| `tags`      | `string` | No       | Comma-separated list of tags. Items must match **all** supplied tags (AND semantics). See [Filtering by tags](https://contextrepo.com/docs/api/endpoints#filtering-by-tags). |

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/collections?limit=10" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": [
    {
      "id": "col_collection123",
      "name": "Engineering Standards",
      "description": "API guidelines, coding standards, and review checklists",
      "color": "#3b82f6",
      "icon": "📐",
      "isPublic": false,
      "itemCount": 12,
      "lastActivityAt": 1710518400000
    }
  ],
  "pagination": {
    "cursor": "MjA=",
    "hasMore": false
  }
}
```

### Get Collection

```
GET /v1/collections/{id}
```

**Auth:** `documents.read`

Returns a single collection with its metadata.

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/collections/col_collection123" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": {
    "id": "col_collection123",
    "name": "Engineering Standards",
    "description": "API guidelines, coding standards, and review checklists",
    "color": "#3b82f6",
    "icon": "📐",
    "isPublic": false,
    "tags": ["engineering"],
    "itemCount": 12,
    "lastActivityAt": 1710518400000,
    "createdAt": 1710432000000,
    "updatedAt": 1710518400000
  }
}
```

> **Note:** A `stats` object (total items, per-type counts, top contributors) is appended only when the caller authenticates with a Clerk session token. API-key and machine-token requests receive the response without `stats`.

### Get Collection Items

```
GET /v1/collections/{id}/items
```

**Auth:** `documents.read`

Returns the prompts and documents in a collection.

| Parameter        | Type     | Required | Description                                  |
| ---------------- | -------- | -------- | -------------------------------------------- |
| `limit`          | `number` | No       | Maximum items (default: 20, max: 100)        |
| `cursor`         | `string` | No       | Pagination cursor                            |
| `includeContent` | `string` | No       | Include document content (`true` or `false`) |

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/collections/col_collection123/items?limit=10" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": [
    {
      "itemType": "prompt",
      "itemId": "k57abc123def456",
      "title": "Code Review Prompt",
      "summary": "Reviews code for bugs and style issues"
    },
    {
      "itemType": "document",
      "itemId": "d_doc123abc",
      "title": "API Design Guidelines",
      "summary": null
    }
  ],
  "pagination": {
    "cursor": "eyIxIjoiMTAifQ==",
    "hasMore": false
  }
}
```

### Create Collection

```
POST /v1/collections
```

**Auth:** `documents.write`

| Field                | Type       | Required | Description                                                                                                              |
| -------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| `name`               | `string`   | Yes      | Collection name                                                                                                          |
| `description`        | `string`   | No       | Collection description                                                                                                   |
| `color`              | `string`   | No       | Hex color code (e.g., `#3b82f6`)                                                                                         |
| `icon`               | `string`   | No       | Emoji icon (e.g., `📐`)                                                                                                  |
| `workspaceId`        | `string`   | No       | Workspace to create the collection in                                                                                    |
| `parentCollectionId` | `string`   | No       | Parent collection for nesting                                                                                            |
| `tags`               | `string[]` | No       | Tags for cross-type organization. See [Filtering by tags](https://contextrepo.com/docs/api/endpoints#filtering-by-tags). |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/collections" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Product Roadmap",
    "description": "Planning docs and feature specs",
    "icon": "🗺️",
    "color": "#10b981"
  }'
```

```json title="Example Response (201 Created)"
{
  "data": {
    "id": "col_newcol789",
    "name": "Product Roadmap",
    "description": "Planning docs and feature specs",
    "icon": "🗺️",
    "color": "#10b981",
    "isPublic": false,
    "tags": [],
    "itemCount": 0,
    "lastActivityAt": 1710604800000,
    "createdAt": 1710604800000,
    "updatedAt": 1710604800000
  }
}
```

### Update Collection

```
PATCH /v1/collections/{id}
```

**Auth:** `documents.write`

Send only the fields you want to change.

| Field         | Type       | Required | Description                                                     |
| ------------- | ---------- | -------- | --------------------------------------------------------------- |
| `name`        | `string`   | No       | New name                                                        |
| `description` | `string`   | No       | New description                                                 |
| `color`       | `string`   | No       | New hex color code                                              |
| `icon`        | `string`   | No       | New emoji icon                                                  |
| `isPublic`    | `boolean`  | No       | Make collection public or private                               |
| `tags`        | `string[]` | No       | Replaces the collection's tag set. Pass `[]` to clear all tags. |

> **Warning:** Reparenting (changing `parentCollectionId`) is not currently supported via PATCH. Set the parent only at creation time via POST.

```bash title="Example Request"
curl -X PATCH "https://api.contextrepo.com/v1/collections/col_collection123" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Engineering Standards v2", "color": "#8b5cf6" }'
```

```json title="Example Response"
{
  "data": {
    "id": "col_collection123",
    "name": "Engineering Standards v2",
    "description": "API guidelines, coding standards, and review checklists",
    "color": "#8b5cf6",
    "icon": "📐",
    "isPublic": false,
    "tags": ["engineering"],
    "itemCount": 12,
    "lastActivityAt": 1710518400000,
    "createdAt": 1710432000000,
    "updatedAt": 1710691200000
  }
}
```

### Delete Collection

```
DELETE /v1/collections/{id}
```

**Auth:** `documents.write`

Returns `200` with body `{ "success": true, "id": "<collectionId>" }` on success. Deleting a collection does **not** delete the prompts and documents inside it — they remain in your workspace.

```bash title="Example Request"
curl -X DELETE "https://api.contextrepo.com/v1/collections/col_collection123" \
  -H "Authorization: API-Key gm_your_api_key"
```

### Add Items to Collection

```
POST /v1/collections/{id}/items
```

**Auth:** `documents.write`

Adds prompts or documents to a collection.

| Field      | Type       | Required | Description                            |
| ---------- | ---------- | -------- | -------------------------------------- |
| `itemIds`  | `string[]` | Yes      | Array of prompt or document IDs to add |
| `itemType` | `string`   | Yes      | Type of items: `document` or `prompt`  |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/collections/col_collection123/items" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "itemIds": ["k57abc123def456", "k57xyz789ghi012"],
    "itemType": "prompt"
  }'
```

```json title="Example Response"
{
  "data": {
    "added": 2,
    "alreadyInCollection": 0
  }
}
```

### Remove Items from Collection

```
PUT /v1/collections/{id}/items
```

**Auth:** `documents.write`

Removes prompts or documents from a collection. Uses `PUT` instead of `DELETE` because the request requires a JSON body.

| Field      | Type       | Required | Description                               |
| ---------- | ---------- | -------- | ----------------------------------------- |
| `itemIds`  | `string[]` | Yes      | Array of prompt or document IDs to remove |
| `itemType` | `string`   | Yes      | Type of items: `document` or `prompt`     |

```bash title="Example Request"
curl -X PUT "https://api.contextrepo.com/v1/collections/col_collection123/items" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "itemIds": ["k57abc123def456"],
    "itemType": "prompt"
  }'
```

```json title="Example Response"
{
  "data": {
    "removed": 1
  }
}
```

---

## Search

### Search Across Resources

```
GET /v1/search
```

**Auth:** At least one of `prompts.read` or `documents.read`

Searches across prompts, documents, and collections. Supports both semantic (AI embeddings) and literal (substring matching) modes.

| Parameter        | Type     | Required | Description                                                                                                                                                                                                                                    |
| ---------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `q` or `query`   | `string` | Yes      | Search query                                                                                                                                                                                                                                   |
| `type`           | `string` | No       | Filter by type: `prompts`, `documents`, `collections`, or `all` (default: `all`)                                                                                                                                                               |
| `semantic`       | `string` | No       | Use semantic search (default: `true`). Set to `false` for literal matching                                                                                                                                                                     |
| `limit`          | `number` | No       | Maximum results per type (default: 10, max: 50)                                                                                                                                                                                                |
| `scoreThreshold` | `number` | No       | Minimum relevance score for semantic results (default: 0.35)                                                                                                                                                                                   |
| `tags`           | `string` | No       | Comma-separated list of tags. Applied symmetrically across prompts, documents, and collections. Items must match **all** supplied tags (AND semantics). See [Filtering by tags](https://contextrepo.com/docs/api/endpoints#filtering-by-tags). |

```bash title="Example Request — Semantic Search"
curl -X GET "https://api.contextrepo.com/v1/search?q=API+design+best+practices&type=all" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response — Semantic"
{
  "data": {
    "documents": [
      {
        "documentId": "d_doc123abc",
        "title": "API Design Guidelines",
        "score": 0.87,
        "highlight": "...every endpoint declares explicit request and response contracts...",
        "tags": ["engineering", "standards"]
      }
    ],
    "prompts": [
      {
        "promptId": "k57abc123def456",
        "title": "Code Review Prompt",
        "description": "Reviews code for bugs and style issues",
        "score": 0.74,
        "tags": ["engineering"]
      }
    ],
    "collections": []
  },
  "meta": {
    "query": "API design best practices",
    "semantic": true,
    "latencyMs": 142
  }
}
```

```bash title="Example Request — Literal Search"
curl -X GET "https://api.contextrepo.com/v1/search?q=API+Design&semantic=false&type=documents" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response — Literal"
{
  "data": {
    "documents": [
      {
        "documentId": "d_doc123abc",
        "title": "API Design Guidelines",
        "tags": ["engineering", "standards"],
        "highlight": "...every endpoint in our API Design standard declares explicit request and response contracts...",
        "chunkId": "hc_chunk789xyz"
      }
    ],
    "prompts": [],
    "collections": []
  },
  "meta": {
    "query": "API Design",
    "semantic": false
  }
}
```

Literal document hits matched in the content preview or body carry an optional `highlight` snippet. Hits matched in the body also carry a `chunkId`, which can be passed to the progressive disclosure endpoints (`GET /v1/pd/read/{chunkId}`, `POST /v1/pd/expand`) to read or navigate around the matching passage.

> **Note:** Semantic search uses AI embeddings to find conceptually related content — it doesn't require exact keyword matches. Literal search matches substrings in titles, descriptions, and indexed document body text via hierarchical chunks — full-body literal matching, eventually consistent with chunking. Title and preview matches are immediate; body matches appear once a document's chunks are indexed.

### Filtering by tags

Every list endpoint and `/v1/search` accepts a `tags` query parameter that filters the response by item-level tags. Tags are free-form string labels stored on the `collections`, `prompts`, and `documents` rows themselves; they apply uniformly across all three resource types.

**Encoding:** comma-separated values in a single query parameter.

```
?tags=draft,roadmap-q3
```

Whitespace around each value is trimmed. Empty segments (`?tags=,foo,`) are dropped. Tag values **must not contain a literal comma** — the parser uses `,` as the separator and there is no escape syntax.

**Semantics:** AND. A row is included in the response only if **every** supplied tag is present in its tag array. Searching with `?tags=alpha,beta` excludes any item that has `alpha` but not `beta`, and vice versa. Pass a single tag (`?tags=alpha`) for one-axis filtering. Omit the parameter entirely to disable tag filtering.

**Supported endpoints:**

- `GET /v1/prompts`
- `GET /v1/documents`
- `GET /v1/collections`
- `GET /v1/search` — applied symmetrically to the `prompts`, `documents`, and `collections` branches in both literal and semantic modes.

**Setting tags:** `POST` and `PATCH` on prompts, documents, and collections all accept a `tags: string[]` body field. Sending `tags: []` clears the tag set; omitting the field on a `PATCH` leaves the existing tags untouched.

**Read shape:** every read response (list, get, search) projects a `tags: string[]` field. Rows that have never had tags assigned project `[]`, never `null` or `undefined`.

\`\`\`bash title="Example — list collections tagged both `draft` AND `q3-roadmap`"
curl -X GET "<https://api.contextrepo.com/v1/collections?tags=draft,q3-roadmap>" \
-H "Authorization: API-Key gm\_your\_api\_key"

````

```bash title="Example — search across all types, scoped to a project tag"
curl -X GET "https://api.contextrepo.com/v1/search?q=migration&tags=customer-x" \
  -H "Authorization: API-Key gm_your_api_key"
````

---

## Progressive Disclosure

Progressive disclosure endpoints let you search and navigate through document content at different levels of detail, from summaries down to individual paragraphs.

### Search Content

```
POST /v1/pd/search
```

**Auth:** `documents.read`

Searches document content with configurable detail level and returns ranked chunks.

| Field          | Type     | Required | Description                                                                                 |
| -------------- | -------- | -------- | ------------------------------------------------------------------------------------------- |
| `query`        | `string` | Yes      | Search query                                                                                |
| `sessionId`    | `string` | No       | Session ID for deduplication across searches                                                |
| `maxTokens`    | `number` | No       | Maximum tokens in response                                                                  |
| `limit`        | `number` | No       | Maximum chunks to return (default: 10)                                                      |
| `detailLevel`  | `string` | No       | `summary` (default) returns condensed chunk content; `full` returns the complete chunk text |
| `documentId`   | `string` | No       | Filter to a specific document                                                               |
| `collectionId` | `string` | No       | Filter to a specific collection                                                             |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/pd/search" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "authentication best practices",
    "limit": 5
  }'
```

```json title="Example Response"
{
  "data": {
    "results": [
      {
        "chunkId": "hc_chunk001",
        "content": "Use JWT tokens with short expiration windows...",
        "level": "section",
        "score": 0.89,
        "parentId": "hc_parent001",
        "siblingIds": { "prev": null, "next": "hc_chunk002" },
        "documentId": "d_doc123abc",
        "documentTitle": "Security Guidelines"
      }
    ],
    "meta": { "query": "authentication best practices", "totalResults": 1, "latencyMs": 142 }
  }
}
```

### Expand Chunk

```
POST /v1/pd/expand
```

**Auth:** `documents.read`

Navigates the document hierarchy from a specific chunk. You can move up (parent), down (children), next/previous (siblings), or get surrounding context.

| Field       | Type     | Required | Description                                                              |
| ----------- | -------- | -------- | ------------------------------------------------------------------------ |
| `chunkId`   | `string` | Yes      | The chunk ID to expand from                                              |
| `direction` | `string` | Yes      | Navigation direction: `up`, `down`, `next`, `previous`, or `surrounding` |
| `count`     | `number` | No       | Number of chunks to return                                               |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/pd/expand" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "chunkId": "hc_chunk001",
    "direction": "down",
    "count": 3
  }'
```

```json title="Example Response"
{
  "data": {
    "chunks": [
      {
        "_id": "hc_chunk002",
        "content": "JWT tokens should be signed with RS256...",
        "level": "paragraph",
        "parentId": "hc_chunk001",
        "chunkIndex": 0,
        "documentId": "d_doc123abc",
        "documentTitle": "Security Guidelines"
      }
    ]
  }
}
```

> **Note:** On this endpoint the chunk id field is named `_id` (not `chunkId`). An empty `chunks` array means there is nothing in the requested direction — including chunk IDs that no longer exist after a document was re-chunked.

### Read Chunk

```
GET /v1/pd/read/{chunkId}
```

**Auth:** `documents.read`

Returns a single chunk with its full content and hierarchy metadata.

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/pd/read/hc_chunk001" \
  -H "Authorization: API-Key gm_your_api_key"
```

```json title="Example Response"
{
  "data": {
    "chunkId": "hc_chunk001",
    "content": "Use JWT tokens with short expiration windows and rotate signing keys regularly.",
    "level": "section",
    "hierarchy": {
      "documentId": "d_doc123abc",
      "documentTitle": "Security Guidelines",
      "sectionPath": "Security Guidelines > Authentication",
      "position": {
        "chunkIndex": 2,
        "parentChunkId": "hc_parent001",
        "prevSiblingId": null,
        "nextSiblingId": "hc_chunk002"
      }
    },
    "metadata": {
      "startIndex": 1042,
      "endIndex": 1138,
      "wordCount": 14,
      "sectionPath": "Security Guidelines > Authentication",
      "headingText": "Authentication"
    }
  }
}
```

### Create Session

```
POST /v1/pd/session
```

**Auth:** Any valid authentication

Creates a search session for deduplication. Pass the returned `sessionId` to the search endpoint to avoid seeing the same chunks across multiple queries.

| Field | Type     | Required | Description                     |
| ----- | -------- | -------- | ------------------------------- |
| `ttl` | `number` | No       | Session time-to-live in seconds |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/pd/session" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "ttl": 3600 }'
```

```json title="Example Response (201 Created)"
{
  "data": {
    "sessionId": "sess_abc123",
    "createdAt": 1710604800000,
    "expiresAt": 1710608400000
  }
}
```

---

## Reasoning

### Synthesize an Answer

```
POST /v1/reason
```

**Auth:** Delegated user authentication, or a scoped API-key/machine credential
with `documents.read`

Ask a question and get a best-effort, cited answer composed across your documents — not a list of chunks. Bounded retrieval feeds a strict assessment of cited `statements` and `limitations`, which is projected into the answer, inline citations to the exact chunks used, and best-effort gaps. The `gaps` list is non-exhaustive; an empty list doesn't prove complete coverage. Read-only.

See [Reasoning](https://contextrepo.com/docs/concepts/reasoning) for guidance on choosing a scope, reading citations, and interpreting gaps and disagreements.

| Field          | Type     | Required | Description                                                                                                                                                       |
| -------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`        | `string` | Yes      | The natural-language question to answer across your documents. It must contain at least one non-whitespace character; leading and trailing whitespace is trimmed. |
| `limit`        | `number` | No       | Maximum number of evidence chunks in the synthesis packet. Defaults to 50; non-integers are truncated and values are clamped to 1–50.                             |
| `maxTokens`    | `number` | No       | Token budget for gathered evidence passed to synthesis (default: 8000). Finite values are truncated; negative values become zero.                                 |
| `documentId`   | `string` | No       | Restrict reasoning to a single document                                                                                                                           |
| `collectionId` | `string` | No       | Restrict reasoning to a single collection                                                                                                                         |

```bash title="Example Request"
curl -X POST "https://api.contextrepo.com/v1/reason" \
  -H "Authorization: API-Key gm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "query": "What is our refund policy for annual plans?", "limit": 8 }'
```

```json title="Example Response (200 OK)"
{
  "data": {
    "answer": "Claim:\nAnnual plans are refundable within the first 14 days. [[hc_chunk001]]",
    "citations": [
      {
        "chunkId": "hc_chunk001",
        "documentId": "doc_abc123",
        "documentTitle": "Billing Policy"
      }
    ],
    "gaps": ["No stated policy for partial-year downgrades"],
    "meta": {
      "chunksGathered": 8,
      "citationsDropped": 0,
      "latencyMs": 1840
    }
  }
}
```

The `answer` field uses server-generated `[[chunkId]]` tokens that resolve to
entries in `citations`. Disagreements appear as ordinary cited statements. The
model preserves supplied source differences without choosing a winner unless
the evidence establishes one.

The server validates admitted chunk IDs and requires each quote to occur in
the admitted chunk after both values collapse whitespace runs and trim their
edges. Invalid dependent content is withheld. `citationsDropped` counts
references withheld by failed mechanical validation; retained duplicate
references do not increase it. This diagnostic is not a semantic-correctness
score. Exact citation validation proves source linkage, not semantic
entailment. `gaps` contains best-effort limitations noticed in this run,
including facts not established by the retrieved evidence within the requested
scope and retrieval limits. It is non-exhaustive and does not prove
repository-wide absence. Disagreements appear as ordinary cited statements in
`answer`.

Reason uses the progressive-search result list directly, preserves its order,
and applies the final `limit` and evidence budget to content, titles, and
wrappers together. It does not enumerate extra collection members or add
ancestors, children, or heading matches. Similarity scores remain internal to
the unscoped relevance guard and are omitted from provider evidence and public
citations.

If no evidence is available, the endpoint skips synthesis and returns the
scoped no-evidence sentence in both `answer` and `gaps`. Weak unscoped evidence
also skips synthesis. A nonempty result from an explicit `documentId` or
`collectionId` scope reaches synthesis even when its best score is below
Reason's fixed relevance guard; progressive retrieval thresholds and
authorization still apply. Retrieval or token limits can exclude eligible
context without adding a generic partial-evidence warning.

---

## MCP Capabilities

### Get MCP Capabilities

```
GET /v1/mcp/capabilities
```

**Auth:** None (public)

Returns the MCP protocol capabilities supported by Context Repo.

```bash title="Example Request"
curl -X GET "https://api.contextrepo.com/v1/mcp/capabilities"
```

```json title="Example Response"
{
  "version": "1.0.0",
  "capabilities": {
    "prompts": {
      "rest": true,
      "list": true,
      "get": true,
      "create": true,
      "update": true,
      "delete": true,
      "versions": true,
      "searchQueryParam": true
    },
    "documents": {
      "rest": true,
      "list": true,
      "get": true,
      "create": true,
      "update": true,
      "delete": true,
      "versions": true,
      "scrape": true
    },
    "collections": {
      "rest": true,
      "list": true,
      "get": true,
      "create": true,
      "update": true,
      "delete": true,
      "items": true
    },
    "search": { "rest": true },
    "progressiveDisclosure": {
      "search": true,
      "expand": true,
      "read": true,
      "session": true
    },
    "reason": { "rest": true },
    "auth": { "bearer": true, "apiKey": true }
  }
}
```

---

## Error Codes

All error responses use the same envelope format with a numeric `code` and a `message` string:

```json
{
  "error": {
    "code": 404,
    "message": "Document not found"
  }
}
```

| HTTP Status | Meaning               | Common Causes                                                                       |
| ----------- | --------------------- | ----------------------------------------------------------------------------------- |
| `400`       | Bad Request           | Missing required fields, invalid JSON body, malformed IDs, invalid parameters       |
| `401`       | Unauthorized          | Missing `Authorization` header, expired JWT token, invalid API key                  |
| `403`       | Forbidden             | Valid authentication but the API key lacks the required permission scope            |
| `404`       | Not Found             | Resource doesn't exist or you don't have access to it                               |
| `429`       | Rate Limited          | Too many requests — wait and retry. Rate limit headers are included in the response |
| `500`       | Internal Server Error | Unexpected server error — retry the request or contact support                      |

## Related Pages

- [Authentication](https://contextrepo.com/docs/api/authentication): Set up Bearer JWT or API key authentication.
- [API Overview](https://contextrepo.com/docs/api): Base URL derivation, response format, and CORS policy.
- [Settings](https://contextrepo.com/docs/dashboard/settings): Create and manage API keys in the dashboard.
