Skip to main content
Use a short-lived client token to make requests from a browser or mobile app. Each token is limited to one session and the actions you permit. A Customer-scoped token instead covers the numbers one Customer owns.

Mint

Call POST /platform/client-tokens with a project or team key that has all of sessions:manage, messages:write, contacts:read, presence:read, presence:observe, and mcp. Updating session rules requires the same permissions. Tokens issued with action ceilings carry an immutable action ceiling. Every request intersects that ceiling with live session rules and current Number ownership. Rule edits cannot grant actions outside the ceiling. A human-owned team key or project token can mint only while its owner remains a team owner or admin and is not banned. Service-account credentials cannot mint tokens that permit messaging actions. The issuer must remain active and unrevoked, with the required scopes and current ownership of the selected Number or Customer. These checks apply to every mint, including token refreshes. A current issuer or ownership denial returns 403 without a token. If Polymorfa cannot complete the issuance checks, it returns 503 without a token.
The response contains the token and its expiry:
ttlSeconds must be within the bounds documented for the endpoint. The token is limited to its team, session, ephemeral ID, and expiry. Session allow requires enrollment in the action-ceilings beta. Until that beta is enabled, session allow requests are refused and omission retains the existing rule-based token format. Existing sealed ceilings remain enforced if new ceiling issuance is disabled. allow also accepts an explicit ceiling for a session token, including mcp and voip_* actions. An empty session allow grants no API actions. Customer allow must contain at least one action. Set the rules before minting. A token with no permitted actions needs reissuing after you configure its rules. The action names chats_read, chats_manage, contact_write, and contact_delete are reserved for enrolled regional beta access. Including a reserved action does not enable regional Contacts or Chats. Regional ceilings also require the corresponding chats:read, chats:manage, or contacts:manage issuer scope. These permissions do not authorize legacy WhatsApp chat routes. read_contact continues to cover its documented contact lookups; it grants no unrestricted access to a retained contact directory. Existing tokens cannot gain these reserved actions through a rule edit.

Session rules

Rules are managed independently:
PUT replaces the whole rule set. Omitted optional fields return to their defaults. Rules stay in effect until you replace or delete them, and deleting a session also deletes its rules. recipientMode is one of conversation, any, or none. Unknown modes fail closed. allowedActions is a comma-separated list containing only these values:

Conversation window

In conversation mode, a client token can send only to a contact who messaged the session within the conversation window. The window starts again with each new message from that contact. conversationTtlSeconds sets the window, in seconds: Values outside this range return 400. A window without an expiry is not available: a contact who has not messaged the session for more than 7 days must message it again before a client token can reply. The voip_* actions permit calling. Three optional rule fields limit calls: maxSetupsPerMinute (call setups per minute for each ephemeralId; 0 uses the default of 10), allowedNumber (a comma-separated list of E.164 numbers the token can call or invite), and maxConcurrency (calls held at once; 0 means no limit). See Calls. Client tokens never pair numbers. Use a QuickLink to connect a number from a browser or phone. The mcp action permits the protocol handshake. Each MCP tool still passes through its ordinary session, recipient, action, origin, and rate rules.

Customer-scoped tokens

Customer-scoped tokens are a beta. When the beta is offered to your team, a team owner or admin selects Join on its beta row on a project’s Numbers page and accepts the terms. Until the team has joined, minting with customer returns 403.
When a Customer owns several numbers, mint one token for the Customer instead of one per session. Pass the Polymorfa Customer ID in customer instead of session:
  • Send exactly one of session or customer.
  • customer is the Customer’s Polymorfa ID. Look up a Customer by your own external ID on your server first; tokens never accept an external ID.
  • The issuing key also needs customers:read. A project token can mint only for Customers in its project. A team key can mint for any Customer in the team. A Customer outside the key’s team or project returns 404.
  • The Customer must be active and own at least one number, and the project must have Customers enabled. A token covers at most 64 numbers; minting for a Customer with more returns 400.
The token covers the numbers the Customer owns at the moment you mint it. Each request is also checked against the Customer’s current numbers: Call the usual session routes with the number’s session ID in the path, for example POST /messaging/{session}/messages/send. Each request must also pass that session’s rules: a Customer-scoped token never allows more than the session’s rules do. allow narrows the token further. It accepts send_message, send_reaction, send_typing, send_seen, read_presence, subscribe_presence, and read_contact. Omit it for a Customer to use that original action set. For a session, omission snapshots the configured actions at mint time; missing rules produce a token with no actions. A Customer-scoped token can’t use calling (voip_*) or MCP; mint a session token for those.

Security behavior

  • Client tokens cannot mint other tokens, including Customer-scoped tokens.
  • Rules, recipient/conversation state, origin constraints, and rate limits are checked after the token authenticates.
  • Delete or disable the session rules to stop permitted effects before all issued tokens expire.
  • Each rule change appears in Audit logs as clientToken.rulesCreated, clientToken.rulesUpdated, or clientToken.rulesDeleted. The entry records which fields changed, the recipient mode, the limits, and the conversation window. It records how many origins and numbers are allowed, not the origins or numbers themselves.
  • If a PUT or DELETE returns 503 with code service_unavailable, Polymorfa stored the change but could not confirm that client tokens use it. Repeat the same request after the Retry-After delay.

Temporary unavailability

Client tokens fail closed. If Polymorfa cannot check a request’s rules, the request is refused instead of being allowed without checks:
  • 503 with code credential_verification_unavailable when the session rules cannot be loaded. The token is still valid; retry the request.
  • 503 with code service_unavailable and a Retry-After header when a per-minute rateLimit or the conversation window cannot be checked. Retry after the stated number of seconds.
See Mint a client token and Session rules in the Platform API reference.