Cards

Issue a new card for a cardholder. Every card is bound to one internal account, fundingSource, at create time. The cardholder must have KYC status APPROVED before a card can be issued; otherwise the request is rejected with CARDHOLDER_KYC_NOT_APPROVED.

Card issuance is fee-bearing and cannot be reversed, so an Idempotency-Key header is required. Retries must carry the same key.

Optional maxSpendPerTransaction, maxSpendPerDay, and maxTransactionsPerDay values set the card-specific caps on one transaction, on spend during one UTC calendar day, and on the number of transactions during one UTC calendar day. Check the funding-source internal account's cardCapabilities.supportsSpendLimitsAtIssuance before supplying either spend limit, and cardCapabilities.supportsTransactionCountLimit before supplying the transaction count limit. If the platform config sets the corresponding cardConfigs value, Grid enforces the lower of the card and platform caps. Amounts use the smallest unit of the card's currency.

If the funding source is an Embedded Wallet internal account, the cardholder must authorize Grid to sign Spark token transactions for that card funding source by completing the delegated-key creation flow with POST /auth/delegated-keys. Until an active delegated key exists for that funding source, Authorization Decisioning cannot use it to fund card transactions.

A platform may be limited to a maximum number of live cards. Once that limit is reached, further issuance is rejected with CARD_LIMIT_REACHED until a card is closed or Lightspark raises the limit. Cards in CLOSED status do not count toward the limit.

New cards start in status: "PROCESSING" while the card issuer provisions the card. The card.status_change webhook fires on each status transition, including the transition to ACTIVE (or to CLOSED with statusReason: "ISSUER_REJECTED" if provisioning fails).

post/cards

Request

  • Base URL: https://api.lightspark.com/grid/2025-10-13
  • URL: https://api.lightspark.com/grid/2025-10-13/cards
  • Auth: HTTP basic

Headers

Idempotency-Keystring required
Example:550e8400-e29b-41d4-a716-446655440000

A unique identifier for the request, up to 255 characters. A retry carrying the same key returns the card created by the first request; reusing a key for a materially different card request is rejected with 409.

Request body

customerIdstring required

The id of the Customer to issue the card to. The customer must have KYC status APPROVED; otherwise the request is rejected with CARDHOLDER_KYC_NOT_APPROVED.

platformCardIdstring

Platform-specific card identifier. Always generated by the server; any value supplied in the request is ignored.

threeDSecurePasswordstring

Static password used as the card's 3-D Secure factor. Required when the first funding-source internal account's cardCapabilities.supports3dSecurePassword is true; omitting it or supplying an empty or whitespace-only string is rejected with INVALID_INPUT. When the capability is false, supplying this field is rejected with INVALID_INPUT because cards in that program have no static-password factor. Grid does not retain the value: it is forwarded to the issuer and discarded, so it cannot be read back afterwards; a cardholder who forgets it must set a new one through PATCH /cards/{id}.

form'VIRTUAL' required

Physical form factor of the card. Only VIRTUAL is supported in v1; PHYSICAL will be added in a later release.

fundingSourcestring required

Internal account id that funds this card. The account must belong to the customer and be denominated in a card-eligible currency; otherwise the request is rejected with INVALID_INPUT.

maxSpendPerTransactioninteger

The largest amount this card can authorize on a single transaction, in the smallest unit of its currency (cents for USD). An authorization for exactly the limit is allowed. A later clearing can still settle above it — a restaurant tip, for example — so this caps the authorization, not the final settled amount. Omit the field to set no limit. If your platform config also sets cardConfigs.maxSpendPerTransaction, the lower of the two applies. You can only send this when the funding-source internal account's cardCapabilities.supportsSpendLimitsAtIssuance is true.

maxSpendPerDayinteger

Optional card-specific cap on cumulative new spend during one UTC calendar day, in the smallest unit of the card's currency (USD cents for USDB-funded cards). Omit this field for no card-specific daily cap. When the platform config also supplies cardConfigs.maxSpendPerDay, Grid enforces the lower of the two values. The window resets at 00:00 UTC, and refunds, reversals, and authorization expiries do not restore capacity during the day. Accepted only when the funding-source internal account's cardCapabilities.supportsSpendLimitsAtIssuance is true. Spend exactly equal to the effective limit is allowed.

maxTransactionsPerDayinteger

