تخطَّ إلى المحتوى

Behaviour and Limits

هذا المحتوى غير متوفر بلغتك بعد.

Three behaviours of the Integration API will shape your integration whether you plan for them or not: what a key can reach, how fast it can call, and how long a revoked key keeps working. This page also states plainly what the API does not do, so you find out here rather than at 2am.

A key reaches only the rows it created. That is the whole rule, and it is enforced in one place for every route on this surface.

A row belongs to your integration when both of these hold:

  • its owner is your integration — derived from the stable integration_id, not from the key material, so it survives credential rotation; and
  • its team matches the team your key carries.

Everything else is out of reach:

RowReachable?
Created by this key’s integration, in this key’s teamYes
Created by a human in the same tenant, privateNo
Created by a human in the same tenant, shared tenant-wideNo
Created by this integration but in a different teamNo
Created by a different integrationNo
In a different tenantNo
Pre-existing, with no recorded ownerNo

The factory routes narrow this further: a flow-mode session your key genuinely owns is still a 404 on /api/v1/factory/assistants/{id}, because a flow row is not an assistant. It is reachable on /api/v1/sessions/{id}.

  • Store the ids you create. You cannot discover a row you did not create, and there is no route that lists another owner’s work.
  • Treat the key as the tenant boundary. No request field selects a tenant or a team, so one key per tenant/team is the unit of scoping.
  • A rotated key keeps its rows. A different key is a different owner, even in the same tenant.

Each integration_id gets a token bucket:

ParameterValue
Sustained rate60 requests per minute (1 token per second)
Burst capacity120 requests back-to-back before the sustained rate binds
Over the limit429 rate_limited with a Retry-After header

Retry-After is a whole number of seconds until the next token is available, minimum 1. Honour it — retrying sooner just spends another refused request.

The bucket is shared across every route on this surface. A knowledge sync and an assistant publish draw from the same 60/minute.

A newly seen key starts with a full burst of 120, which is enough for a modest initial sync in one go. Size a bulk load around the sustained rate, not the burst.

The reverse direction is quicker. A key the admin rejects is remembered as invalid for only 10 seconds, so a newly minted key becomes usable within about ten seconds even if something called with it before it existed.

Both windows are ceilings, not schedules: any request after the cached entry expires re-checks the admin.

Every outcome that is not “the admin says this key is active” refuses the request. There is no fallback that lets a request through unverified, and no stale positive is served when the admin is unreachable.

OutcomeResponse
Admin does not recognise the key401 invalid_api_key
Admin resolves it, status is not active403 integration_disabled
Admin resolves it, status is one this build does not recognise403 integration_disabled
Admin unreachable, timed out, rate-limited, erroring, or undecodable503 integration_auth_unavailable
No admin attached to this deployment503 integration_auth_unavailable

Treat 503 integration_auth_unavailable as retryable with backoff; it says nothing about your key. Treat 401 and 403 as terminal until a human intervenes.

Each of these is a current boundary of the product, stated so you can design around it rather than debug into it.

For the browser-facing half of a chat integration, use the WebChat widget, which is designed for it:

Build agentic workers through a flow session

Section titled “Build agentic workers through a flow session”
  1. Verify the key’s scope with GET /api/v1/knowledge/whoami and assert the tenant and team your code expects.

  2. Persist every id you create. Ownership means you cannot rediscover a row you did not create.

  3. Match on error.code, never on error.message. Messages are English fallbacks and may change.

  4. Treat every 404 as “not reachable” — do not branch on missing versus forbidden.

  5. Back off on 429 using Retry-After, and size bulk work against 60 requests/minute rather than the 120 burst.

  6. Retry 503 integration_auth_unavailable with backoff; do not retry 401 or 403.

  7. Document the 60-second revocation window in your own runbook, so an on-call engineer is not testing whether revocation worked.

  8. Fail your build when a publish reports unreachableTools unless you have deliberately accepted it — and default the field first (published.unreachableTools ?? []), because it is omitted on a clean publish rather than sent empty.

  9. Keep the key on your server. No CORS, and no reason to ship a tenant-wide credential to a browser.