Seismic uses an OAuth 2.0 two-step authorization code grant. You first exchange yourDocumentation Index
Fetch the complete documentation index at: https://docs.seismic-cards.systems/llms.txt
Use this file to discover all available pages before exploring further.
clientId for a short-lived authorization code, then exchange that code along with your clientSecret for an access token valid for 24 hours. Every subsequent API call includes that token in the x-access-token header.
Get your credentials
During onboarding, Seismic provisions a credential bundle for your program:
| Field | Visibility | Description |
|---|---|---|
clientId | Public | Identifies your program. Sent as a query parameter to /v1/oauth/authorize. |
clientSecret | Server-side only | Signs OAuth token requests. Treat like a password. Never embed in mobile apps or websites. |
parentAccountId | Server-side | UUID of your top-level partner account. Required when creating user sub-accounts. |
merchantId | Server-side | UUID of your master merchant account. Used to fund user budgets via inter-account transfers. |
defaultBinId | Server-side | UUID of the BIN your program issues from. You may have more than one — see GET /v1/card/bins. |
webhookSecret | Server-side | Used to verify HMAC-SHA256 signatures on incoming webhooks. |
Get an authorization code
Send a Response (200):The
GET request to /v1/oauth/authorize with your clientId as a query parameter. This returns a single-use authorization code that expires in 10 minutes.data.code field is the authorization ticket you’ll use in the next step. The outer code field is the response status ("000000" means success).The authorization code is single-use and expires in 10 minutes. If you don’t exchange it in time, run this step again to get a fresh code.
Exchange the code for an access token
Post your Response (200):
clientId, clientSecret, and the authorization code you just received to /v1/oauth/access-token. This returns an access token valid for 24 hours and a refresh token valid for 30 days.| Field | Type | Description |
|---|---|---|
accessToken | string | Pass on every subsequent request as x-access-token: <accessToken>. |
refreshToken | string | Long-lived (30 days). Reserved for a future refresh endpoint — for now, re-run steps 2 and 3 to get a new token. |
expiresIn | int | Seconds until the access token expires. Default is 86400 (24 hours). |
timestamp | int | Server timestamp in seconds. |
Make your first authenticated call
With an Response (200):
If you received a
accessToken in hand, list the BINs your program is authorized to issue from. Every program has at least one. The BIN’s id is what you’ll pass as binId in cardholder and card creation requests.| Field | Type | Description |
|---|---|---|
id | string | The BIN UUID — pass as binId in card and cardholder creation requests. |
bin | string | First 6 digits of the card number. |
type | int | 0 = Budget BIN (use these for the standard issuance flow). 1 = Prepaid BIN. |
currencies | string[] | Supported currencies. Currently ["USD"]. |
network | string | VISA or MASTERCARD. |
supportPhysicalCard | bool | Whether physical cards are supported on this BIN. |
200 with "code": "000000", you’re authenticated and ready to issue cards. Continue to Issuing a Card.Required headers
Include these headers on every API call:| Header | When required | Value |
|---|---|---|
x-access-token | All authenticated calls | The access token from step 3. |
Content-Type | All requests with a body | application/json |
Idempotency-Key | Mutating endpoints: POST /v1/cardholders, POST /v1/budget-card, POST /v1/budgets, POST /v1/budgets/{id}/transfer-in, POST /v1/budgets/{id}/transfer-out, POST /v1/business/transfer/external | A UUID v4 you generate per logical operation. Re-using the same key with the same body returns the same response — safe to retry on network errors. |
Node.js / TypeScript reference implementation
ThisSeismicAuth class handles token caching and automatic re-authentication. Use it as a starting point for your own server-side integration.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
40001 Invalid parameter on /v1/oauth/authorize | Missing or malformed clientId query parameter | Confirm the credential string and that you’re hitting the correct environment URL. |
40399 permission denied on any endpoint | Access token expired, revoked, or used against the wrong environment | Re-run the full OAuth flow against the correct base URL. |
Response has "code": "000000" but accessToken is empty | Authorization code was already used or expired (> 10 minutes) | Step 2 returns a single-use code. Run it again to get a fresh one. |
All calls return 40399 after a long idle period | Token aged out after 24 hours | Ensure your token cache checks expiresIn. The reference implementation above handles this correctly. |