> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Payment Method

> Create a new payment method.

**API scope required**: `payment-methods.create`

<Warning>
  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.
</Warning>

<Note>
  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.
</Note>


## OpenAPI

````yaml post /unstable/payment-methods
openapi: 3.0.3
info:
  title: Crossmint Payment Methods API
  version: unstable
  description: >-
    Manage payment methods for Crossmint users. Use these endpoints to create,
    retrieve, update, delete, and list saved payment instruments.


    ## Base URLs


    | Operation | Base URL |

    |---|---|

    | Create (POST) | `https://vault.crossmint.com/api` |

    | All other operations | `https://www.crossmint.com/api` |


    The create endpoint routes through a PCI-compliant proxy that tokenizes
    sensitive payment data before it reaches Crossmint servers.


    ## Authentication


    All requests require a server-side API key in the `X-API-KEY` header.
servers:
  - url: https://www.crossmint.com/api
    description: Production
  - url: https://staging.crossmint.com/api
    description: Staging
security:
  - ApiKeyAuth: []
tags:
  - name: Payment Methods
    description: Create, retrieve, update, delete, and list payment methods.
paths:
  /unstable/payment-methods:
    post:
      tags:
        - Payment Methods
      summary: Create a payment method
      description: >-
        Saves a payment method for a user so it can be reused across Checkout,
        Onramp, and Offramp orders. Card data must be submitted through
        `vault.crossmint.com`, which tokenizes sensitive fields (PAN, CVC)
        before forwarding to Crossmint servers. Bank account numbers and IBANs
        are also tokenized. Duplicate detection prevents saving the same card or
        account twice for the same user.
      operationId: createPaymentMethod
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePaymentMethodRequest'
            examples:
              Card:
                summary: Card
                value:
                  type: card
                  userLocator: email:alice@example.com
                  card:
                    number: '4111111111111111'
                    expirationMonth: 12
                    expirationYear: 2028
                    cvc: '123'
                    billing:
                      name: Alice Smith
                      phone: '+12125551234'
                      address:
                        line1: 123 Main St
                        city: Springfield
                        stateOrRegion: IL
                        postalCode: '62701'
                        country: US
              SEPA:
                summary: SEPA
                value:
                  type: bank-account-sepa-iban
                  userLocator: email:hans.mueller@example.com
                  bankAccount:
                    iban: DE89370400440532013000
                    bic: COBADEFFXXX
                    billing:
                      name: Hans Müller
                    currency: eur
                    country: DE
                    entityType: individual
              BankAccountUs:
                summary: US Bank Account
                value:
                  type: bank-account-us
                  userLocator: email:alice@example.com
                  bankAccount:
                    accountNumber: '5071056259'
                    routingNumber: '091300010'
                    accountType: checking
                    currency: usd
                    country: US
                    entityType: individual
                    bankName: Chime
                    billing:
                      name: Alice Smith
                      phone: '+12125551234'
                      address:
                        line1: 123 Main St
                        city: New York
                        postalCode: '10001'
                        country: US
                        stateOrRegion: NY
                    bankAddress:
                      line1: 123 Main St
                      city: New York
                      stateOrRegion: NY
                      postalCode: '10001'
                      country: US
              BankAccountMx:
                summary: MX Bank Account
                value:
                  type: bank-account-mx-clabe
                  userLocator: email:javier.toledo@example.com
                  bankAccount:
                    accountNumber: '032180000118359719'
                    currency: mxn
                    country: MX
                    entityType: individual
                    billing:
                      name: Javier Toledo
                      phone: '+525512345678'
                      address:
                        line1: Av. Reforma 1
                        city: Mexico City
                        postalCode: '06600'
                        country: MX
                        stateOrRegion: CDMX
              BankAccountCo:
                summary: CO Bank Account
                value:
                  type: bank-account-co
                  userLocator: email:carlos.gomez@example.com
                  bankAccount:
                    accountNumber: '1234567890'
                    bankCode: '001'
                    accountType: savings
                    documentType: CC
                    documentNumber: '1234567890'
                    billing:
                      name: Carlos Gómez
                      phone: '+573001234567'
                      address:
                        line1: Carrera 7
                        city: Bogotá
                        stateOrRegion: DC
                        postalCode: '110010'
                        country: CO
                    currency: cop
                    country: CO
                    entityType: individual
      responses:
        '201':
          description: >-
            Payment method created successfully. Returns the full PaymentMethod
            object including the derived `displayName` and the type-specific
            sub-object (`card` or `bankAccount`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
              examples:
                Card:
                  summary: Card
                  value:
                    paymentMethodId: d4e5f6a7-b8c9-0123-def4-567890abcdef
                    default: true
                    displayName: Visa ••1111
                    type: card
                    card:
                      brand: visa
                      last4: '1111'
                      expiration:
                        month: '12'
                        year: '2028'
                      billing:
                        name: Alice Smith
                        phone: '+12125551234'
                        address:
                          line1: 123 Main St
                          city: Springfield
                          stateOrRegion: IL
                          postalCode: '62701'
                          country: US
                      fundingType: debit
                      bin: '411111'
                      country: US
                SEPA:
                  summary: SEPA
                  value:
                    paymentMethodId: 3323460b-d9d2-4ec6-b380-8a3e01e3f226
                    default: false
                    displayName: SEPA Account ••6789
                    type: bank-account-sepa-iban
                    bankAccount:
                      billing:
                        name: Hans Müller
                        phone: '+4915112345678'
                        address:
                          line1: Unter den Linden 1
                          city: Berlin
                          stateOrRegion: BE
                          postalCode: '10117'
                          country: DE
                      bankName: null
                      accountSuffix: '6789'
                      currency: eur
                      country: DE
                      entityType: individual
                      bic: COBADEFFXXX
                BankAccountUs:
                  summary: US Bank Account
                  value:
                    paymentMethodId: dd8a59c6-aac0-47c2-9c21-686caf7f0359
                    default: false
                    displayName: Chime ••6259
                    type: bank-account-us
                    bankAccount:
                      billing:
                        name: Alice Smith
                        phone: '+12125551234'
                        address:
                          line1: 123 Main St
                          city: New York
                          stateOrRegion: NY
                          postalCode: '10001'
                          country: US
                      bankName: Chime
                      accountSuffix: '6259'
                      currency: usd
                      country: US
                      entityType: individual
                      bankAddress:
                        line1: 123 Main St
                        city: New York
                        stateOrRegion: NY
                        postalCode: '10001'
                        country: US
                      routingNumber: '091300010'
                      accountType: checking
                BankAccountMx:
                  summary: MX Bank Account
                  value:
                    paymentMethodId: 27bacbe1-d0ff-4bc3-b37a-ca91cc64fa39
                    default: false
                    displayName: MX Bank Account ••9719
                    type: bank-account-mx-clabe
                    bankAccount:
                      billing:
                        name: Javier Toledo
                        phone: '+525512345678'
                        address:
                          line1: Av. Reforma 1
                          city: Mexico City
                          stateOrRegion: CDMX
                          postalCode: '06600'
                          country: MX
                      bankName: null
                      accountSuffix: '9719'
                      currency: mxn
                      country: MX
                      entityType: individual
                      bankCode: '138'
                BankAccountCo:
                  summary: CO Bank Account
                  value:
                    paymentMethodId: 1cad2281-bd3d-4219-8787-7dfea94c60b1
                    default: false
                    displayName: CO Bank Account ••7890
                    type: bank-account-co
                    bankAccount:
                      billing:
                        name: Carlos Gómez
                        phone: '+573001234567'
                        address:
                          line1: Carrera 7
                          city: Bogotá
                          stateOrRegion: DC
                          postalCode: '110010'
                          country: CO
                      bankName: null
                      accountSuffix: '7890'
                      currency: cop
                      country: CO
                      entityType: individual
                      bankCode: '001'
                      accountType: savings
        '400':
          description: Request validation failed or duplicate payment method.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400ResponseCreate'
              examples:
                duplicate:
                  description: Duplicate payment method
                  value:
                    error: true
                    message: >-
                      Payment method already exists for this user with the same
                      details
                sepa_business:
                  description: SEPA business not supported
                  value:
                    error: true
                    message: SEPA business accounts are not supported
                sensitive_data:
                  description: >-
                    Sensitive data sent directly to www.crossmint.com instead of
                    vault.crossmint.com
                  value:
                    error: true
                    message: >-
                      Payment method requests must be submitted through
                      vault.crossmint.com. Sensitive data cannot be sent
                      directly to api.crossmint.com.
                    code: PAYMENT_METHOD_SENSITIVE_DATA_NOT_ALLOWED
                missing_locator:
                  description: Missing userLocator when using API key auth
                  value:
                    error: true
                    message: userLocator is required when not using JWT authentication
                    code: PAYMENT_METHOD_INVALID_USER_LOCATOR
                proxy_fields_missing:
                  description: Card creation via API key missing proxy-supplied fields
                  value:
                    error: true
                    message: >-
                      Card creation via API key requires proxy-supplied
                      fingerprint, brand, last4, expMonth, expYear. Submit
                      through vault.crossmint.com.
                    code: PAYMENT_METHOD_PROXY_FIELDS_MISSING
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/401Response'
        '403':
          description: Authentication source not allowed or required add-on not enabled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/403Response'
              examples:
                auth_source:
                  description: Authentication source not allowed
                  value:
                    error: true
                    message: >-
                      Payment methods are not allowed with this authentication
                      source
                card_auth:
                  description: Card creation requires JWT or vault proxy
                  value:
                    error: true
                    message: >-
                      Card payment methods require user authentication (JWT) or
                      vault.crossmint.com proxy submission.
        '422':
          description: Request body failed schema validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/422Response'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/429Response'
      servers:
        - url: https://vault.crossmint.com/api
          description: Production (PCI vault)
        - url: https://vault.staging.crossmint.com/api
          description: Staging (PCI vault)
components:
  schemas:
    CreatePaymentMethodRequest:
      type: object
      description: Create request. Provide the sub-object that matches the chosen `type`.
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - card
            - bank-account-us
            - bank-account-mx-clabe
            - bank-account-co
            - bank-account-sepa-iban
          description: >-
            Payment method type. Determines which sub-object (`card` or
            `bankAccount`) must be provided.
        userLocator:
          type: string
          description: >-
            Identifies the target user. Format: `<type>:<value>` (e.g.,
            `email:alice@example.com`, `userId:abc123`). Required when
            authenticating with a server API key; ignored with JWT (the JWT
            subject is used instead).
        card:
          type: object
          description: >-
            Card details. Required when `type` is `card`. All card data is
            tokenized by the PCI vault before it reaches Crossmint servers.
          properties:
            number:
              type: string
              description: >-
                Card number (PAN), as a string without separators. 13-19 digits.
                Tokenized by the vault — never stored in plaintext.
            expirationMonth:
              type: integer
              description: Expiration month (1-12).
            expirationYear:
              type: integer
              description: >-
                Four-digit expiration year (e.g., 2028). Two-digit years are
                rejected.
            cvc:
              type: string
              description: >-
                Card verification code (3 digits, or 4 for Amex). Tokenized by
                the vault; used for initial verification only and not stored.
            billing:
              type: object
              description: Cardholder billing details. `name` is always required.
              properties:
                name:
                  type: string
                  description: Cardholder full name as it appears on the card.
                phone:
                  type: string
                  description: Phone number in E.164 format (e.g., `+12125551234`).
                address:
                  type: object
                  description: >-
                    Billing address. When provided, all fields except `line2`
                    are required.
                  properties:
                    line1:
                      type: string
                      description: Primary address line (max 200 characters).
                    line2:
                      type: string
                      description: >-
                        Secondary address line — apartment, suite, unit, etc.
                        (max 60 characters).
                    city:
                      type: string
                      description: City (max 50 characters).
                    stateOrRegion:
                      type: string
                      description: State, province, or region (max 50 characters).
                    postalCode:
                      type: string
                      description: Postal or ZIP code (max 20 characters).
                    country:
                      type: string
                      description: >-
                        Two-letter ISO 3166-1 alpha-2 country code (e.g., `US`,
                        `DE`).
                  required:
                    - line1
                    - city
                    - postalCode
                    - stateOrRegion
                    - country
              required:
                - name
          required:
            - number
            - expirationMonth
            - expirationYear
            - cvc
            - billing
        bankAccount:
          type: object
          description: >-
            Bank account details. Required when `type` is a bank type. The exact
            fields depend on the country-specific type. Account numbers and
            IBANs are tokenized by the vault.
          properties:
            accountNumber:
              type: string
              description: >-
                Bank account number. For US: 4-17 digits. For MX: 18-digit
                CLABE. For CO: account number. Tokenized by the vault — never
                stored in plaintext.
            routingNumber:
              type: string
              description: >-
                Nine-digit ABA routing transit number with checksum validation.
                US bank accounts only.
            iban:
              type: string
              description: >-
                IBAN (ISO 13616, 15-34 characters). Tokenized by the vault —
                never stored in plaintext. SEPA only.
            bic:
              type: string
              description: >-
                BIC/SWIFT code (ISO 9362, 8 or 11 uppercase alphanumeric
                characters). Optional — under EPC IBAN-only rules, the BIC can
                be derived from the IBAN. SEPA only.
            bankName:
              type: string
              description: >-
                Name of the bank (e.g., "Wells Fargo", "Deutsche Bank").
                Required for US; optional for SEPA.
            bankAddress:
              type: object
              description: Bank branch mailing address. US bank accounts only.
            bankCode:
              type: string
              description: >-
                Bank code. For MX: 3-digit code from the CLABE. For CO: code
                assigned by Banco de la República.
            accountType:
              type: string
              enum:
                - checking
                - savings
              description: >-
                Account type: `checking` or `savings`. Required for US and CO
                bank accounts.
            documentType:
              type: string
              description: >-
                Colombian document type: `CC` (Cédula), `NIT` (Tax ID), `CE`
                (Cédula de Extranjería), `PASS` (Passport), or `PEP` (Special
                Permit). CO only.
            documentNumber:
              type: string
              description: >-
                Document number matching `documentType`. Tokenized by the vault.
                CO only.
            billing:
              type: object
              description: Account holder billing details. `name` is always required.
              properties:
                name:
                  type: string
                  description: Account holder full legal name.
                phone:
                  type: string
                  description: Phone number in E.164 format (e.g., `+4915112345678`).
                address:
                  type: object
                  description: >-
                    Billing address. When provided, `line1`, `city`,
                    `postalCode`, and `country` are required.
                  properties:
                    line1:
                      type: string
                      description: Primary address line (max 200 characters).
                    line2:
                      type: string
                      description: >-
                        Secondary address line — apartment, suite, unit, etc.
                        (max 60 characters).
                    city:
                      type: string
                      description: City (max 50 characters).
                    stateOrRegion:
                      type: string
                      description: >-
                        State, province, or region (max 50 characters). Required
                        for all types except SEPA.
                    postalCode:
                      type: string
                      description: Postal or ZIP code (max 20 characters).
                    country:
                      type: string
                      description: >-
                        Two-letter ISO 3166-1 alpha-2 country code (e.g., `US`,
                        `DE`).
                  required:
                    - line1
                    - city
                    - postalCode
                    - country
              required:
                - name
            currency:
              type: string
              description: >-
                ISO 4217 currency code in lowercase. Must match the type: `usd`
                for US, `mxn` for MX, `cop` for CO, `eur` for SEPA.
            country:
              type: string
              description: >-
                ISO 3166-1 alpha-2 country code. For SEPA, must be one of the 37
                EPC member states or Gibraltar.
            entityType:
              type: string
              enum:
                - individual
                - business
              description: >-
                Account holder type: `individual` or `business`. SEPA does not
                currently support `business`.
          required:
            - billing
            - currency
            - country
    PaymentMethod:
      description: >-
        A saved payment method. Sensitive fields (full PAN, CVC, full account
        numbers) are never included in responses.
      oneOf:
        - type: object
          description: >-
            A saved payment method. Sensitive fields (full PAN, CVC, full
            account numbers) are never included in responses.
          properties:
            paymentMethodId:
              type: string
              format: uuid
              description: Unique identifier (UUID v4), assigned by the server on creation.
            default:
              type: boolean
              description: >-
                Whether this is the user's default payment method. Only one per
                user can be the default; setting a new default automatically
                unsets the previous one.
            displayName:
              type: string
              description: >-
                Human-readable label derived by the server (e.g., "Visa ••1111",
                "SEPA Account ••6789"). Not settable by the client.
            type:
              type: string
              enum:
                - card
              description: >-
                Payment method type. Determines which sub-object (`card` or
                `bankAccount`) is present.
            card:
              type: object
              description: Card details. Present when `type` is `card`.
              properties:
                brand:
                  type: string
                  description: Card network brand, detected from the card number.
                  enum:
                    - visa
                    - mastercard
                    - amex
                    - discover
                    - jcb
                    - unionpay
                    - diners-club
                last4:
                  type: string
                  description: Last four digits of the card number.
                expiration:
                  type: object
                  description: Card expiration date.
                  properties:
                    month:
                      type: string
                      description: Two-digit month, zero-padded (`01`-`12`).
                    year:
                      type: string
                      description: Four-digit year.
                  required:
                    - month
                    - year
                billing:
                  type: object
                  description: Cardholder billing details as provided on creation.
                  properties:
                    name:
                      type: string
                      description: Cardholder name.
                    phone:
                      type: string
                      description: Phone number.
                    address:
                      type: object
                      description: Billing address.
                  required:
                    - name
                fundingType:
                  type: string
                  description: >-
                    Card funding type, detected from the BIN. Present when the
                    issuer provides this data.
                  enum:
                    - credit
                    - debit
                    - prepaid
                    - unknown
                bin:
                  type: string
                  description: >-
                    Bank Identification Number (first 6-8 digits). Present when
                    available from the card network.
                country:
                  type: string
                  description: >-
                    ISO 3166-1 alpha-2 code of the card-issuing country. Present
                    when available from the card network.
              required:
                - brand
                - last4
                - expiration
                - billing
          required:
            - paymentMethodId
            - default
            - type
            - displayName
            - card
        - type: object
          description: >-
            A saved payment method. Sensitive fields (full PAN, CVC, full
            account numbers) are never included in responses.
          properties:
            paymentMethodId:
              type: string
              format: uuid
              description: Unique identifier (UUID v4), assigned by the server on creation.
            default:
              type: boolean
              description: >-
                Whether this is the user's default payment method. Only one per
                user can be the default; setting a new default automatically
                unsets the previous one.
            displayName:
              type: string
              description: >-
                Human-readable label derived by the server (e.g., "Visa ••1111",
                "SEPA Account ••6789"). Not settable by the client.
            type:
              type: string
              enum:
                - bank-account-us
                - bank-account-mx-clabe
                - bank-account-co
                - bank-account-sepa-iban
              description: >-
                Payment method type. Determines which sub-object (`card` or
                `bankAccount`) is present.
            bankAccount:
              type: object
              description: >-
                Bank account details. Present when `type` is a bank type. Full
                account numbers and IBANs are never included.
              properties:
                billing:
                  type: object
                  description: Account holder billing details as provided on creation.
                bankName:
                  type: string
                  description: >-
                    Name of the bank, or `null` if the bank could not be
                    identified.
                  nullable: true
                accountSuffix:
                  type: string
                  description: Last four digits of the account number, CLABE, or IBAN.
                currency:
                  type: string
                  description: ISO 4217 currency code in lowercase (e.g., `usd`, `eur`).
                country:
                  type: string
                  description: ISO 3166-1 alpha-2 country code.
                entityType:
                  type: string
                  description: Account holder type. Present when provided on creation.
                  enum:
                    - individual
                    - business
                routingNumber:
                  type: string
                  description: ABA routing number. US only.
                accountType:
                  type: string
                  description: Account type. US and CO only.
                  enum:
                    - checking
                    - savings
                bankAddress:
                  type: object
                  description: Bank mailing address. US only.
                bankCode:
                  type: string
                  description: Bank code. MX and CO only.
                bic:
                  type: string
                  description: >-
                    BIC/SWIFT code. SEPA only; present when provided on
                    creation.
                taxId:
                  type: string
                  description: >-
                    Mexican tax identifier (RFC). MX only; present when
                    provided.
                businessDescription:
                  type: string
                  description: Business description. MX only; present when provided.
              required:
                - billing
                - bankName
                - accountSuffix
                - currency
                - country
            availableTiers:
              type: array
              description: >-
                Offramp speed tiers serviceable for this account, each with
                backing rail(s). Empty if none.
              items:
                type: object
                properties:
                  tier:
                    type: string
                    enum:
                      - instant
                      - same_day
                      - multi_day
                  rails:
                    type: array
                    items:
                      type: string
                      enum:
                        - wire
                        - ach_credit
                        - same_day_ach_credit
                        - rtp_credit
                        - sepa
                        - sepa_instant
                        - faster_payments
                        - swift
                        - spei
                        - pse
                        - fednow
                        - chaps
                required:
                  - tier
                  - rails
            lastPayoutAt:
              type: string
              format: date-time
              description: >-
                Read-only. ISO 8601 timestamp of the most recent successful
                offramp payout funded by this bank account. Absent if none.
          required:
            - paymentMethodId
            - default
            - type
            - displayName
            - bankAccount
            - availableTiers
    400ResponseCreate:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          description: Human-readable error message describing what went wrong
        code:
          type: string
          description: Machine-readable error code for programmatic handling
          enum:
            - PAYMENT_METHOD_SENSITIVE_DATA_NOT_ALLOWED
            - PAYMENT_METHOD_INVALID_USER_LOCATOR
            - PAYMENT_METHOD_PROXY_FIELDS_MISSING
      description: Bad request on payment method creation.
    401Response:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          example: Missing or invalid API key.
      description: Missing or invalid API key / JWT.
    403Response:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          example: Payment methods are not allowed with this authentication source
      description: API key lacks the required scope for this operation.
    422Response:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          example: Request body failed schema validation
      description: >-
        Request body validation failed (e.g., missing required fields, invalid
        field format).
    429Response:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          example: Rate limit exceeded
      description: >-
        Rate limit exceeded. Retry after the interval indicated in the
        Retry-After header.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: Server-side API key from the Crossmint dashboard.

````