Base URL

EnvironmentURL
Productionhttps://api-production-285b.up.railway.app
Self-hostedhttp://127.0.0.1:8000 (default)

The API version is 0.3.0. All endpoints return JSON unless otherwise noted.


Authentication

The API supports three authentication methods, evaluated in order:

1. Service token (Bearer)

Set AUTH_TOKEN or DOCUMINT_AUTH_TOKEN as an environment variable on the server. Clients pass it as a Bearer token:

bash
curl -H "Authorization: Bearer $AUTH_TOKEN" \
  https://api-production-285b.up.railway.app/projects

Service tokens have full access and bypass workspace scoping.

2. API token (Bearer)

Workspace-scoped tokens created via the token management endpoints. Tokens are prefixed with dm_ and carry workspace and scope metadata:

bash
curl -H "Authorization: Bearer dm_live_abc123..." \
  https://api-production-285b.up.railway.app/projects

3. Clerk JWT (Bearer)

When CLERK_JWKS_URL and CLERK_ISSUER are configured, the API verifies Clerk-issued JWTs using RS256. Optionally set CLERK_AUDIENCE to restrict accepted tokens.

bash
curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  https://api-production-285b.up.railway.app/me

4. CLI token exchange

Exchange a short-lived Clerk session for a stored API token:

bash
curl -X POST https://api-production-285b.up.railway.app/auth/cli/exchange \
  -H "Authorization: Bearer $CLERK_JWT" \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "ws_abc", "name": "cli-token"}'

Debug mode

When DEBUG=true and the client connects from localhost (127.0.0.1, ::1, or localhost), authentication is optional. This is intended for local development only.


Rate limiting

Rate limits are enforced per client IP using SlowAPI. Default: 120 requests/minute globally.

Specific endpoints have tighter limits:

EndpointLimit
POST /waitlist5/minute
POST /early-access10/minute
POST /workspaces10/minute
POST /projects10/minute
POST /workspaces/{id}/tokens10/minute
POST /workspaces/{id}/tokens/{id}/revoke20/minute
POST /projects/{id}/rescan30/minute
POST /projects/{id}/findings/{id}/patch20/minute
POST /projects/{id}/patches/{id}/approve20/minute
POST /projects/{id}/findings/{id}/approve20/minute
POST /projects/{id}/patches/{id}/pr20/minute
POST /jobs/drift30/minute
POST /jobs/publish20/minute
POST /auth/cli/exchange10/minute
POST /internal/revalidate60/minute
POST /integrations/github/webhooks60/minute
POST /integrations/github/installations/{id}/sync20/minute

When a rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header.


Error codes

StatusMeaning
400Bad request -- invalid payload, missing MCP tool name, or unsupported MCP method
401Authentication required or invalid token
403Permission denied -- insufficient scope or non-service auth for admin endpoints
404Resource not found -- project, finding, patch, or preview does not exist
422Validation error -- invalid email, malformed input
429Rate limit exceeded
503Internal secret not configured (for internal endpoints)

Error responses follow this shape:

json
{
  "detail": "Human-readable error message"
}

Security headers

All responses include:

HeaderValue
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Strict-Transport-Securitymax-age=31536000; includeSubDomains
Content-Security-Policydefault-src 'self'

Endpoints

Health and system

GET /

Returns the service name, project, and public site URL. No authentication required.

json
{
  "name": "Documint V1",
  "project": "Documint",
  "site": "https://documint.xyz"
}

GET /health

Returns backend health including cache stats and runtime details. No authentication required.

json
{
  "status": "healthy",
  "project_id": "documint-self",
  "repo_root": "/app",
  "docs_root": "/app/content/docs",
  "cache": { "redis_cache": { "connected": true } },
  "runtime": { "commit_ref": "abc123", "deployment_provider": "railway" }
}

GET /runtime

Returns deployment metadata, commit source, and git availability.

GET /metrics

Returns Prometheus metrics in text/plain format. Tracks http_requests_total (by method and endpoint) and http_request_duration_seconds.


Identity

GET /me

Returns the current operator identity and visible workspaces. Requires authentication.

POST /auth/cli/exchange

Exchange a Clerk JWT for a stored API token.

Request body:

json
{
  "workspace_id": "ws_abc",
  "name": "my-cli-token"
}

Workspaces

