Base URL
| Environment | URL |
|---|---|
| Production | https://api-production-285b.up.railway.app |
| Self-hosted | http://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:
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:
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.
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:
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:
| Endpoint | Limit |
|---|---|
POST /waitlist | 5/minute |
POST /early-access | 10/minute |
POST /workspaces | 10/minute |
POST /projects | 10/minute |
POST /workspaces/{id}/tokens | 10/minute |
POST /workspaces/{id}/tokens/{id}/revoke | 20/minute |
POST /projects/{id}/rescan | 30/minute |
POST /projects/{id}/findings/{id}/patch | 20/minute |
POST /projects/{id}/patches/{id}/approve | 20/minute |
POST /projects/{id}/findings/{id}/approve | 20/minute |
POST /projects/{id}/patches/{id}/pr | 20/minute |
POST /jobs/drift | 30/minute |
POST /jobs/publish | 20/minute |
POST /auth/cli/exchange | 10/minute |
POST /internal/revalidate | 60/minute |
POST /integrations/github/webhooks | 60/minute |
POST /integrations/github/installations/{id}/sync | 20/minute |
When a rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header.
Error codes
| Status | Meaning |
|---|---|
400 | Bad request -- invalid payload, missing MCP tool name, or unsupported MCP method |
401 | Authentication required or invalid token |
403 | Permission denied -- insufficient scope or non-service auth for admin endpoints |
404 | Resource not found -- project, finding, patch, or preview does not exist |
422 | Validation error -- invalid email, malformed input |
429 | Rate limit exceeded |
503 | Internal secret not configured (for internal endpoints) |
Error responses follow this shape:
{
"detail": "Human-readable error message"
}
Security headers
All responses include:
| Header | Value |
|---|---|
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Strict-Transport-Security | max-age=31536000; includeSubDomains |
Content-Security-Policy | default-src 'self' |
Endpoints
Health and system
GET /
Returns the service name, project, and public site URL. No authentication required.
{
"name": "Documint V1",
"project": "Documint",
"site": "https://documint.xyz"
}
GET /health
Returns backend health including cache stats and runtime details. No authentication required.
{
"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:
{
"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:
{
"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:
{
"name": "ci-token",
"scopes": ["read", "write"]
}
Response:
{
"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.
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:
{
"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.
{
"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:
{
"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:
{
"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.
{
"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:
{
"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:
{
"title": "docs: update add_memory() parameter table"
}
Publishing
POST /jobs/publish
Publish repo-backed markdown into Documint-hosted public pages.
Request body:
{
"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.
{
"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:
| Event | Behavior |
|---|---|
push | Extracts changed files from commits, runs scoped drift check |
pull_request | Triggers full artifact drift evaluation, creates GitHub Check Run for inline PR annotations |
release | Triggers full artifact drift evaluation |
installation / installation_repositories | Syncs 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.
{
"server": { "name": "documint", "version": "0.3.0" },
"transport": "http-jsonrpc",
"tools": [...]
}
POST /mcp
Execute MCP tool calls via JSON-RPC.
Request body:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_projects",
"arguments": { "workspace_id": "ws_abc" }
}
}
Response:
{
"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:
{
"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:
{
"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.