openapi: 3.0.3 info: title: Astrada bank-accounts card-verification API version: '2024-02-28' contact: email: developer@astrada.co description: 'Welcome to our API Reference. 👋 ' servers: - url: https://api.astrada.co security: null tags: - name: card-verification description: Card Verification paths: /card-verifications/unlock: post: tags: - card-verification summary: Unlock a card's verification attempt lockout description: 'Clear the cross-network verification **attempt lockout** for a card, identified by its `cardId`. This re-enables verification attempts for the card after it has been throttled by too many recent hard failures — the account-scoped, cross-network throttle that protects the non-HIGHEST tiers (Visa/Stripe, Mastercard/TNS). Idempotent: unlocking a card that has no active lock succeeds and clears nothing. The HIGHEST per-fingerprint lockout is **not** affected by this endpoint. ' security: - main-auth: - subaccounts:write operationId: CardVerificationAttemptLockoutUnlock requestBody: required: true content: application/json: schema: type: object required: - cardId properties: cardId: description: Identifier of the card whose attempt lockout to clear. type: string format: uuid examples: UnlockAttemptLockoutRequestExample: value: cardId: 00cdba2d-01f0-46bb-b34a-c76d9699e991 responses: '200': description: 'The card''s attempt lockout was cleared, or the card had no active lock (idempotent). ' content: application/hal+json: schema: type: object required: - unlocked properties: unlocked: description: Always `true` on success. type: boolean enum: - true vaultCardFingerprint: description: 'The provider-independent vault fingerprint that was cleared. Present only when an active lock existed for the card. ' type: string examples: UnlockAttemptLockoutResponseExample: value: unlocked: true vaultCardFingerprint: 1f1d2c3b-4a5e-6f70-8192-a3b4c5d6e7f8 '400': $ref: '#/components/responses/bad-request' '401': $ref: '#/components/responses/unauthorized' '403': $ref: '#/components/responses/forbidden' '500': $ref: '#/components/responses/server-error' /card-verifications/3ds: get: tags: - card-verification summary: List a card's 3DS verifications description: 'List the 3DS verifications for a card, most recent first. Use the optional `state` filter (e.g. `state=failed`) to retrieve only failed verifications — each failed verification carries a `failureReason` explaining why it failed. This includes cards declined synchronously at creation (the `POST` returned `400`): those attempts are persisted as failed verifications with `currentStepId: null`. ' security: - main-auth: - card-verifications:read operationId: CardVerificationList parameters: - $ref: '#/components/parameters/card-id.required' - in: query name: state required: false description: Optional filter to retrieve only verifications in the given state. schema: type: string enum: - completed - failed - in-progress responses: '200': description: Successful operation content: application/hal+json: schema: type: object required: - _links - _embedded - totalItems properties: _links: type: object required: - self properties: self: $ref: '#/components/schemas/link' _embedded: type: object required: - cardVerifications properties: cardVerifications: type: array items: $ref: '#/components/schemas/card-verification' totalItems: type: integer examples: Example list filtered by state=failed: value: _links: self: href: /card-verifications/3ds?cardId=8309b5f8-d5d8-49bb-9001-38bf1bb0f1e4&state=failed _embedded: cardVerifications: - _links: self: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b steps: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b/steps id: 9fab1bea-bc1e-4757-bd47-479422e5983b subaccountId: f297d659-c13d-4219-aeaa-e10a845140a5 cardId: 8309b5f8-d5d8-49bb-9001-38bf1bb0f1e4 type: 3DS state: failed authenticationFlow: frictionless failureReason: category: authentication_declined description: The card issuer declined the 3-D Secure authentication. retryable: true code: '05' providerMessage: The card issuer declined this authentication attempt. createdAt: '2024-01-04T18:53:32.000Z' updatedAt: '2024-01-04T18:55:12.000Z' totalItems: 1 '401': $ref: '#/components/responses/unauthorized' '403': $ref: '#/components/responses/forbidden' '500': $ref: '#/components/responses/server-error' /card-verifications/3ds/{verificationId}: parameters: - $ref: '#/components/parameters/verification-id' get: tags: - card-verification summary: Retrieve 3DS verification description: Returns the current status and detailed information of a specific 3DS verification by its identifier. security: - main-auth: - card-verifications:read operationId: GetCardVerification responses: '200': description: Successful operation content: application/hal+json: schema: $ref: '#/components/schemas/card-verification' examples: Example Get Card Verification Response: $ref: '#/components/examples/card-verification' Example Failed Verification with failureReason: $ref: '#/components/examples/card-verification-failed' '400': $ref: '#/components/responses/bad-request' '401': $ref: '#/components/responses/unauthorized' '403': $ref: '#/components/responses/forbidden' '404': $ref: '#/components/responses/not-found' '500': $ref: '#/components/responses/server-error' components: responses: bad-request: description: The server cannot or will not process the request due to something that is perceived to be a client error content: application/problem+json: schema: type: object properties: detail: type: string title: type: string enum: - Bad Request errors: type: array items: type: object properties: title: type: string detail: type: string required: - title - detail required: - detail - title examples: Example Generic Bad Request Payload Response: value: title: Bad Request detail: Request object failed validation. Example Generic Bad Request Parameters Response: value: title: Bad Request detail: Request parameters are invalid. not-found: description: The requested resource was not found on the server content: application/problem+json: schema: type: object properties: type: type: string instance: type: string detail: type: string title: type: string enum: - Not Found required: - detail - title example: title: Not Found detail: The requested resource was not found on the server. unauthorized: description: Authentication credentials were either missing or incorrect content: application/problem+json: schema: type: object properties: detail: type: string title: type: string enum: - Unauthorized required: - detail - title example: title: Unauthorized detail: Authentication credentials were either missing or incorrect. forbidden: description: Authentication credentials used do not have have permissions to perform the request content: application/problem+json: schema: type: object properties: detail: type: string title: type: string enum: - Forbidden required: - detail - title example: title: Forbidden detail: You do not have permission to access the requested resource. server-error: description: The server encountered an unexpected condition that prevented it from fulfilling the request content: application/problem+json: schema: type: object properties: detail: type: string title: type: string enum: - Internal Server Error required: - detail - title example: title: Internal Server Error detail: The server encountered an unexpected condition that prevented it from fulfilling the request. schemas: card-verification: type: object properties: _links: type: object properties: self: $ref: '#/components/schemas/link' description: The link to this verification resource. steps: $ref: '#/components/schemas/link' description: The link to this verification's steps (`/card-verifications/3ds/{verificationId}/steps`). currentStep: $ref: '#/components/schemas/link' description: 'The link to the step the client should execute next. Absent once the verification reaches a terminal `state` (`completed` or `failed`). ' required: - self - steps id: description: The unique identifier of the Verification entity. type: string format: uuid subaccountId: description: The unique identifier of the subaccount related to this entity. type: string format: uuid cardId: description: The unique identifier of the card related to this entity. type: string format: uuid type: description: Verification Step Type type: string enum: - 3DS currentStepId: description: 'The identifier of the next step the client should execute. `null` when the verification has no follow-up step — typically because the issuer supports frictionless authentication, or because the card did not require interactive 3DS. When `null`, `state` will be `completed` on the creation response and clients should not call any `/steps/...` endpoint. On retrieved/listed verifications, `currentStepId` is also `null` with `state: failed` when the card was declined synchronously at creation (the creation call returned `400`, and the attempt is persisted as a failed verification with its `failureReason`). For the HIGHEST tier, a frictionless 3DS outcome does NOT complete the verification: it returns `stripe-holds-pending` (the cardholder must initiate two small verification holds via `/steps/place-holds`), which then advances to `stripe-amount-confirm` (the cardholder reads the two amounts back via `/steps/amount-confirm`). ' type: string nullable: true enum: - fingerprint - challenge - stripe-3ds - stripe-holds-pending - stripe-amount-confirm - null state: description: Current Verification state type: string enum: - completed - failed - in-progress clientSecret: description: Stripe SetupIntent or PaymentIntent client secret, used by the client to run `stripe.handleNextAction`. Returned whenever the verification is on the Stripe 3DS step — on the creation response (`POST /card-verifications/3ds`) and on the retrieve response (`GET /card-verifications/3ds/{verificationId}`) while `currentStepId` is `stripe-3ds`. type: string stripePublishableKey: description: Stripe publishable key to initialize Stripe.js on the client. Returned alongside `clientSecret` (creation response and retrieve response while `currentStepId` is `stripe-3ds`). type: string authenticationFlow: description: 'The 3DS authentication flow attested by the issuer, surfaced at the terminal state. `challenge` = the cardholder actively authenticated; `frictionless` = the issuer approved without interaction; `null` = 3DS was not engaged (e.g. a low-risk automatic skip). ' type: string nullable: true enum: - challenge - frictionless - null failureReason: $ref: '#/components/schemas/failure-reason' description: 'Normalized, customer-facing reason the verification failed. Present only when `state` is `failed` — read it to triage the failure (category, retryability, and the issuer''s message). See the `FailureReason` schema. ' createdAt: description: Date and time when this resource was created, in UTC, following ISO 8601 format. type: string format: date-time updatedAt: description: Date and time when this resource was last updated, in UTC, following ISO 8601 format. type: string format: date-time required: - id - subaccountId - cardId - type - state - createdAt - updatedAt - _links failure-reason: type: object description: 'Normalized, customer-facing reason a card verification failed. Present only when the verification `state` is `failed`. `category`, `description` and `retryable` are always present; `issuerMessage` and `acsReferences` appear only when the issuer returned them (typically on a frictionless decline — when the issuer renders its own challenge UI no per-attempt message is available). ' properties: category: description: 'Stable, provider-agnostic failure category an integrator can branch on without enumerating raw issuer codes. ' type: string enum: - authentication_declined - authentication_canceled - cvc_check_failed - card_declined - contact_issuer - card_blocked - too_many_attempts - not_supported - temporary_issue - processing_error description: description: Human-readable explanation of the failure, safe to relay to the cardholder. type: string retryable: description: Whether the cardholder can retry now and plausibly succeed. type: boolean issuerMessage: description: The issuer's own cardholder-facing message, when provided (frictionless declines only). type: string code: description: 'Raw provider reason code (e.g. a 3DS `transStatusReason` or a Stripe `decline_code`), surfaced for support escalation. ' type: string providerMessage: description: 'The payment provider''s cardholder-safe message for the specific failure code (e.g. "Your card does not support this type of purchase."). Finer-grained than the category-level `description`; absent when the provider supplied none. ' type: string adviceCode: description: 'The issuer''s advice code on authorization declines, verbatim from the payment provider. Documented values: `try_again_later`, `do_not_try_again`, `confirm_card_data`; values the provider introduces later pass through unchanged. Absent when the issuer gave no advice (e.g. 3-D Secure authentication failures). ' type: string acsReferences: description: 3DS ACS reference identifiers, when returned by the issuer — useful when escalating to the issuer. type: object properties: acsTransactionId: type: string acsReferenceNumber: type: string dsTransactionId: type: string required: - category - description - retryable link: type: object properties: href: type: string templated: type: boolean type: type: string deprecation: type: string name: type: string profile: type: string title: type: string hreflang: type: string required: - href parameters: card-id.required: in: query name: cardId required: true schema: type: string format: uuid example: 8164683a-8d23-4421-9694-1a81fc9b9c37 verification-id: in: path name: verificationId required: true schema: type: string format: uuid example: 9cac38a2-6584-4c1f-92fd-85223774979b examples: card-verification-failed: description: Example of a failed Card Verification, with a populated failureReason explaining why the 3DS verification failed. value: _links: self: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b steps: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b/steps id: 9fab1bea-bc1e-4757-bd47-479422e5983b subaccountId: f297d659-c13d-4219-aeaa-e10a845140a5 cardId: 8309b5f8-d5d8-49bb-9001-38bf1bb0f1e4 type: 3DS currentStepId: null state: failed authenticationFlow: frictionless failureReason: category: authentication_declined description: The card issuer declined the 3-D Secure authentication. retryable: true issuerMessage: Your bank declined this verification. Please contact your bank or try another card. code: '05' acsReferences: acsTransactionId: 8a880dc0-d2d2-4067-bcb1-b08d1690b26e acsReferenceNumber: ACME-ACS-2024-0042 dsTransactionId: 97267598-fae6-494f-8453-2d3807e0c77f createdAt: '2024-01-04T18:53:32.000Z' updatedAt: '2024-01-04T18:55:12.000Z' card-verification: description: Example of Card Verification resource value: _links: self: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b steps: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b/steps currentStep: href: /card-verifications/3ds/9fab1bea-bc1e-4757-bd47-479422e5983b/steps/fingerprint id: 9fab1bea-bc1e-4757-bd47-479422e5983b subaccountId: f297d659-c13d-4219-aeaa-e10a845140a5 cardId: 8309b5f8-d5d8-49bb-9001-38bf1bb0f1e4 type: 3DS currentStepId: fingerprint state: in-progress createdAt: '2024-01-04T18:53:32.000Z' updatedAt: '2023-01-04T10:55:12.000Z' securitySchemes: main-auth: type: oauth2 flows: implicit: authorizationUrl: https://api.astrada.co/auth/realms/{accountId}/protocol/openid-connect/token refreshUrl: https://api.astrada.co/auth/realms/{accountId}/protocol/openid-connect/token scopes: accounts:write: Accounts write resource accounts:read: Accounts read resource subaccounts:write: Subaccounts write resource subaccounts:read: Subaccounts read resource card-connector-data-links:write: card-connector-data-link resource card-connector-consents:read: Card Consent read resource card-connector-consents:write: Card Consent write resource webhooks:read: Read Webhook resources webhooks:write: Write Webhook resources card-subscriptions:write: Create card subscription card-subscriptions:read: Read card subscription card-verifications:write: Create card verification card-verifications:read: Read Card verification cards:read: Read Card resources cardholder:read: Read Cardholder resources cardholder:write: Write Cardholder resources transactions:read: Read Transaction resources transaction-messages:read: Read Transaction Message resources network-bulk-feeds:read: Read network bulk feed network-bulk-feeds:write: Write network bulk feed network-links:write: Write network link enrollment-methods:write: Write enrollment methods simulation:write: Write sandbox simulations banking:read: Read banking resources banking:write: Write banking resources banking:admin: Admin banking operations appstore:enrollment:write: Enroll cards via the appstore B2C flow appstore:cards:read: View enrolled cards in the appstore appstore:transactions:read: View synced transactions in the appstore appstore:transactions:sync: Trigger transaction sync in the appstore appstore:sessions:read: Read appstore session state appstore:sessions:write: Write or delete appstore session state appstore:tokens:read: Read appstore stored tokens and connections appstore:tokens:write: Write appstore stored tokens and connections externalDocs: description: Find out more about Astrada API. url: https://docs.astrada.co/reference