GET /workspaces

List workspaces visible to the authenticated user.

POST /workspaces

Create a new workspace.

Request body:

json
{
  "name": "My Team",
  "slug": "my-team"
}

Workspace tokens

GET /workspaces/{workspace_id}/tokens

List API tokens for a workspace.

POST /workspaces/{workspace_id}/tokens

Create a new scoped API token.

Request body:

json
{
  "name": "ci-token",
  "scopes": ["read", "write"]
}

Response:

json
{
  "id": "tok_abc",
  "name": "ci-token",
  "token": "dm_live_...",
  "scopes": ["read", "write"],
  "created_at": "2026-03-24T14:30:00Z"
}

POST /workspaces/{workspace_id}/tokens/{token_id}/revoke

Revoke an API token. Returns the revoked token summary.


Projects

GET /projects

List all projects. Optionally filter by workspace_id query parameter.

bash
curl -H "Authorization: Bearer $TOKEN" \
  "https://api-production-285b.up.railway.app/projects?workspace_id=ws_abc"

POST /projects

Create a new project.

Request body:

json
{
  "name": "My API",
  "slug": "my-api",
  "workspace_id": "ws_abc",
  "github_repo": "acme/my-api"
}

GET /projects/{project_id}

Get a composed project snapshot with findings, patches, and publish history.

GET /projects/{project_id}/status

Get a summary of project health: drift status, last scan, and open findings count.

json
{
  "project_id": "proj_abc",
  "name": "My API",
  "open_findings": 3,
  "last_scan": "2026-03-24T14:30:00Z"
}

GET /snapshot

Get the full project snapshot for a project. Accepts optional project_id query parameter.


Drift detection

POST /projects/{project_id}/rescan

Trigger a fresh documentation drift scan for a project.

Optional request body:

json
{
  "project_id": "proj_abc",
  "signal_type": "manual",
  "changed_files": ["src/api.py"]
}

Response: A job object with job_id and status.

POST /jobs/drift

Run the drift detector directly (alternative to /rescan).

Request body:

json
{
  "project_id": "proj_abc",
  "signal_type": "webhook",
  "changed_files": ["src/api.py", "src/models.py"]
}

Findings

GET /projects/{project_id}/findings

List open drift findings for a project. Each finding includes severity, summary, changed symbols, and suggested actions.

GET /projects/{project_id}/findings/{finding_id}/symbol-diff

Get a symbol-level diff showing exactly what changed in source code signatures vs. documentation.

json
{
  "finding_id": "finding_xyz",
  "project_id": "proj_abc",
  "artifact_id": "api-reference",
  "changes": [
    {
      "symbol_name": "add_memory",
      "change_type": "PARAM_ADDED",
      "severity": "BREAKING",
      "before": "def add_memory(content: str) -> str",
      "after": "def add_memory(content: str, ttl: int = 3600) -> str"
    }
  ]
}

Patches

GET /projects/{project_id}/patches

List all patch drafts for a project.

GET /projects/{project_id}/patches/{patch_id}

Get a specific patch draft with preview markdown, rationale, and citations.

POST /projects/{project_id}/findings/{finding_id}/patch

Generate a patch draft for a specific finding.

Optional request body:

json
{
  "policy": "on_demand"
}

POST /projects/{project_id}/patches/{patch_id}/approve

Approve a patch by its patch ID and create a GitHub PR.

POST /projects/{project_id}/findings/{finding_id}/approve

Approve the most recent patch for a finding (convenience endpoint for MCP agents). Creates a GitHub PR with the documentation fix.


Pull requests

POST /projects/{project_id}/patches/{patch_id}/pr

Open a GitHub pull request for an approved patch.

Optional request body:

json
{
  "title": "docs: update add_memory() parameter table"
}

Publishing

POST /jobs/publish

Publish repo-backed markdown into Documint-hosted public pages.

Request body:

json
{
  "project_id": "proj_abc"
}

GET /projects/{project_id}/publishes

List publish deployments for a project.

GET /projects/{project_id}/publishes/{deployment_id}

Get a specific publish deployment.

GET /previews/{preview_id}

Get a preview deployment by ID.


Activity and context files

GET /projects/{project_id}/activity

Get the project activity timeline (scans, patches, PRs, publishes).

GET /projects/{project_id}/claude-md

