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

POST writes to /v1/documents and /v1/documents/scrape accept an optional Idempotency-Key HTTP header. Sending the same key with the same body within a 24-hour window returns the original response byte-for-byte instead of re-executing the handler — agents can retry on network timeout without spawning duplicate rows or paying for duplicate Firecrawl scrapes.

Idempotency-Key: 8c3f1a92-7e4d-4f1b-9a01-2b7c5d6e8f10
EndpointStatus
POST /v1/documents/scrapeSupported
POST /v1/documentsSupported

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