Feature controls
Tenant kill switches: turn a whole capability family off for one environment, and keep it off no matter how broadly an API key is later minted.
A feature control is a kill switch an organization owner or admin sets on one environment: this environment does not use AI, or payments, or media — period. It is a governance control, not a per-key permission. Scopes decide what one API key may do and are chosen by whoever mints the key; a feature control survives someone minting a broader key later, which is exactly what a security questionnaire is asking about when it asks whether a capability can be switched off.
Every switch is per environment, so a project can lock production down and keep sandbox open for the same integration.
The feature families
These capability families can be disabled. Everything else — messages, contacts, templates, webhooks, billing, and sign-in — is core product and can never be turned off, because an organization could not tell that state apart from an outage.
| Family | What turning it off blocks |
|---|---|
ai | LLM completions, AI agents, and automations. Publishing, running, and resuming an automation are blocked, and incoming messages stop creating automation runs. Pausing one, cancelling a run, deleting, and rotating a webhook-trigger secret are not blocked. |
payments | Merchant collection, including creating a payment request and its hosted payment link, asking a payer to approve one (POST /v1/payments/{payment_id}/request-approval), and advancing a sandbox payment (POST /v1/sandbox/payments/{payment_id}/status). Reads stay open. |
agentic_payments | Agent-initiated Pix: enrolling a bank authorization and starting an agentic payment. Revoking an authorization and cancelling a payment are not blocked. |
media | New media entering the environment: POST /v1/media/uploads and the POST /v1/media/uploads/{asset_id}/completestep that makes an upload sendable, plus any send carrying the media itself — inline base64, or an external URL Tyxter fetches for you. |
broadcasts | Bulk sending: POST /v1/batches, and creating or updating an audience. |
provisioning | Getting new numbers, including POST /v1/phone-numbers/provision, connecting a number you already own, and API-key transfers when either the source or target environment has provisioning disabled (POST /v1/phone-numbers/{phone_number_id}/transfer). Disconnect and release are not blocked. |
Merchant payments and agentic payments are two switches rather than one on purpose: different rails, different counterparties, different risk. Automations sit under airather than beside it, because automations exist to run AI agents — a separate switch would leave a live path behind “AI is off”.
Each switch is normally read from the environment the request authenticates into. A phone-number transfer is the one API-key write that crosses environments, so it checks both the source and the target before moving the number.
What a disabled family still allows
A kill switch stops an organization spending and acting through a capability. It is deliberately not a blackout, and the three exceptions matter more than the rule:
- Reads always work. Disabling
mediahides nothing you already have; it stops new media arriving. Visibility is not a capability worth revoking, and a switch that also hid history would be indistinguishable from an outage. - Wind-down always works. Cancel, revoke, release, and delete keep working in a disabled family. The sharpest case is
provisioning: turning it off must never mean you cannot release numbers that are still billing you. - The dashboard is never blocked. The owners and admins who flip a switch are dashboard users. Gating them would mean turning
paymentsoff and then being unable to turn it back on.
Enforcement covers the programmatic doors — API keys on the /v1/* API, and tool calls on the product MCP server described on Build with AI— and it applies identically in sandbox and production. A switch that bound only production would leave sandbox exercising a capability the organization declared off.
Sending media that already exists is a further deliberate exception: a send that references a stored asset_id, or a provider-side media handle, is messaging rather than new media, so mediadoes not block it. What the switch stops is new bytes arriving — whether you upload them, inline them in the send, or point Tyxter at a URL to fetch.
The error
A blocked request answers 403 with type authorization_error and error.code feature_disabled. The message names the family and states that the key's scopes are not the cause. It is normally evaluated at the authenticated environment before any resource is looked up, so it never reveals whether a record exists. The cross-environment phone transfer first validates the confirmed source and target, then applies the target switch. It is not retryable — nothing about the request can clear it.
{
"error": {
"type": "authorization_error",
"code": "feature_disabled",
"message": "The \"media\" feature family is disabled for this environment. An organization owner disabled it; the API key's scopes are not the cause, so a different key will not restore access."
}
}The full envelope, including request_id and trace_id, is on the Errors page. A tools/call on the MCP server that lands in a disabled family is refused with the same feature_disabled code before the tool runs.
insufficient_scope or feature_disabled?
Both are 403, and the remedy is completely different — branch on the code, not the status:
| Code | What it means | What fixes it |
|---|---|---|
insufficient_scope | This key is too narrow for the operation. | Mint or request a key that carries the scope. An integrator can resolve it. |
feature_disabled | The organization turned this family off for this environment. | No key will work. An organization owner or admin must re-enable it in the dashboard. |
feature_disabled with a broader key, it will fail identically. Stop and hand off to an organization owner.Managing the switches
Feature controls live in the dashboard under Settings → Features, per project and environment. Any organization member can read the current state — a developer who hits feature_disabledshould be able to see why without waiting on an admin — and only owners and admins can change it. Every change is written to the organization's audit log.
There is deliberately no public API for changing a feature control, and there will not be one: exposing kill switches to API keys would let a leaked key disable the switch meant to contain it. Administration is session-authenticated only.
For a vendor or procurement review
The short answer to “can this tenant be prevented from using AI / payments / media / phone provisioning?” is yes, per environment, set by your own organization admins, enforced on API keys and on MCP tool calls, without depending on how narrowly any individual key was minted. Read this page alongside Trust & security, Data retention & privacy, and Multi-tenant platforms before a vendor review.