Get the CLAUDE.md context file for a project.

GET /projects/{project_id}/agents-md

Get the AGENTS.md guide for a project.

GET /projects/{project_id}/llms-txt

Get the llms.txt index (per llmstxt.org spec).

GET /projects/{project_id}/llms-full-txt

Get the llms-full.txt content (expanded version of llms.txt).

GET /projects/{project_id}/coverage

Get documentation coverage report: percentage of symbols documented per artifact.

json
{
  "project_id": "proj_abc",
  "artifacts": [
    {
      "id": "api-reference",
      "name": "API Reference",
      "documented": 18,
      "total": 20,
      "percentage": 90.0
    }
  ],
  "overall": {
    "documented": 45,
    "total": 52,
    "percentage": 86.5
  }
}

Artifacts

GET /artifacts/{artifact_id}/trace

Explain which source files and doc files back an artifact. Accepts optional project_id query parameter.


Jobs

GET /jobs/{job_id}

Get the status of a queued or completed job.

GET /projects/{project_id}/jobs

List all jobs for a project.


Sources and integrations

GET /sources

Get the Git repository source configuration.

GET /integrations/github/app

Returns GitHub App metadata, required events, permissions, and the install URL.

GET /integrations/github/installations

List GitHub App installations for a workspace. Requires workspace_id query parameter.

GET /integrations/github/installations/{installation_id}/repositories

List repositories available through a GitHub App installation.

POST /integrations/github/installations/{installation_id}/sync

Sync repository metadata from a GitHub App installation.

POST /integrations/github/webhooks

Receives GitHub webhook deliveries. Authenticated via X-Hub-Signature-256 using GITHUB_WEBHOOK_SECRET.

Supported events:

EventBehavior
pushExtracts changed files from commits, runs scoped drift check
pull_requestTriggers full artifact drift evaluation, creates GitHub Check Run for inline PR annotations
releaseTriggers full artifact drift evaluation
installation / installation_repositoriesSyncs installation metadata and repository list

Unsupported events and mismatched repositories are acknowledged with "status": "ignored".


Public docs

GET /public/projects/{workspace_slug}/{project_slug}/docs

Returns the hosted docs index page for a published project. No authentication required.

GET /public/projects/{workspace_slug}/{project_slug}/docs/{path}

Returns a specific hosted documentation page. No authentication required.


Internal

POST /internal/revalidate

Records a publish revalidation request. Authenticated via X-Documint-Internal header with the INTERNAL_REVALIDATE_SECRET.

POST /admin/bootstrap-self

Seed the self-dogfood workspace and project. Requires service auth or debug mode.


MCP surface (HTTP JSON-RPC)

GET /mcp

Returns the MCP server manifest including version and tool definitions.

json
{
  "server": { "name": "documint", "version": "0.3.0" },
  "transport": "http-jsonrpc",
  "tools": [...]
}

POST /mcp

Execute MCP tool calls via JSON-RPC.

Request body:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_projects",
    "arguments": { "workspace_id": "ws_abc" }
  }
}

Response:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{ "type": "text", "text": "..." }],
    "structuredContent": { "projects": [...] }
  }
}

Supported methods: tools/list, tools/call.

Available tools: list_projects, analyze_repository, detect_doc_drift, generate_doc_patch, review_doc_patch, publish_preview, explain_doc_trace, get_project_activity.


Waitlist and early access

POST /waitlist

Join the Documint waitlist.

Request body:

json
{
  "email": "dev@example.com",
  "source": "landing"
}

POST /early-access

Submit the brain teaser answer for early access. Correct answer grants an API token immediately; incorrect answer adds to the waitlist.

Request body:

json
{
  "email": "dev@example.com",
  "answer": "312211"
}

Production deployment notes

When the backend runs in a container without a .git directory, the current revision is read from platform-provided environment variables in this order: DOCUMINT_DEPLOY_COMMIT, RAILWAY_GIT_COMMIT_SHA, VERCEL_GIT_COMMIT_SHA, GITHUB_SHA.

Production mode requires:

  • PostgreSQL (SQLite is only supported for local/test)
  • Redis cache
  • DEBUG=false
  • GitHub App credentials configured
  • Clerk JWT verification configured
  • Job execution mode set to queue (with an arq worker)

See the self-hosted guide for full setup instructions.