Context RepoContext Repo Docs
API Reference

Authentication

Authenticate API requests using a Bearer JWT session token or an API key from your Context Repo dashboard.

Every API request requires an Authorization header. Context Repo supports two authentication methods: Bearer JWT for session-based access and API-Key for programmatic integrations.

Bearer JWT

Use a session JWT token when making requests on behalf of a signed-in user. This is the same token your browser uses when you're logged into the dashboard.

Header format:

Authorization: Bearer <session_jwt_token>

The token must be a valid, non-expired session token issued by your signed-in dashboard session. Browser-based integrations built on top of Context Repo retrieve this token from their existing authenticated session — refer to your auth provider's documentation for the exact retrieval call.

Bearer tokens have full access to all resources owned by the authenticated user — they aren't restricted by permission scopes.

Bearer JWT authentication is primarily for browser-based, signed-in usage. For scripts, CLI tools, MCP clients, and server-to-server integrations, use an API key — it's simpler to set up and longer-lived.

API Key

API keys provide scoped, long-lived access for external tools, scripts, and integrations like the Chrome Extension and MCP clients.

Header format:

Authorization: API-Key <your_api_key>

The header name API-Key is case-sensitive. API keys generated by the dashboard have the shape gm_<publicId>_<secret> — for example:

Authorization: API-Key gm_aB3cD4eF5gH6_xK9mN2pQ7rS5tU8vW1yZ3aB6cD9eF2gH5jK7

Getting an API Key

  1. Open the Context Repo dashboard
  2. Go to Settings > API Keys
  3. Click New API Key
  4. Give it a name and select the permission scopes you need
  5. Click Create and copy the key immediately — it's only shown once

For a detailed walkthrough of key creation, viewing, and revoking, see the Settings page.

Permission Scopes

API keys are scoped per resource and per access kind. Four scopes are available:

ScopeLabelWhat It Allows
prompts.readPrompts — ReadList, read, search, and inspect prompt versions
prompts.writePrompts — WriteCreate, update, delete, and restore prompt versions. Implies prompts.read.
documents.readDocuments & Collections — ReadList, read, deep-search, and export documents and collections
documents.writeDocuments & Collections — WriteCreate, update, delete, restore versions, scrape URLs, and manage collection memberships. Implies documents.read.

When you create a key in the dashboard, you pick None / Read / Write per resource — there is one selector for Prompts and another for Documents & Collections. Selecting "Write" automatically grants the matching read access, so you don't need to select both.

If your API key doesn't have the required scope for an endpoint, the API returns a 403 Forbidden error. Make sure you've assigned the right scopes for your use case.

Scope Requirements by Endpoint

Read methods (GET) require the matching .read scope; write methods (POST/PATCH/DELETE/restore) require the matching .write scope (which already includes .read).

