---
title: "Create a corporate card."
method: POST
path: "/ledger/card-accounts"
tags: ["ledger-card accounts"]
---

# Create a corporate card.

`POST /ledger/card-accounts`

## Request

- Base URL: `https://external.dev.onboardpay.co`
- URL: `https://external.dev.onboardpay.co/ledger/card-accounts`
- Auth: API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/nestechops/apis/onboard-external-api-gateway/docs/ledger/card-accounts/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a card account for the business. KYB/KYC is submitted to the card provider as part of
this call; the card itself is only issued (and the initial funding amount debited) once KYC is
approved - see the returned status. A business may have at most one card account pending KYC at
a time, and is subject to a lifetime limit on the total number of card accounts it may ever
create (see the 409 response).

## Request body

- CreateCardAccountRequest: Request to create a corporate card. KYB is submitted to the card provider as part of this call; fees are computed and applied by the ledger, never by the card provider directly.
  - `accountId` string, uuid, required: The MAIN account to fund the card from.
  - `displayName` string, required: A label for the card.
  - `cardPackageId` string: Card package/provider ID (see GET /card-packages) to create the card against. Defaults to the ledger's configured default card provider (currently `onb-cards`) when omitted.
  - `cardBrand` 'VISA' | 'MASTERCARD' | 'VERVE'
  - `initialFundingAmount` number, required
  - `dailyLimit` number
  - `transactionLimit` number
  - `whitelistedMccs` string[]
  - `blacklistedMccs` string[]
  - `contactlessPaymentEnabled` boolean

## Response `201`

Card account created (typically PENDING_KYC)

- CardAccount
  - `id` string, uuid, required: Unique card account ID.
  - `accountId` string, uuid, required: The MAIN account this card is funded from.
  - `currency` string, required
  - `status` 'PENDING_KYC' | 'PENDING_PROVISIONING' | 'ACTIVE' | 'FROZEN' | 'TERMINATED' | 'KYC_REJECTED' | 'CREATION_FAILED', required: Lifecycle of a card account. PENDING_KYC and PENDING_PROVISIONING are transient - a card only starts moving money once it reaches ACTIVE. KYC_REJECTED and CREATION_FAILED are terminal with no funds ever moved (the dedicated ledger account is only created once KYC is approved).
  - `balance` number, required: The card's live spendable balance.
  - `failureReason` string: Populated when status is KYC_REJECTED or CREATION_FAILED.
  - `spendControls` CardSpendControls
    - `dailyLimit` number
    - `transactionLimit` number
    - `whitelistedMccs` string[]
    - `blacklistedMccs` string[]
    - `contactlessPaymentEnabled` boolean
  - `createdDate` string, date-time, required
  - `cardDetails` CardDetails: Physical/visual card attributes, kept separate from the account-level fields above.
    - `displayName` string
    - `cardBrand` 'VISA' | 'MASTERCARD' | 'VERVE'
    - `cardType` string: Always VIRTUAL in this release.
    - `cardHolderName` string: The name embossed on the card, as assigned by the card provider.
    - `maskedCardNumber` string
    - `expiryMonth` string
    - `expiryYear` string
    - `billingAddress` CardBillingAddress: The card's billing address, as returned by the card provider. Response-only - fields are populated only when the provider supplies them, so none are required here (contrast CardHolderAddress, which validates a request body where every field must be present).
      - `address` string
      - `city` string
      - `state` string
      - `country` string
      - `postalCode` string
      - `zipCode` string
      - `houseNo` string
    - `encryptedCardDetails` string: Base64 RSA-encrypted {pan, cvv, expiryMonth, expiryYear} blob, populated only when fetched via GET /card-accounts/{cardAccountId}/details with a public key.

## Other responses

- `400`: Request could not be validated
- `401`: Client is not authorized to make request
- `403`: Expected permission is not available.
- `404`: Entity was not found
- `409`: The business has reached its lifetime limit on the number of card accounts it may create.
- `default`: Internal Server Error

## Changes

- **2026-09-16** `877f09d54c7d`: 1 info
  - added the non-success response with the status `409`
- **2026-09-11** `5ff3e810d459`: 1 info
  - added the new optional request property `cardPackageId`
- **2026-09-08** `5b7b2c163546`: 2 info
  - added the optional property `cardDetails/billingAddress` to the response with the `201` status
  - added the optional property `cardDetails/cardHolderName` to the response with the `201` status
- **2026-09-03** `1805362fe220`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/nestechops/apis/onboard-external-api-gateway/changes/ledger/card-accounts/post.md)

---

[API](https://skmtc.dev/nestechops/apis/onboard-external-api-gateway.md) - [All operations](https://skmtc.dev/nestechops/apis/onboard-external-api-gateway/llms.txt) - [OpenAPI document](https://skmtc.dev/nestechops/apis/onboard-external-api-gateway/revisions/5da9ec1b2573?raw)
