API reference
POST /index
Trigger an index run against a Git workspace. Idempotent at the file level via content hash.
The indexer worker exposes a single mutating endpoint that pulls a workspace, parses it, embeds its symbols, and persists everything into your tenant rows in Supabase Postgres.
Endpoint
POST https://api.prom.codes/index
Authorization: Bearer <PROMETHEUS_WORKER_TOKEN>
Content-Type: application/json
api.prom.codes is a transparent reverse proxy (Vercel Edge runtime,
Frankfurt) that forwards the request to the indexer worker on Railway.
CORS preflight (OPTIONS) is handled at the proxy, hop-by-hop headers
are stripped, and the upstream status and body are passed through
verbatim. The same surface is reachable under
https://prom.codes/api/v1/index if you prefer the main domain.
Request body
{
"workspaceId": "01J5...uuid",
"source": {
"type": "git",
"url": "https://github.com/owner/repo",
"ref": "main",
"auth": {
"type": "token",
"token": "ghp_..."
}
},
"options": {
"include": ["src/**/*.ts", "packages/**/*.{ts,tsx}"],
"exclude": ["**/*.test.ts", "**/node_modules/**"],
"maxFileSizeBytes": 524288
}
}
Fields
| Field | Type | Required | Notes |
|---|---|---|---|
workspaceId | UUID | yes | Pre-created workspace; tenant-scoped. |
source.type | "git" | yes | Only Git is supported today. local, s3 planned. |
source.url | string | yes | HTTPS clone URL. |
source.ref | string | no | Branch, tag, or commit SHA. Defaults to remote HEAD. |
source.auth.token | string | no | Required for private repos. |
options.include | string[] | no | Glob allow-list. Defaults to common code extensions. |
options.exclude | string[] | no | Glob deny-list applied after include. |
options.maxFileSizeBytes | integer | no | Skip files larger than this. Defaults to 512 KB. |
Response
{
"ok": true,
"runId": "01J6...uuid",
"fileCount": 124,
"symbolCount": 1812,
"chunkCount": 1812,
"embeddedCount": 1812,
"skippedUnchanged": 0,
"embedMs": 4220,
"provider": "voyage",
"model": "voyage-code-3",
"dim": 1024,
"region": "us"
}
skippedUnchanged reports how many files were skipped because their
SHA-256 content hash matched the previously indexed version. Run
POST /index twice in a row and you should see all files in the
skipped count — that is the file-level idempotency contract.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | INVALID_BODY | Schema validation failed. Body lists the offending field. |
| 401 | UNAUTHORIZED | Missing or invalid bearer token. |
| 403 | FORBIDDEN_WORKSPACE | Token does not own workspaceId. |
| 404 | WORKSPACE_NOT_FOUND | Workspace UUID does not exist. |
| 422 | CLONE_FAILED | Git clone failed; see details.gitStderr. |
| 500 | EMBED_FAILED | Embedding provider returned an error. |
| 502 | STORAGE_UNAVAILABLE | Supabase unreachable. Retry with backoff. |