Endpoint GroupRead methodsWrite methods
Prompts (/v1/prompts/*)prompts.readprompts.write
Documents (/v1/documents/*)documents.readdocuments.write
Document coordination (/v1/documents/{id}/coordination*)documents.readdocuments.write; only the owner can change policy
Document scraping (POST /v1/documents/scrape)documents.write
Collections (/v1/collections/*)documents.readdocuments.write
Search (GET /v1/search)At least one of prompts.read or documents.read
Progressive Disclosure (/v1/pd/*)documents.read
User profile (GET /v1/user/me)Any authenticated request
MCP Capabilities (GET /v1/mcp/capabilities)None — public, unauthenticated

Sandbox & Public Endpoints

Context Repo exposes one public, unauthenticated endpoint so agents, scanners, and integration tools can verify connectivity, content-type negotiation, and CORS behavior before provisioning credentials:

EndpointAuthPurpose
GET /v1/mcp/capabilitiesNoneReturns the MCP protocol version, advertised capabilities, and supported tool surface. Static manifest, safe to cache.

Sandbox curl

curl -i https://api.contextrepo.com/v1/mcp/capabilities

Expect a 200 OK with Content-Type: application/json, a 24-hour shared Cache-Control: public, max-age=86400, s-maxage=86400 header, and an X-API-Version: v1 header. The capabilities payload is a static manifest shared across every client, safe to cache aggressively at CDN and browser layers.

Demo workflow without credentials

Agents and automated scanners that need to exercise the full request → response → error-recovery cycle without authentication can probe the public capabilities endpoint, then deliberately malform requests against other /v1/* routes to walk through the typed error envelopes:

# Capability probe — 200 OK with version + tool list
curl -i https://api.contextrepo.com/v1/mcp/capabilities

# Auth-required endpoint without credentials — 401 with ErrorEnvelope
curl -i https://api.contextrepo.com/v1/documents

# Malformed body on a write — 400 with field-level details
curl -i -X POST https://api.contextrepo.com/v1/documents \
  -H "Authorization: API-Key gm_demo_invalid" \
  -H "Content-Type: application/json" \
  -d 'not-json'

Every error response uses the same ErrorEnvelope shape (see Error Format) — a single error path covers 400 / 401 / 403 / 404 / 409 / 413 / 429 / 500. Agents can therefore wire one parser against the public capability probe and re-use it across the authenticated surface.

Sandbox response headers

Every /v1/* 2xx response also carries machine-readable rate-limit and version signals so an agent can self-pace its budget and detect future deprecations without parsing release notes:

HeaderExamplePurpose
RateLimit-Limit100RFC 9598 — total requests allowed in the current window
RateLimit-Remaining99RFC 9598 — requests left in the current window
RateLimit-Reset2026-05-20T13:00:00.000ZRFC 9598 — ISO-8601 timestamp when the window resets
X-RateLimit-Limit / Remaining / Reset(same values)Legacy alias — preserved for older agents that grep for X--prefixed headers
X-API-Versionv1Route-version constant; switches to v2, v3, … when new majors ship
Deprecation?0RFC 9745 structured field — ?0 means not deprecated; flips to ?1 and gains a Sunset header when a version is retired

The publicly cacheable /v1/mcp/capabilities endpoint omits the RateLimit-* headers to keep its 24-hour CDN cache from baking one client's stale budget data into the response served to every other client. The X-API-Version and Deprecation headers still flow through because they are route-constant, not caller-scoped.

Why no anonymous write tier

Mutation endpoints (POST, PATCH, DELETE) require authentication by design: writes touch user-scoped resources, are versioned per user, and bill against per-user rate-limit buckets. To exercise the full surface — including the async scrape + poll loop documented in Asynchronous Operations — create an API key via Settings → API Keys.

Idempotency

Document create, update, restore, refresh, and scrape writes accept an optional Idempotency-Key HTTP header in standard editing mode. Coordinated document writes require it, and every lease operation requires it. Sending the same key with the same request within a 24-hour window returns the original compact response instead of re-executing the write.

Idempotency-Key: 8c3f1a92-7e4d-4f1b-9a01-2b7c5d6e8f10
EndpointStatus
POST /v1/documents/scrapeSupported
POST /v1/documentsSupported
PATCH /v1/documents/{id}Supported; required in managed mode
POST /v1/documents/{id}/restoreSupported; required in managed mode
POST /v1/documents/{id}/refreshSupported; required in managed mode
POST /v1/documents/{id}/coordination/leaseRequired

For a coordinated update, restore, or refresh, the header-based form sends the key with the document precondition and current lease:

If-Match: "<exact ETag from GET /v1/documents/{id}>"
Idempotency-Key: <unique retry key>
X-ContextRepo-Lease-Id: <lease ID>
X-ContextRepo-Lease-Fence: <fence number>

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.

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.

Sample replay

# First call — runs Firecrawl, returns documentId "doc_a1b2"
curl -i -X POST https://api.contextrepo.com/v1/documents/scrape \
  -H "Authorization: API-Key gm_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8c3f1a92-7e4d-4f1b-9a01-2b7c5d6e8f10" \
  -d '{"url":"https://example.com"}'
# HTTP/1.1 202 Accepted
# Location: /v1/documents/doc_a1b2

# Replay with the SAME key and body — Firecrawl is NOT invoked
curl -i -X POST https://api.contextrepo.com/v1/documents/scrape \
  -H "Authorization: API-Key gm_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8c3f1a92-7e4d-4f1b-9a01-2b7c5d6e8f10" \
  -d '{"url":"https://example.com"}'
# HTTP/1.1 202 Accepted
# Location: /v1/documents/doc_a1b2
# Idempotent-Replayed: true

Contract

BehaviorStatusNotes
Fresh keyoriginal status (201 / 202)Handler runs once; response is cached for 24h
Replay (same key + same body)original statusIdempotent-Replayed: true advisory header set
Same key + different body422 Unprocessable EntityReusing one key for two distinct payloads is rejected
Same key + first request still processing409 ConflictRetry after the first finishes
Invalid header (>255 chars / control chars / non-ASCII)400 Bad Request

Keys are scoped per-user and per-endpoint. Two different users sending the same key value get independent fresh executions; the same user can reuse a key value across POST /v1/documents and POST /v1/documents/scrape without collision.

TTL and failure caching

  • Ledger rows expire 24 hours after the first request and are purged by a background cron.
  • Successful responses (2xx) and deterministic client errors (4xx) are cached.
  • Transient server errors (5xx) are never cached — the ledger row is deleted on failure so a subsequent retry with the same key is treated as fresh.

Choosing an Auth Method

Use CaseRecommended Method
Browser-based integrationsBearer JWT
Chrome ExtensionAPI Key with documents.write (needed to save scraped pages)
MCP clients (Cursor, Claude Desktop, etc.)API Key with the scopes matching the MCP tools you'll use — for full read + write access, grant prompts.write and documents.write
CI/CD pipelines and scriptsAPI Key with the minimum scopes needed
Custom applicationsAPI Key for server-to-server, Bearer JWT for user-facing

Error Responses

Authentication failures return one of two status codes:

StatusMeaning
401 UnauthorizedMissing or invalid Authorization header — the token or key couldn't be verified
403 ForbiddenValid authentication, but the API key doesn't have the required permission scope
{
  "error": {
    "code": 401,
    "message": "Invalid authentication"
  }
}