Endpoint summary
| Verb | Path | Auth | Purpose |
|---|---|---|---|
| POST | /api_accounts |
provisioning | Create (idempotent by uid) |
| GET | /api_accounts |
provisioning | List + usage + pagination |
| GET | /api_accounts/:uid |
provisioning | Sync status and index size |
| DELETE | /api_accounts/:uid |
provisioning | Destroy the account and its content |
| POST | /api_accounts/:uid/resync |
provisioning | Re-crawl the website |
| PUT | /api_accounts/:uid/connections/:connection_uid |
provisioning | Connect a source (idempotent by uid) |
| GET | /api_accounts/:uid/connections |
provisioning | List one customer's connected sources |
| GET | /api_accounts/:uid/connections/:connection_uid |
provisioning | One source's status |
| DELETE | /api_accounts/:uid/connections/:connection_uid |
provisioning | Purge one source and its content |
| POST | /api_accounts/:uid/connections/:connection_uid/reauthorise |
provisioning | Fresh consent URL for a dead grant |
| GET | /context |
customer or provisioning | RAG context (org-wide with the provisioning token) |
| GET | /question |
customer or provisioning | Grounded answer with citations |
| POST | /context/save |
customer | Write a note to that customer's memory |
| GET | /ping |
customer or provisioning | Token health check |
| * | /custom_connections/* |
customer | Push markdown content |
Errors
Provisioning API (/api_accounts)
| Code | Meaning |
|---|---|
| 401 | Bad or missing provisioning token |
| 402 | Organisation is not on the white-label plan, its subscription has lapsed, or the automatic bundle add failed at the payment provider |
| 403 | The token holder is not an organisation admin |
| 404 | Unknown uid, a uid belonging to another organisation, or an id that is not an API account |
| 409 | resync while a sync is already running |
| 422 | Invalid uid, label, site_url (bad URL, explicit port, or embedded credentials) or webhook_url (bad URL, embedded credentials, or a private/loopback target), or a resync on an account with no website |
| 429 | Rate limited; honour Retry-After |
Connections API (/api_accounts/:uid/connections)
Same auth, same 401/402/403/429 as the rest of the provisioning API. The body carries an error_code alongside the message:
| Code | error_code |
Meaning |
|---|---|---|
| 404 | unknown_connection_type |
The connection_type is not a type Context Link has. The message lists the accepted values. |
| 403 | connection_type_not_activated |
Your organisation has not activated that type. Turn it on yourself at /white_label/connection_activations. |
| 409 | connection_limit_reached |
The customer already holds the maximum of that type, or of connections overall. |
| 409 | connection_type_immutable |
That uid already holds a different type. Changing type is a delete and recreate. |
| 409 | partner_credentials_required |
That OAuth type (any but Google Drive, which may run on Context Link's app) is turned on without your own OAuth keys. Add them, and whitelist our redirect URI on your app, at /white_label/connection_activations. |
| 422 | invalid_setup_fields |
A required setup field, or a return_url, is missing or invalid. errors carries one message per field. |
| 422 | connection_type_not_reauthorisable |
reauthorise on a type that has no authorisation to renew. |
Query API (/context, /question, /ping)
| Code | Meaning |
|---|---|
| 400 | Missing query parameter, or /context/save without a namespace |
| 401 | Missing Authorization header, or the organisation's subscription has lapsed |
| 402 | /question on an organisation whose plan doesn't include it |
| 403 | /context/save attempted with the provisioning token (org-wide mode is read-only) |
| 404 | Unrecognised token |
| 429 | Rate limited, or the monthly question allowance is spent |
| 503 | /question reached the model and it failed. The default payload has result: "llm_unavailable", answer: null, empty citations, and format: "markdown". With response_format=structured, it uses the shared structured envelope with markdown: null and empty results. Retry. |
/context and /question both accept the opt-in response_format=structured query parameter and then return the same format, query, markdown, and results envelope. If the parameter is absent or has any other value, each endpoint's existing payload is unchanged.
Note the asymmetry: a lapsed subscription reads as 401 on the query endpoints and 402 on the provisioning and custom-connections APIs. Both mean "check billing".
Custom Connections API
Documented in full on the Custom Connections page.
Limits
| Limit | Value |
|---|---|
| API accounts | 10 per bundle; bundles auto-added on overflow |
| Website crawl | 500 pages per API account |
| Connections per API account | 10, and the memory connection is exempt |
| Websites per API account | 1, counting toward the 10 |
| Custom connections per API account | 6, counting toward the 10 |
| Connected sources per type per API account | 5, counting toward the 10 |
| Posts per sync per connected source | 500 by default; lower where a sync is expensive: 30 for YouTube, 50 for Web Mentions |
| OAuth redirect link lifetime | 15 minutes |
| Questions | One pool shared across your whole fleet, sized at 5,000 questions per bundle per month |
| Custom-connection quotas | 1,000 posts / 100MB per connection; 100KB per post body |
| Write rate limit | 5 per 10s per token and per organisation |
10 is the binding ceiling. The per-type numbers are maxima within it, not slices that add up to it. A customer can hold 6 custom connections or 5 mailboxes, but not both, because the total still has to come in at 10. The memory connection is the one exception: it never counts.
Questions come out of one pool shared across your whole fleet, sized at 5,000 questions per bundle per month. One busy customer draws it down for every other customer you serve.
The per-organisation write limit is shared across your whole fleet, so a bulk backfill across many customers serialises at 5 writes per 10 seconds. Spread large migrations out.