Auth Tokens

Every token type the retail API issues or accepts, what each one unlocks, and how long it lives.

Before You Start

Read the following guides before proceeding:

GuideWhy
Getting StartedPlatform overview and setup
Api BasicsRequired headers and request configuration
AuthenticationHow each token is obtained, with code

Overview

The retail API uses more than one kind of token, and they are not interchangeable. This page is the
inventory: what each one is, what it unlocks, and how long it lasts. Authentication
is where the flows and code live.

TokenObtained fromProvesUnlocksLifetime
S2S tokenPOST /api/v1/token (client credentials)Your company's identityEvery endpoint, with X-User-* headers naming the user48 hours
User tokenPOST /api/v1/user/authorizeOne specific userThe same endpoints, scoped to that user — no identity headers neededRead expires_at
Identity tokenPrivy or Crossmint, in your front endThe end user's sign-inExchange for a Wirex token — it is not a Wirex credential itselfSet by the provider
Action tokenPOST /api/v1/confirmation/signature/verify or POST /api/v1/confirmation/sms/verifyA fresh, deliberate confirmation by the userOne action type only — card details, 3DS, or phone verification5 minutes
KYC SDK tokenPOST /api/v1/user/verification-tokenNothing on its ownEmbedding the SumSub SDK in your appSet by SumSub
SumSub share tokenYou generate it at SumSubThat your SumSub applicant may be shared with WirexRegistering a user with verification you already holdSet by SumSub

Only the first two go in the Authorization header. The rest are inputs to a specific call.


Which One Do I Need?

You want toUse
Call any endpoint from your backendS2S token + X-User-Wallet / X-Chain-Id
Let a client app call Wirex directly, without your credentialsUser token
Sign users in with Privy or CrossmintIdentity token, exchanged for a Wirex token
Read a PAN, CVV or PINS2S or user token plus an action token
Approve a 3DS challenge in-appS2S or user token plus an action token
Confirm a phone numberS2S or user token plus an action token
Run KYC inside your own appKYC SDK token
Onboard a user you have already verified at SumSubSumSub share token

Bearer Tokens

S2S Token

Client-credentials token representing your company, not any user. HMAC-SHA256, scope partner:full,
48-hour validity. Because it carries no user, most endpoints require X-User-Wallet and X-Chain-Id
headers to name the user the request is for.

Cache it until shortly before exp and refresh with a margin. POST /api/v1/token is rate-limited
per IP and per client — back off exponentially on 429.

User Token

Issued from an S2S token plus identity headers, and scoped to that one user. Its purpose is to be
handed to a client application so the client can call Wirex directly without ever seeing your
client_secret.

A user token identifies its user, so identity headers are not needed on requests that carry it.

Which of the Two

S2S tokenUser token
RepresentsYour companyOne user
Lives onYour backend onlySafe to pass to a client app
Identity headersRequired on user-scoped endpointsNot needed
Blast radius if leakedEvery user in your companyOne user

Naming across trees. The Corporate API calls its client-credentials token the partner token,
and its second-leg scoped token the corporation token. Same two-step shape, different names —
see Corporate Authentication.


Action Tokens

Bearer tokens authenticate the caller. Action tokens prove the user just deliberately confirmed a
specific thing
, and are required on top of a bearer token for sensitive operations.

An action token is minted for one action_type and is rejected by any operation belonging to another.

Action Types

action_typeConfirmsObtainable by signatureObtainable by SMS
GetCardDetailsReading PAN, CVV and PINYesYes
3dsChallengeApproving or declining a 3DS challengeYesNo
VerifyPhoneConfirming a phone numberYesYes

Values are matched case-insensitively, but send them exactly as written above. An unrecognised value
fails with action_type: Invalid value for action type and issue: invalid_value.

3dsChallenge cannot be obtained through SMS. POST /api/v1/confirmation/sms rejects it with the
same invalid_value error as an unknown type — the signature route is the only way to mint it.

Obtaining One by Signature

POST /api/v1/confirmation/signature/verify

The user signs this exact message with the wallet's private key:

By signing this I confirm that I am executing action {action_type} at {nonce}
FieldTypeRequiredDescription
action_typestringYesThe action being confirmed
message_signaturestringYesSignature over the message above
nonceintegerYesUnix timestamp used when forming the message
public_keystringNoHex-encoded public key of the signer. Required on XRPL, where the address cannot be derived from the signature; ignored elsewhere

The nonce must be no more than 5 minutes old. An older timestamp is refused, so form the message
at signing time rather than reusing a value from earlier in the session.

Obtaining One by SMS

POST /api/v1/confirmation/sms
POST /api/v1/confirmation/sms/verify

The first call sends a code and returns a session; the second exchanges the code for the action token.
See Card Details for the full flow.

Validity

An action token is valid for 5 minutes and for one action type. The failures are distinct:

Errorerror_detailsMeaning
ErrorExpiredaction_token: expiredMore than 5 minutes old — mint a new one
ErrorInvalidFieldaction_token: invalid_purposeMinted for a different action_type
ErrorInvalidFieldaction_token: invalid_tokenMalformed
ErrorInvalidFieldaction_token: invalid_claimsClaims could not be parsed

invalid_purpose is the one that catches integrations out: it is not an expiry and retrying does not
help. Mint a token for the action you are actually performing.


KYC Tokens

These are SumSub credentials, not Wirex ones. They appear here because they are easy to confuse with
the tokens above.

TokenDirectionPurpose
KYC SDK tokenWirex → you (POST /api/v1/user/verification-token)Embed the SumSub SDK in your own app
Verification linkWirex → you (POST /api/v1/user/verification-link)Redirect the user to the hosted SumSub widget
SumSub share tokenYou → Wirex (sharing_data.sharing_token on registration)Reuse verification you already hold, instead of re-verifying

The share token runs opposite to every other token on this page — you generate it at SumSub and
send it to Wirex. See Shared KYC.


Handling

  • Store client_secret in a secrets manager. Never in source control, never in client-side code
  • Cache the S2S token until shortly before exp; refresh with a margin
  • A user token is that user's credential — scope it and expire it like one
  • Never log a full token; truncate for debugging
  • Use HTTPS with TLS 1.2 or later and validate certificates
  • Do not mint action tokens speculatively. They last 5 minutes and are tied to one action

Did this page help you?