Skip to main content
POST
Create Payment Method
This endpoint is gated behind Payment Card Industry Data Security Standard (PCI DSS) compliance. Because it accepts raw card numbers, Card Verification Codes (CVCs), and bank account details, you may only use it if your organization is PCI DSS compliant and has been explicitly enabled by Crossmint. You must provide evidence of your compliance (e.g. your Attestation of Compliance) and reach out to Crossmint to have it turned on — it is disabled by default.If you are not PCI compliant, do not use this endpoint. Instead, use the client-side Save a Card flow, which renders Crossmint’s CrossmintPaymentMethodManagement component. Card data is collected directly by Crossmint in the browser and never touches your servers, so you do not need to be PCI compliant to use it.
This endpoint requires a JWT from an external auth provider (Auth0, Firebase, Stytch, etc.) or a custom JWT backed by a JWKS endpoint. Crossmint Auth is not supported.
This endpoint accepts raw card data and bank account details. Requests must be sent to the vault host (vault.staging.crossmint.com or vault.crossmint.com), which tokenizes sensitive fields before forwarding to the API. Raw card numbers, CVCs, and bank account numbers never reach api.crossmint.com directly.

Headers

X-API-KEY
string
required

API key required for authentication

Body

application/json
bankAccount
object
required
type
enum<string>
required

Account identifier type: Mexican bank account identified by an 18-digit CLABE. type names the account identifier / capture schema Crossmint collects — never the payment rail; rail selection happens at payment execution time.

Available options:
bank-account-mx-clabe
userLocator
string

Identifies the target user when authenticating with a server API key. Format: <type>:<value> (e.g., email:alice@example.com, userId:abc123, phoneNumber:+12125551234, twitter:alice). Required for API-key authentication; ignored when authenticating with a JWT (the JWT subject is used).

Minimum string length: 1

Response

201 - application/json

The payment method has been successfully created

bankAccount
object
required
createdAt
string<date-time>
required

ISO 8601 timestamp when this payment method was created.

Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
paymentMethodId
string
required
Minimum string length: 1
status
enum<string>
required

Whether this destination can receive a payout right now. 'active' when a provider has confirmed a rail, 'pending' while rail resolution is still running, 'rejected' when it cannot receive funds, 'inactive' when it was deleted or disabled. Branch on this field, never on reason.

Available options:
active,
inactive,
pending,
rejected
type
enum<string>
required
Available options:
bank-account-co
updatedAt
string<date-time>
required

ISO 8601 timestamp when this payment method was last modified.

Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
default
boolean
display
object
lastPayoutAt
string<date-time>

Read-only. ISO 8601 timestamp of the most recent successful offramp payout funded by this bank account. Absent if none.

Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
reason
string

Why the status is not 'active'. Absent when it is, and on a 'pending' status other than a provider outage. Known values today: provider-unavailable, destination-not-found, destination-closed, destination-cannot-receive, no-rail-available, deleted, disabled. New codes can appear at any time, so branch on status and treat an unrecognised reason as the status alone.