Cards

Update a card's status, bound fundingSource, and / or maxSpendPerTransaction, maxSpendPerDay, or maxTransactionsPerDay, or set a new threeDSecurePassword. At least one field must be supplied.

  • status transitions are limited to ACTIVE ⇄ FROZEN and ACTIVE | FROZEN → CLOSED. CLOSED is terminal and irreversible. Any other transition returns 409 INVALID_STATE_TRANSITION.
  • fundingSource, when supplied, replaces the card's bound internal account. It must belong to the customer and be denominated in the card's currency. fundingSource cannot be supplied alongside status: CLOSED. On card programs where the card issuer makes authorization decisions, fundingSource cannot be combined with any status change, so send the changes as separate requests. On card programs where Grid makes the authorization decision, the combination remains valid for status changes other than CLOSED.
  • maxSpendPerTransaction sets the largest amount the card can authorize on a single transaction. An authorization for exactly the limit is allowed, and a later clearing can still settle above it — a restaurant tip, for example — so this caps the authorization, not the final settled amount. Send a positive integer in the smallest unit of the card's currency (cents for USD) to set the limit, or null to remove it. If your platform config sets cardConfigs.maxSpendPerTransaction, the lower of the two applies. You can only send this when the card's cardCapabilities.supportsSpendLimits is true, and not together with status: CLOSED.
  • maxSpendPerDay, when supplied, replaces the card-specific cap on cumulative new spend during one UTC calendar day. Supply a positive integer in the smallest unit of the card's currency to set it or null to clear it. If the platform config sets cardConfigs.maxSpendPerDay, Grid enforces the lower of the card and platform values. Refunds, reversals, and authorization expiries do not restore capacity during the day. The card's cardCapabilities.supportsSpendLimits must be true. maxSpendPerDay cannot be supplied alongside status: CLOSED.
  • maxTransactionsPerDay, when supplied, replaces the card-specific cap on the number of transactions the card may authorize during one UTC calendar day. Supply a positive integer to set it or null to clear it. If the platform config sets cardConfigs.maxTransactionsPerDay, Grid enforces the lower of the card and platform values. Refunds, reversals, and authorization expiries do not restore capacity during the day. maxTransactionsPerDay requires the card's cardCapabilities.supportsTransactionCountLimit to be true and cannot be supplied alongside status: CLOSED.

This endpoint is authenticated by the platform credential alone and returns 200 directly. It deliberately does not use Grid's 202 → signed-retry pattern: that pattern signs with the session key of a credential on the owning internal account, so it models actions taken by the end user on their own credentials or funds. Freezing or closing a card is routinely an action taken about a user and without them present - fraud response, offboarding, an ops-driven freeze - and requiring the cardholder's signature would make exactly those cases impossible. Operations that expose sensitive card data (POST /cards/{id}/reveal, 3DS password retrieval) are SCA-railed instead, because there the cardholder is the party being served.

Effects:

  • status: FROZEN: Authorization Decisioning declines new auths with cardDeclinedReason: CARD_NOT_ACTIVE. Existing pulls and in-flight reconciliation continue — freezing does not pause the lifecycle of authorizations that already passed.
  • status: ACTIVE: normal authorization behavior resumes.
  • status: CLOSED: terminal close. The card transitions to status: "CLOSED" with statusReason: "CLOSED_BY_PLATFORM" and stays in the system for audit and reconciliation. All pending auths reconcile to a terminal state via the existing reconcile primitive. Inbound clearings received after close follow the standard force-post / late-presentment path — Lightspark absorbs the loss if a post-hoc pull on the now-unbound source fails. The funding source is detached. Refunds already in flight still complete because Lightspark holds the card-reserve keys.
  • fundingSource change: returns the updated card with the new binding and fires no webhook.

The card.status_change webhook fires on every successful status transition.

patch/cards/{id}

Request

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

Request body

status'ACTIVE' | 'FROZEN' | 'CLOSED'

Target status for the card. Permitted transitions are ACTIVE ⇄ FROZEN and ACTIVE | FROZEN → CLOSED. CLOSED is terminal and irreversible; once closed, the card stays in the system for audit and reconciliation but cannot transact again.

substatus'LOST' | 'COMPROMISED' | 'DAMAGED' | 'END_USER_REQUEST' | 'ISSUER_REQUEST' | 'NOT_ACTIVE' | 'SUSPICIOUS_ACTIVITY' | 'INTERNAL_REVIEW' | 'EXPIRED' | 'UNDELIVERABLE' | 'OTHER'

Why the card is moving, in the card issuer's vocabulary. Required whenever status is supplied, and forwarded to the issuer. Pick OTHER when none of the named values fit and say why in reason.

reasonstring

A short sentence naming why the card is moving. Required whenever status is supplied, and recorded against the card so a later reader can tell why it changed.

fundingSourcestring

Replaces the card's funding source. Must belong to the customer and be denominated in a currency supported by the card's program, including USDB for USD cards. Changing the funding source does not change the card's currency or spending-limit units. Cannot be supplied alongside status: CLOSED. To stop a card from spending, set status: FROZEN instead.

maxSpendPerTransactioninteger nullable

A new limit on 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. Send a positive integer to set the limit, null to remove it, or omit the field to leave it unchanged. If your platform config also sets cardConfigs.maxSpendPerTransaction, the lower of the two applies. You can only send this when the card's cardCapabilities.supportsSpendLimits is true, and not together with status: CLOSED.

maxSpendPerDayinteger nullable

Replacement card-specific UTC-calendar-day cap, in the smallest unit of the card's currency. Omit this field to leave the current cap unchanged, supply null to clear it, or supply a positive integer to set it. When the platform config also supplies cardConfigs.maxSpendPerDay, Grid enforces the lower of the two values. Refunds, reversals, and authorization expiries do not restore capacity during the day. Accepted only when the card's cardCapabilities.supportsSpendLimits is true. Cannot be supplied alongside status: CLOSED.

maxTransactionsPerDayinteger nullable

Replacement card-specific cap on the number of transactions the card may authorize during one UTC calendar day. Omit this field to leave the current cap unchanged, supply null to clear it, or supply a positive integer to set it. When the platform config also supplies cardConfigs.maxTransactionsPerDay, Grid enforces the lower of the two values. Refunds, reversals, and authorization expiries do not restore capacity during the day. Accepted only when the card's cardCapabilities.supportsTransactionCountLimit is true. Cannot be supplied alongside status: CLOSED.

threeDSecurePasswordstring

Sets a new static 3-D Secure password on the card. Send it on its own, and only when the card's cardCapabilities.supports3dSecurePassword is true.

Example request

{
  "status": "FROZEN",
  "substatus": "SUSPICIOUS_ACTIVITY",
  "reason": "Cardholder reported the card stolen.",
  "fundingSource": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
  "maxSpendPerTransaction": 10000,
  "maxSpendPerDay": 25000,
  "maxTransactionsPerDay": 20,
  "threeDSecurePassword": "AbCd1234EfGh5678"
}

Response

Card updated. Returns the updated card.

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