API reference
Base https://api.3dsgate.com. JSON in, JSON out. All timestamps are RFC 3339 in UTC.
Authentication
Authorization: Bearer sk_live_…. Keys are environment-scoped: a test key only reaches /v2/authentications in sandbox mode. Requests without a key return 401 with code auth_missing.
Optional Idempotency-Key on POST. Replays within 24 h return the original response with Idempotent-Replay: true; a different body on the same key returns 409.
POST /v2/authentications
| amount | integer, minor units, required |
|---|---|
| currency | ISO 4217, required |
| messageVersion | 2.1.0 or 2.2.0, required |
| card.brand | visa, mastercard, amex, jcb, discover, unionpay |
| card.bin | first six digits |
| card.last4 | last four digits |
| card.holderName | as printed, optional |
| buyer.email | required when the issuer may choose email |
| buyer.phone | E.164, required when the issuer may choose SMS |
| buyer.locale | BCP 47, drives challenge language |
| notificationUrl | HTTPS, required |
| returnUrl | HTTPS, required |
| metadata | object, up to 20 keys, echoed back |
201 returns authenticationId, acsTransID, dsTransID, challengeUrl, expiresAt.
GET /v2/authentications/{id}
Current state. Fields: status (created, method, challenged, authenticated, failed, unavailable, expired), transStatus, eci, authenticationValue, attempts, mode.
GET /v2/authentications/{id}/events
Ordered audit timeline. Each entry: at, event, detail. Retained 24 months.
POST /v2/authentications/{id}/resend
Re-issues the challenge in the same mode. Permitted up to three times per session, rate limited to one per 30 s.
Notifications
Posted to notificationUrl with X-3DS-Signature: lowercase hex HMAC-SHA256 of the raw body using the endpoint secret. Also X-3DS-Timestamp, which must be within 300 s.
{
"event": "authentication.finished",
"authenticationId": "ath_01J9Z4K2V6",
"transStatus": "Y",
"eci": "05",
"authenticationValue": "AAABBEg0VhI0VniQEjRWAAAAAAA=",
"messageVersion": "2.2.0",
"at": "2026-10-28T15:04:11Z"
}
transStatus — Y authenticated, N not authenticated, U unavailable, A attempted.
Errors
Errors return the HTTP status plus a stable code, a human message and a requestId. See error codes.
| 400 | invalid_request, unsupported_version |
|---|---|
| 401 | auth_missing, auth_invalid |
| 403 | origin_not_allowed, url_not_registered |
| 404 | not_found |
| 409 | idempotency_conflict, session_finished |
| 422 | bin_unmapped, phone_invalid, amount_out_of_range |
| 429 | rate_limited — honour Retry-After |
Rate limits
600 session creations per minute per key, 60 state reads per second. Both return 429 with Retry-After and X-RateLimit-Reset.