All card endpoints live under
/customers/{customerId}/accounts/{accountId}/cards… and check the matching
physicalCards.* / virtualCards.* permission claims.
The status actions use GET, not POST. block, unblock, activate, and cancel
are GET requests — a long-standing quirk of this surface. Don’t let an HTTP client that
treats GET as side-effect-free cache or retry them blindly.
Issue and read
| Endpoint | Notes |
|---|
GET …/cards | List the account’s cards (provider live data with legacy fallback, deduped). |
POST …/cards/v2 | Create a card — body cardType (required), nickName. Prefer this over the legacy POST …/cards. |
GET …/cards/{cardId} | One card, masked PAN. |
Status actions (GET)
| Endpoint | Claim |
|---|
GET …/cards/{cardId}/block | physicalCards.block / virtualCards.block |
GET …/cards/{cardId}/unblock | …unblock |
GET …/cards/{cardId}/activate (optional ?truncatedPan=) | physicalCards.activate |
GET …/cards/{cardId}/cancel | …cancel |
Each returns { "success": true, "result": { "status": … } }. Sandbox physical cards
return mocked statuses.
PIN and limits
PATCH …/cards/{cardId}/reset-pin — set a new card PIN (physical cards).
PATCH …/cards/{cardId}/update-limit-group — body limitGroupId, cardType,
providerCardId; moves the card to a provider-configured limit group.