Update a card
Update a card's state and / or its bound fundingSources. At least one of the two fields must be supplied.
- state transitions are limited to ACTIVE ⇄ FROZEN and ACTIVE | FROZEN → CLOSED. CLOSED is terminal and irreversible. Any other transition returns 409 INVALID_STATE_TRANSITION.
- fundingSources, when supplied, fully replaces the card's bound funding sources. Array order determines the priority Authorization Decisioning tries them in. Each id must belong to the cardholder and be denominated in the card's currency; the list must contain at least one source. fundingSources cannot be supplied alongside state: CLOSED.
Because both updates are sensitive state changes, this endpoint uses Grid's 202 → signed-retry pattern (same shape as DELETE /auth/credentials/{id} and POST /internal-accounts/{id}/export):
-
Call PATCH /cards/{id} with the target fields and no signing headers. The response is 202 with a payloadToSign, requestId, and expiresAt.
-
Sign the payloadToSign with the session private key of a verified authentication credential on the card's owning internal account and retry with the signature as the Grid-Wallet-Signature header and the requestId echoed back as the Request-Id header. The signed retry returns 200 with the updated Card.
Effects:
- state: FROZEN: Authorization Decisioning declines new auths with CARD_PAUSED. Existing pulls and in-flight reconciliation continue — freezing does not pause the lifecycle of authorizations that already passed.
- state: ACTIVE: normal authorization behavior resumes.
- state: CLOSED: terminal close. The card transitions to state: "CLOSED" with stateReason: "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. Funding-source bindings are detached. Refunds already in flight still complete because Lightspark holds the card-reserve keys.
- fundingSources change: emits card.funding_source_change reflecting the new ordered binding.
The card.state_change webhook fires on every successful state transition; the card.funding_source_change webhook fires whenever fundingSources is updated.
Headers
Signature over the payloadToSign returned in a prior 202 response, produced with the session private key of a verified authentication credential on the card's owning internal account and base64-encoded. Required on the signed retry; ignored on the initial call.
The requestId returned in a prior 202 response, echoed back on the signed retry so the server can correlate it with the issued challenge. Required on the signed retry; must be paired with Grid-Wallet-Signature.
Request body
Example request
{
"state": "FROZEN",
"fundingSources": [
"InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"InternalAccount:019542f5-b3e7-1d02-0000-000000000003"
]
}Response
Signed retry accepted. Returns the updated card.
Example response
{
"id": "Card:019542f5-b3e7-1d02-0000-000000000010",
"cardholderId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
"platformCardId": "card-emp-aary-001",
"last4": "4242",
"expMonth": 12,
"expYear": 2029,
"fundingSources": [
"InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"InternalAccount:019542f5-b3e7-1d02-0000-000000000003"
],
"currency": "USD",
"processorRef": "card_b81c2a4f",
"issuerRef": "lead_card_7a1b9c3d",
"createdAt": "2026-05-08T14:10:00Z",
"updatedAt": "2026-05-08T14:11:00Z"
}