Before you begin
- You’ll need the new client ID Marqeta issues for your program, along with the key ID (kid) for your public key — request them from your Marqeta representative if you don’t have them yet.
- Your existing signing key, scope, and token audience do not change as part of this migration.
- Your current setup keeps working until you switch over, so you can test the dedicated flow without a hard cutover.
Steps
Step 1 - Update your Customer Auth API service.
Once you’ve requested and received your new client ID from your Marqeta representative, you’ll need to update your custom Auth API service. This service mints (or proxies) the access token the SDK uses.- Point the token request at the dedicated host. Send POST /oauth/token to the dedicated host for your environment (see Endpoints by environment).
- Rebuild the client assertion. The client_assertion is a JWT signed with your existing private key.
The following changes to the Header:
The JWT header must now carry a ‘kid’ - the key ID Marqeta provides alongside your new client ID. It tells the dedicated host which of your registered public keys to verify the signature against.
The following changes need to be made to the payload (see Token exchange reference):- “iss” and “sub” change from your current ID to your new client ID.
- “aud” changes to include the full endpoint, not just the bare host
- “exp” is now capped at 5 minutes — the dedicated host rejects any assertion whose “exp” is more than 300 seconds after “iat”.
- “exp” changes to 1717000300 and will now be capped at 5 minutes, anything longer will be rejected.
Note
Leave audience pointed at the UX Toolkit API. The audience form parameter does not change, — it stays the UX Toolkit API host for your environment, but the trailing slash is removed from the end. The token is minted by the dedicated host but intended for the UX Toolkit API. Don’t confuse this with the assertion’s aud claim above; they are different values.
Leave audience pointed at the UX Toolkit API. The audience form parameter does not change, — it stays the UX Toolkit API host for your environment, but the trailing slash is removed from the end. The token is minted by the dedicated host but intended for the UX Toolkit API. Don’t confuse this with the assertion’s aud claim above; they are different values.
- Forward the DPoP proof unchanged. Your Customer Auth API service still receives the SDK’s DPoP header and forwards it on the upstream token request — you don’t generate or modify it. Its htu must match the dedicated host.
Step 2 - Start using V2 of the UX Toolkit SDK
Upgrade to Version 2 by changing the major version in the script tag that loads the SDK, whereprgmshrtcde is your program short code:
https://web.ux-toolkit.marqeta.com/prgmshrtcde/releases/2/index.js
Version 2 mints from the dedicated host by default and automatically binds the DPoP proof’s htu to the dedicated token endpoint. Changing to the v2 url is the entire change on the SDK side, your app keeps calling the SDK exactly as it does today.
Verify it worked
- Keep both paths behind a switch — have your Customer Auth API service select the host by config or a request flag, so you can flip back instantly if needed.
- Verify in sandbox: point your Customer Auth API service at your new sandbox client ID, upgrade the SDK, mint a token, and confirm the SDK renders live data. Exercise both cardholder and administrative scopes if you use them.
- Promote to production with your new production client ID. You’re successful when SDK successfully mints a token from the dedicated host and renders live data for both cardholder and administrative scopes (if used), with no 401 errors on token refresh.
- Once traffic is fully on the dedicated flow, ask Marqeta to decommission your previous credential.
Token exchange reference
Endpoints by environment
Mint at the dedicated host; keep audience set to the UX Toolkit API host for the same environment.Sandbox
- Mint at: https://secure-sandbox.marqeta.com/oauth/token
- Audience: https://ux-toolkit-api-sandbox.marqeta.com
Production
- Mint at: https://secure.marqeta.com/oauth/token
- Audience: https://ux-toolkit-api.marqeta.com
Common issues
- 401 invalid_client with a bare host in the assertion aud
- The assertion aud must be the full token-endpoint URL (…/oauth/token), not just https://secure.marqeta.com. Watch for URL-normalizers that quietly strip the path.
- 401 invalid_client after previously working
- The assertion lifetime is capped at 5 minutes. The dedicated host rejects any client_assertion whose exp exceeds iat + 300 seconds. Mint the assertion fresh per request rather than reusing a longer-lived one.
- DPoP proof rejected
- The proof’s htu must match the endpoint actually hit. If htu still points at the UX Toolkit API host while the request goes to the dedicated host, the proof is rejected. Upgrading to SDK v2 keeps htu and the request target in sync so this works.
Related articles
- [UX Toolkit SDK v2 upgrade notes]
- [DPoP proof-of-possession reference]