Optional card-specific cap on the number of transactions the card may authorize during one UTC calendar day. Omit this field for no card-specific daily transaction cap. When the platform config also supplies cardConfigs.maxTransactionsPerDay, Grid enforces the lower of the two values. The window resets at 00:00 UTC. Each approved authorization counts once; refunds, reversals, and authorization expiries do not restore capacity during the day. Accepted only when the funding-source internal account's cardCapabilities.supportsTransactionCountLimit is true.

Example request

{
  "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "platformCardId": "card-emp-001",
  "threeDSecurePassword": "AbCd1234EfGh5678",
  "fundingSource": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
  "maxSpendPerTransaction": 5000,
  "maxSpendPerDay": 25000,
  "maxTransactionsPerDay": 20
}

Response

Card created successfully. Newly-created cards start in PROCESSING while the issuer provisions them. Cards funded by an Embedded Wallet internal account also require an active delegated key for that funding source before Authorization Decisioning can use it.

idstring required

System-generated unique card identifier

customerIdstring required

The id of the Customer who holds this card.

platformCardIdstring

Platform-specific card identifier generated by the server.

status'PENDING_KYC' | 'PROCESSING' | 'ACTIVE' | 'FROZEN' | 'CLOSED' required

Lifecycle status of a card.

StatusDescription
PENDING_KYCThe cardholder has not yet completed KYC. Cards in this status cannot transact.
PROCESSINGThe card has been requested and is being provisioned with the issuer.
ACTIVEThe card is live and can authorize transactions.
FROZENThe card is temporarily disabled by the platform. New authorizations are declined with cardDeclinedReason: CARD_NOT_ACTIVE. Existing settlements and refunds continue to reconcile.
CLOSEDThe card is permanently closed. Terminal, irreversible status.
statusReason'ISSUER_REJECTED' | 'CLOSED_BY_PLATFORM' | 'CLOSED_BY_GRID'

Reason a card reached a terminal or non-active status. Present on CLOSED cards, and on cards that fail provisioning before reaching ACTIVE.

ReasonDescription
ISSUER_REJECTEDThe card issuer rejected provisioning during PROCESSING.
CLOSED_BY_PLATFORMThe card was closed via PATCH /cards/{id} (status: CLOSED) by the platform.
CLOSED_BY_GRIDThe card was closed by Grid (e.g. compliance or risk action).
brand'VISA' | 'MASTERCARD'

Card network brand. Read-only — determined by Grid when the card is provisioned with the issuer.

form'VIRTUAL' required

Physical form factor of the card. Only VIRTUAL is supported in v1; PHYSICAL will be added in a later release.

last4string

Last four digits of the card PAN.

expMonthinteger

Card expiration month (1–12).

expYearinteger

Card expiration year (four digits).

fundingSourcestring required

Internal account id that funds this card.

maxSpendPerTransactioninteger nullable required

The largest amount this card can authorize on a single transaction, in the smallest unit of its currency (cents for USD). An authorization for exactly the limit is allowed. A later clearing can still settle above it — a restaurant tip, for example — so this caps the authorization, not the final settled amount. null means the card sets no limit of its own. If your platform config also sets cardConfigs.maxSpendPerTransaction (the platform-level limit), the lower of the two applies and this value stays as you set it.

maxSpendPerDayinteger nullable required

Card-specific cap on cumulative new spend during one UTC calendar day, in the smallest unit of the card's currency. The window resets at 00:00 UTC. Null means the card has no card-specific daily cap. When the platform config also supplies cardConfigs.maxSpendPerDay, Grid enforces the lower of the two values without replacing this configured value. Refunds, reversals, and authorization expiries do not restore capacity during the day. Spend exactly equal to the effective limit is allowed.

maxTransactionsPerDayinteger nullable required

Card-specific cap on the number of transactions the card may authorize during one UTC calendar day. The window resets at 00:00 UTC. Null means the card has no card-specific daily transaction cap. When the platform config also supplies cardConfigs.maxTransactionsPerDay, Grid enforces the lower of the two values without replacing this configured value. Each approved authorization counts once for the day it was authorized; refunds, reversals, and authorization expiries do not restore capacity during the day. A transaction that brings the day's count exactly to the effective limit is allowed.

currencystring

