spa_ tokens are accepted on /api/v2/agentic/*, and only on those endpoints. An API key sent to an agentic endpoint is rejected, and an agent credential sent to /api/v2/payments is rejected.
Token format
X-Livemode header on the agentic API and no way to switch a credential between modes after creation.
SouthPay stores a SHA-256 digest plus the first 16 characters for display. The full token is returned once, at creation, and cannot be recovered afterwards. If you lose it, revoke the credential and create another.
Agents send a standard bearer header on every request:
401 with code agent_credential_required. A token matching no active credential returns 401 with code invalid_agent_credential. Revoked and expired credentials stop working immediately.
Scopes
Omitting scopes at creation grants all eight. Pass an explicit list for least privilege. A call outside the credential’s scopes returns
403 with code insufficient_scope.
Scopes are independent, not hierarchical: a credential with payments:write still needs payments:read to list payments.
A scope is necessary but not sufficient for money movement. Refunds, token changes, payouts and mandate issuance are additionally gated, and deny by default. See agent authorization.
Creating a credential
There are two paths, and neither uses an API key.In the dashboard
Open Agents and create a credential, choosing the mode, a name, a principal for the audit trail, the scopes and an optional expiry. The full token is shown once. The same screen lists, revokes and shows per-credential activity, and is where you configure spend limits. The endpoints behind those screens accept dashboard sessions only. They are not part of the public API, so there is no API-key or OAuth-token equivalent for creating, listing or revoking credentials, including for a platform acting on a sub-merchant, which is refused with403 platform_cannot_issue_credentials.
Minting a credential from an OAuth token
If you are building an application that connects to merchant stores, exchange a user-consented OAuth access token for an agent credential. This is the public endpoint the MCP server’s browser login uses. The access token must hold theagents:write scope and must be bound to a store.
- The credential’s mode follows the OAuth grant’s
livemode, not a parameter. scopesis optional. Unknown values are dropped, and an empty or absent list falls back to the default scopes.- The
agent_principalis derived asoauth:{client_id}:{user_id}, so exactly one credential exists per application, user, store and mode. Calling this endpoint again for the same combination rotates the existing credential rather than creating a second one. Any key issued by an earlier call stops working at that moment. secretis the full token, present only on this response.
403 insufficient_scope if the token lacks agents:write, 422 store_required if the token is not bound to a store.
Spend limits
Spend limits are per-credential, per-asset payout caps set by the merchant in the dashboard. They do two jobs:- They unlock payouts. Without an authorization provider, an agent cannot pay out an asset at all until a spend limit exists for it. The attempt is refused with
403 payout_controls_requiredbefore any balance check runs. - They cap payouts. Each payout is checked against a per-transaction cap and a daily counter that resets at midnight UTC, returning
403 per_tx_cap_exceededor403 daily_cap_exceeded.
50000000 is 50 USDC. Either cap can be left unset, and a limit with only a daily cap still unlocks the asset.
An agent inspects its own headroom with GET /api/v2/agentic/payout_limits, or the get_payout_limits MCP tool:
Response 200
controls_configured: false on an asset predicts a payout_controls_required denial. Size payouts from this endpoint rather than discovering caps through a 403.
Activity and audit
Every payment, payout, refund and x402 settlement records the credential that created it, and agentic queries are filtered by that credential, so an agent sees only its own records, even on a store with several agents. Merchants review per-credential activity in the dashboard under Agents.Rate limiting
Agentic endpoints allow 600 requests per minute per credential in live mode, and 120 in test mode. One budget covers every agentic path. Over the limit, requests return429:
Response 429
429 carries a Retry-After header in seconds, and every response carries X-RateLimit-Remaining. GET /api/v2/agentic/market_data is outside this limit: it is unauthenticated and throttled at 30 requests per minute per IP.
