Endpoints
Complete REST endpoint reference for prompts, documents, collections, search, and progressive disclosure.
All endpoints require authentication. Include an Authorization header with every request — see Authentication for details.
Prompts
List Prompts
GET /v1/promptsAuth: 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. |
curl -X GET "https://api.contextrepo.com/v1/prompts?limit=10" \
-H "Authorization: API-Key gm_your_api_key"{
"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
curl -X GET "https://api.contextrepo.com/v1/prompts/k57abc123def456" \
-H "Authorization: API-Key gm_your_api_key"{
"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/promptsAuth: prompts.write
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Prompt title |
description | string | Yes | Brief description |
content | string | Yes | Prompt template content (supports ${variable} syntax) |
parameters | object | No | Additional parameters |
variables | array | No | Variable definitions with name, type, and description |
workspaceId | string | No | Workspace to create the prompt in |
tags | string[] | No | Tags for categorization |
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}"
}'{
"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": 1,
"tags": [],
"stats": { "views": 0, "copies": 0 }
}
}The response includes a Location header with the new prompt's URL: /v1/prompts/{id}.
Update Prompt
PATCH /v1/prompts/{id}Auth: prompts.write
Send only the fields you want to change. Updates automatically create a new 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 of changes (saved in version history) |
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"
}'{
"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.
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}/versionsAuth: prompts.read
Returns the version history for a prompt, ordered by creation date.
curl -X GET "https://api.contextrepo.com/v1/prompts/k57abc123def456/versions" \
-H "Authorization: API-Key gm_your_api_key"{
"data": [
{
"id": "v_version001",
"version": 2,
"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": 1,
"content": "Review the following ${language} code:\n\n${code}",
"changeLog": "Initial version",
"userName": "Alex Chen"
}
]
}Restore Prompt Version
POST /v1/prompts/{id}/restoreAuth: 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) |
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" }'{
"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": 3,
"stats": { "views": 42, "copies": 7 }
}
}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 strong validator for that exact document revisionX-ContextRepo-Revision: the current numeric revisionX-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.
Canonical create, update, and restore operations return a compact acknowledgement:
{
"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/documentsAuth: 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. |
curl -X GET "https://api.contextrepo.com/v1/documents?limit=5&includeContent=true" \
-H "Authorization: API-Key gm_your_api_key"{
"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
}
}When includeContent is true, content is truncated to 2,000 characters in list responses. Use the get-document endpoint for the full text.
Get Document
GET /v1/documents/{id}Auth: documents.read
| Parameter | Type | Required | Description |
|---|---|---|---|
includeContent | string | No | Include full content (default: true) |
curl -X GET "https://api.contextrepo.com/v1/documents/d_doc123abc" \
-H "Authorization: API-Key gm_your_api_key"{
"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
}
}
}Optional fields with no value (sourceUrl, source, contentHtml, rawHtml, workspaceId) are omitted from the response rather than returned as null. 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}/refreshAuth: 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.
curl -X POST "https://api.contextrepo.com/v1/documents/d_doc123abc/refresh" \
-H "Authorization: API-Key gm_your_api_key"{
"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/documentsAuth: 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 |
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"]
}'{
"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) |
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"
}'{
"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.
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}/versionsAuth: documents.read
Returns the version history for a document.
curl -X GET "https://api.contextrepo.com/v1/documents/d_doc123abc/versions" \
-H "Authorization: API-Key gm_your_api_key"{
"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}/restoreAuth: 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 |
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" }'{
"data": {
"id": "d_doc123abc",
"revision": 3,
"currentVersion": 3,
"contentHash": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"lastChangedAt": 1787702400000,
"noop": false
}
}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}/coordinationAuth: 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}/coordinationAuth: documents.write (document owner only)
Send an empty body and the current If-Match value. Managed mode requires
writers to hold the current lease and send all four protocol headers on a
canonical write:
If-Match: "<exact ETag from GET>"
Idempotency-Key: <unique retry key>
X-ContextRepo-Lease-Id: <lease ID>
X-ContextRepo-Lease-Fence: <fence number>Disable Document Coordination
DELETE /v1/documents/{id}/coordinationAuth: 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/leaseAuth: 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/scrapeAuth: 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 for details |
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"]
}'{
"data": {
"documentId": "d_scraped789"
}
}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/collectionsAuth: 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. |
curl -X GET "https://api.contextrepo.com/v1/collections?limit=10" \
-H "Authorization: API-Key gm_your_api_key"{
"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.
curl -X GET "https://api.contextrepo.com/v1/collections/col_collection123" \
-H "Authorization: API-Key gm_your_api_key"{
"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
}
}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}/itemsAuth: 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) |
curl -X GET "https://api.contextrepo.com/v1/collections/col_collection123/items?limit=10" \
-H "Authorization: API-Key gm_your_api_key"{
"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/collectionsAuth: 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. |
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"
}'{
"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. |
Reparenting (changing parentCollectionId) is not currently supported via PATCH. Set the parent only at creation time via POST.
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" }'{
"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.
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}/itemsAuth: 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 |
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"
}'{
"data": {
"added": 2,
"alreadyInCollection": 0
}
}Remove Items from Collection
PUT /v1/collections/{id}/itemsAuth: 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 |
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"
}'{
"data": {
"removed": 1
}
}Search
Search Across Resources
GET /v1/searchAuth: 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. |
curl -X GET "https://api.contextrepo.com/v1/search?q=API+design+best+practices&type=all" \
-H "Authorization: API-Key gm_your_api_key"{
"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
}
}curl -X GET "https://api.contextrepo.com/v1/search?q=API+Design&semantic=false&type=documents" \
-H "Authorization: API-Key gm_your_api_key"{
"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.
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-q3Whitespace 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/promptsGET /v1/documentsGET /v1/collectionsGET /v1/search— applied symmetrically to theprompts,documents, andcollectionsbranches 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/searchAuth: 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 |
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
}'{
"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/expandAuth: 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 |
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
}'{
"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"
}
]
}
}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.
curl -X GET "https://api.contextrepo.com/v1/pd/read/hc_chunk001" \
-H "Authorization: API-Key gm_your_api_key"{
"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/sessionAuth: 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 |
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 }'{
"data": {
"sessionId": "sess_abc123",
"createdAt": 1710604800000,
"expiresAt": 1710608400000
}
}Reasoning
Synthesize an Answer
POST /v1/reasonAuth: Any valid authentication (reuses the documents.read scope — no new permission required)
Ask a question and get a synthesized, cited answer composed across your documents — not a list of chunks. The response includes inline citations to the exact chunks used, an explicit list of gaps, and any conflicts between sources. Read-only.
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The natural-language question to answer across your documents |
limit | number | No | Maximum number of evidence chunks to gather before synthesis (default: 8, max: 50) |
maxTokens | number | No | Token budget for gathered evidence passed to synthesis (default: 6000) |
documentId | string | No | Restrict reasoning to a single document |
collectionId | string | No | Restrict reasoning to a single collection |
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 }'{
"data": {
"answer": "Annual plans are refundable within the first 14 days...",
"citations": [
{
"chunkId": "hc_chunk001",
"documentId": "doc_abc123",
"documentTitle": "Billing Policy",
"score": 0.82
}
],
"gaps": ["No stated policy for partial-year downgrades"],
"conflicts": [],
"meta": {
"chunksGathered": 8,
"citationsDropped": 0,
"latencyMs": 1840
}
}
}MCP Capabilities
Get MCP Capabilities
GET /v1/mcp/capabilitiesAuth: None (public)
Returns the MCP protocol capabilities supported by Context Repo.
curl -X GET "https://api.contextrepo.com/v1/mcp/capabilities"{
"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:
{
"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
Authenticate API requests using a Bearer JWT session token or an API key from your Context Repo dashboard.
Versioning & Deprecation Policy
How the Context Repo REST API is versioned — additive-only changes within /v1, side-by-side majors, and a six-month deprecation runway signaled with Deprecation and Sunset headers.