Currency the card transacts in, fixed at issuance by its card program. USDB-funded cards transact in USD, with funding converted at 1 USDB = 1 USD. Spending limits use the smallest unit of the card's currency (USD cents for USDB-funded cards). Changing the funding source does not change the card's currency or spending-limit units.

processorRefstring

Opaque processor-side reference for the card (e.g. the Lithic card token). Useful for cross-referencing in the processor's dashboards; not used for any Grid request routing.

issuerRefstring

Opaque identifier for the card on the issuer of record (e.g. the Lead Bank account/card identifier). Useful for cross-referencing in issuer dashboards; not used for any Grid request routing.

createdAtstring date-time required

Creation timestamp

updatedAtstring date-time required

Last update timestamp

Example response

{
  "id": "Card:019542f5-b3e7-1d02-0000-000000000010",
  "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "platformCardId": "card-emp-001",
  "last4": "4242",
  "expMonth": 12,
  "expYear": 2029,
  "fundingSource": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
  "cardCapabilities": {
    "supportsSpendLimits": true,
    "supportsSpendLimitsAtIssuance": true,
    "supportsTransactionCountLimit": true,
    "supportsPanReveal": true,
    "supportsDigitalWalletTokenization": true
  },
  "maxSpendPerTransaction": 5000,
  "maxSpendPerDay": 25000,
  "maxTransactionsPerDay": 20,
  "currency": "USD",
  "processorRef": "card_b81c2a4f",
  "issuerRef": "lead_card_7a1b9c3d",
  "createdAt": "2026-05-08T14:10:00Z",
  "updatedAt": "2026-05-08T14:11:00Z"
}

Changes

    • info

      added the required property / to the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • breaking

      removed the required property from the response with the status

    • warning

      added the new DOCUMENT_ALREADY_EXISTS enum value to the response property for the response status

    • warning

      added the new DUPLICATE_EXTERNAL_ACCOUNT enum value to the response property for the response status

    • warning

      added the new DUPLICATE_PAY_REQUEST enum value to the response property for the response status

    • warning

      added the new INSUFFICIENT_FUNDS enum value to the response property for the response status

    • warning

      added the new QUOTE_EXPIRED enum value to the response property for the response status

    • warning

      added the new QUOTE_RATE_UNAVAILABLE enum value to the response property for the response status

    • warning

      added the new SMS_OTP_CREDENTIAL_SET_CHANGED enum value to the response property for the response status

    • warning

      added the new SMS_OTP_PHONE_NUMBER_ALREADY_EXISTS enum value to the response property for the response status

    • warning

      added the new STABLECOIN_AMOUNT_NOT_REPRESENTABLE enum value to the response property for the response status

    • warning

      added the new STABLECOIN_BURN_SOURCE_NOT_SUPPORTED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_EXTERNAL_ACCOUNT_LINK_FAILED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_EXTERNAL_ACCOUNT_LINK_METHOD_REQUIRED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_EXTERNAL_ACCOUNT_NOT_LINKED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_EXTERNAL_ACCOUNT_NOT_SUPPORTED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_EXTERNAL_ACCOUNT_PROVIDER_LINK_FAILED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_EXTERNAL_ACCOUNT_PROVIDER_LINK_REQUIRED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_GRID_OPERATIONS_NOT_ENABLED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_NOT_PROVISIONED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_OPERATION_NOT_SUPPORTED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_PROVIDER_ERROR enum value to the response property for the response status

    • warning

      added the new STABLECOIN_PROVIDER_SOURCE_NOT_LINKED enum value to the response property for the response status

    • warning

      added the new STABLECOIN_SYMBOL_ALREADY_EXISTS enum value to the response property for the response status

    • warning

      added the new STABLECOIN_TOKEN_IDENTIFIER_ALREADY_EXISTS enum value to the response property for the response status

    • warning

      added the new STABLECOIN_VERIFICATION_FAILED enum value to the response property for the response status

    • warning

      added the new UNRECOGNIZED_MANDATORY_COUNTERPARTY_DATA_KEY enum value to the response property for the response status

    • warning

      added the new WALLET_NOT_PROVISIONED enum value to the response property for the response status

    • info

      added the required property / to the response with the status

    • info

      added the required property to the response with the status

    • info

      added the required property to the response with the status

    • info

      added the required property to the response with the status

    • info

      added the required property to the response with the status

    • info

      added the required property to the response with the status