Two credential types
Both are plain bearer credentials: whoever holds the string can use it until it expires or is revoked. Neither is bound to a specific device or TLS session today — see Sender-binding (DPoP) below for where that’s headed.
TTL
API tokens don’t expire on their own — they’re meant to live in a secret manager on infrastructure you control, so there’s noexp to renew. Set an explicit expires_at at creation if you want one to lapse automatically (e.g. for a temporary integration).
Widget JWTs are signed by your server, so you choose the exp — keep it short (15–30 min). A widget session is handed to a browser, which is a much less trusted environment than your backend: a short TTL bounds how long a copy-pasted or logged token stays useful. Pair a short TTL with getAuthToken so the widget refreshes quietly instead of the session just dying — see token lifecycle and refresh.
Rotation
Both credential types rotate the same way: no overlap window. The moment you rotate, the old secret stops verifying — there’s no grace period where both the old and new secret work.- API tokens: hit Regenerate in the panel. In-flight requests using the old secret get
401immediately; retry with the new one. See Rotating. - Widget B2B secret: hit Rotate secret on the Widget page. Every JWT signed with the old secret — including ones already handed to visitors’ browsers — fails signature verification on its next request.
publicIddoesn’t change, only the signing secret, so once your token-minting endpoint picks up the new secret, sessions recover on their nextgetAuthTokencall.
401.
Rate limiting
Both credential types are rate-limited, and both return the same shape on a hit:- API tokens carry
per_minute/daily/monthlylimits set when you create the token (defaults60/1,000/10,000) — see full table. - Widget sessions are limited per end-user, not per token — you set
daily_message_limit,monthly_message_limit, andper_minute_message_limitas claims in each JWT you sign, so one visitor can never burn through your whole budget. See per-user message limits.
Retry-After and back off exponentially. Rejected requests don’t count against the bucket.
Sender-binding (DPoP)
Today, both credential types are classic bearer tokens — anyone who has the string can use it, full stop, until it’s rotated or expires. That’s standard for API tokens held by a backend you control, but it’s a real limitation for tokens that end up in a browser. Under consideration for a future release: DPoP (Demonstrating Proof-of-Possession) — binding a token to a public/private keypair generated client-side, so a copied bearer string alone isn’t enough to replay a request; the caller also has to prove it holds the matching private key. This isn’t implemented yet and isn’t scheduled — it’s noted here so the direction is visible, not as a commitment. If sender-binding matters for your threat model today, the mitigation is what’s already available: short TTLs,getAuthToken refresh, and rotating on any suspected leak.