Use the Brief API
Authenticate with Brief's versioned API, find endpoints, handle limits, and read or record team status declarations.
The Brief API is available at https://app.briefhq.ai/api/v1. Send a personal API key as a bearer token to list documents:
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://app.briefhq.ai/api/v1/documents
Create a key in the Brief app under Integrations → Connect Brief Into Another Tool → API Keys → New Key…. Choose a personal key for your own access or a workspace key for an integration shared by the workspace. A workspace administrator must create a workspace key. Keep the full secret when it is shown at creation; the key list shows its name, scope, prefix, and last use, and lets you revoke it. Revoke a key you no longer need. Personal keys are tied to their creator, and key access still follows the caller's document and workspace permissions.
Document routes require a user identity with access to the document. A workspace API key has no user identity for document access, so it cannot list documents with the request above; that request returns 404 with a workspace key.
Most protected reads need a read scope; writes need a write scope. An OAuth client uses mcp:read and mcp:write for those operations. A write scope alone does not grant access to ordinary protected reads, but GET /health accepts a write-only credential so you can check it. A request without sufficient access returns 403.
Manage API keys
Use the API Keys section in Integrations to create, rename, or revoke a key. A personal key represents its creator; a workspace key is managed by a workspace administrator. Keys created in this screen have read and write access. If a key is lost, create a replacement and revoke the old key; the complete secret is shown at creation.
The API also provides GET and POST /api-keys/personal for personal key management and GET and POST /api-keys for workspace keys. The personal management routes require a human session; workspace key management requires a workspace administrator. A bearer API key alone cannot use these management routes as a substitute for an administrator's session.
Find an endpoint
The OpenAPI specification lists request fields and responses. Common routes include:
| Task | API route |
|---|---|
| List or create documents | GET or POST /documents |
| Read or update a document | GET or PATCH /documents/{id} |
| List or create folders | GET or POST /folders |
| Read or update a folder | GET or PATCH /folders/{id} |
| Browse the folder tree | GET /folders/tree |
| Search | GET /search?query=<text> |
| List or record decisions | GET /decisions or POST /decisions/record |
| Review decision versions | GET /decisions/{id}/history |
| List or create features | GET or POST /features |
| List or create research signals | GET or POST /research-signals |
| Read a research signal | GET /research-signals/{id} |
| Read or update product context | GET or PUT /product-context |
| Read current product state | GET /product-context/current-state |
| Read work pipeline | GET /work-pipeline |
| List workspace skills | GET /skills |
| Track an event | POST /events/record |
| List workspaces available to the caller | GET /workspaces |
| Check a credential | GET /health |
Prefix each route with https://app.briefhq.ai/api/v1. See Documents, Decisions, and Features for the corresponding product workflows.
For routes in the OpenAPI specification, use it for request and response fields. The status declarations route described below is not yet listed there; use the request details on this page for that route. For example, GET /documents accepts folder_id, page, limit, or cursor; its response includes documents and pagination. The server checks document access when listing a folder, so a folder that is empty or unavailable to you can return the same empty list. POST /features expects an object under feature, while other create routes have their own body shapes. Read a route's schema before sending a write.
For search, pass the question as the query parameter. For document creation, supply title, folder_id, and optional Markdown content in JSON. The folder and document routes also support moving, updating, and deleting items; check the OpenAPI operation for the exact method and body before a destructive request. Research signal creation needs captured quote evidence from an eligible source, so an unsupported quote can cause a 400 response.
For a personal API key, GET /workspaces lists only the key's workspace. An OAuth caller can see the workspaces it belongs to. If a request fails with 401, check the bearer key; with 403, check its capability and your role; with 404, check the route, ID, and access to that item.
Team status declarations
GET /status-declarations returns current declarations for the workspace. Add as_of=<ISO-8601 timestamp with a UTC offset> to read the declarations effective at that time. To narrow the read to one signal, provide provider, container_identity, and signal_identity together. Add history=true to that scoped request to see all its versions; history=true cannot be combined with as_of.
For example, read one signal's version history with GET /status-declarations?provider=linear&container_identity=project-123&signal_identity=status-456&history=true. The scope values should be the provider's stable identities for the signal you intend to describe.
A workspace administrator can create a version with POST /status-declarations from an authenticated human session. A bearer API key or OAuth token cannot perform this administrator-only write. The JSON body is:
{"provider":"linear","containerIdentity":"project-123","signalIdentity":"status-456","declaredMeaning":"Ready for customer review"}
The body requires provider, containerIdentity, signalIdentity, and declaredMeaning. Each changed meaning creates a new version. Repeating the same meaning returns the existing version. This endpoint has no PATCH or PUT operation and no UI for editing declarations.
Use a declaration to record your team's interpretation of a provider status, label, channel, or folder. The declaration records that interpretation; it does not establish that the interpretation has been verified or automatically change downstream product data. declaredMeaning is free text of up to 2,000 characters. Provider and identity fields must be nonempty and at most 500 characters each. A new version returns 201; repeating the current meaning returns 200. To inspect changes, request a single signal with all three scope fields and history=true. A partial scope, unscoped history, an invalid as_of, or history combined with as_of returns 400.
Errors and limits
Check the HTTP status and response body for errors; error fields vary by route. For a 429 response, follow the Retry-After header when present. The shared API-key limit includes retry_after in the body; other route limits can use different fields. Most versioned routes share API-key limits of 20 requests per minute, 200 per hour, and 4,000 per day. Some streaming and polling routes skip these shared limits; some endpoints have additional limits.
For a changed request that times out, read the resource before retrying: the first attempt may have succeeded. Keep the key in a secret manager and send it only to your Brief deployment's API address. The API returns JSON errors, but response fields vary by endpoint; handle the HTTP status even when an optional error code or hint is absent.
Brief's CLI and terminal client send their versions with API requests. If one is below its configured minimum, the API returns 426 with an upgrade instruction. Other clients should not assume a minimum version applies to them.