Documentation API
Using the API
Base URL, authentication, the endpoint allowlist, errors, and rate limits - everything that applies to every request.
The ThoughtBridge API is a versioned JSON REST API. This page covers what applies to every request; the API reference documents each endpoint.
Base URL
https://thoughtbridge-api-238666896847.australia-southeast1.run.app/v1
All documented endpoints live under the /v1 prefix. A friendlier custom
domain is planned; the URL above is stable for the beta and this page will
be updated when the domain changes.
Authentication
Send your API key as a bearer token on every request:
curl -H "Authorization: Bearer tb_..." \
"https://thoughtbridge-api-238666896847.australia-southeast1.run.app/v1/projects"
What a key can reach
API keys work against a fixed allowlist. Requests to any other endpoint
return 403 API_KEY_FORBIDDEN regardless of scope.
| Method and path | Minimum scope |
|---|---|
GET /captures | read |
GET /captures/{captureId} | read |
GET /captures/{captureId}/files | read |
GET /captures/{captureId}/video-url | read |
GET /projects | read |
GET /projects/{projectId} | read |
POST /captures/upload-url, POST /captures/{captureId}/complete-upload | read_write |
POST /captures/{captureId}/video-upload-url, POST /captures/{captureId}/video-ready | read_write |
PATCH /captures/{captureId} (move to another project in the key’s set) | read_write |
PUT /captures/{captureId}/state | read_write |
PATCH /captures/{captureId}/analysis (edit summary and/or tasks) | read_write |
PATCH /captures/{captureId}/tasks/{taskIndex}, PUT /captures/{captureId}/task-states | read_write |
POST /captures/{captureId}/notes | read_write |
POST /captures/{captureId}/context-links, DELETE /captures/{captureId}/context-links/{linkId} | read_write |
POST /captures/{captureId}/media, DELETE /captures/{captureId}/video-artifacts/{index} | read_write |
POST /runner/register, GET /runner/queue, POST /runner/runs/{captureId}/claim, PATCH /runner/runs/{captureId}, GET /runner/chats, POST /runner/chats/{projectId}/reply | runner |
Any scope can use the read rows. The read_write rows need a
read_write key - see capture thoughts from anywhere
for the upload-url/complete-upload flow and API keys for
what else read_write unlocks. The runner rows need a runner key and
exist for the Bridget runner itself - you will not normally call them by
hand.
A key scoped to specific projects (see API keys) only
lists and reaches thoughts in that set; naming a project outside it returns
403 API_KEY_PROJECT.
Off limits to any key
A few operations are app-only regardless of scope. Deleting a capture,
retrying a failed one, and amending one (“add to my last capture”) never
take a key. Neither does minting or revoking a key, billing, or any
project/destination/runner-instance administration - renaming or deleting a
project, adding/updating/removing/resyncing a destination, forgetting a
runner instance - or Bridget chat, promotion, two-way sync, and bridge-it’s
execute/answer/merge/cancel. A project-scoped key hitting one of these
returns 403 API_KEY_OWNER_ONLY: the project owner has to do it from their
own account. See share a project for what
sharing does and doesn’t hand over.
Errors
Every 4xx and 5xx response carries the same JSON envelope:
{
"code": "NOT_FOUND",
"message": "Capture cap_abc123 not found",
"details": null
}
code is machine-readable (SCREAMING_SNAKE_CASE); message is for humans;
details optionally carries structured extras such as field-level
validation errors. Codes you will meet:
| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Malformed parameters or body. |
| 401 | UNAUTHORIZED | Missing, invalid, or revoked key. |
| 403 | API_KEY_FORBIDDEN | Endpoint not on the key allowlist. |
| 403 | API_KEY_SCOPE | Endpoint needs a higher scope than the key has. |
| 403 | API_KEY_PROJECT | A project-scoped key named a project outside its set. |
| 403 | API_KEY_OWNER_ONLY | An account/project administration endpoint - the owner must do it from their own account. |
| 404 | NOT_FOUND | Resource does not exist or is not yours. |
| 429 | - | Rate limit exceeded; retry after a pause. |
| 500 | INTERNAL_SERVER_ERROR | Something broke on our side. |
Rate limits
Requests are rate limited per account: 120 requests per 60-second window
across the API. Exceeding the limit returns 429; back off and retry. If
you are polling for changes, the updatedSince parameter on
GET /captures gets you everything new in one request a minute, well
inside the limit.
Versioning
Breaking changes will ship as a new version prefix (/v2), never as silent
changes to /v1. Additive changes (new fields, new endpoints) can appear on
/v1 at any time, so tolerate unknown fields in responses.