Why this exists
The card itself is issued through an external rail (see Baanx issuance). What partners need from Sumvin is a stable, auth-scoped API for the user-facing actions that follow — freezing a card the user can’t find, reporting it stolen, reactivating it after a false alarm — without integrating against the issuer directly. The state machine is enforced server-side, so partners can drive transitions without re-implementing validation.The endpoints, validation, and audit trail described below are shipped. The underlying issued card may be a stub today depending on integration status with the issuance rail — the lifecycle layer works either way.
Endpoints
All routes live under/v0/cards. Auth is the standard Juno-issued JWT (x-juno-jwt header). Routes accept an optional token — when present, the token’s scopes are enforced (sr:us:pint:cards:read for reads, sr:us:pint:cards:manage for state-changing actions). All read and write endpoints require the user to be in a serviceable status (KYC verified, account active).
| Method | Path | Action | Required scope (when PINT present) |
|---|---|---|---|
GET | /v0/cards | List the user’s cards | sr:us:pint:cards:read |
GET | /v0/cards/{card_id} | Get one card, optionally with status history | sr:us:pint:cards:read |
POST | /v0/cards/{card_id}/freeze | Freeze an active card | sr:us:pint:cards:manage |
POST | /v0/cards/{card_id}/unfreeze | Reinstate a frozen card | sr:us:pint:cards:manage |
POST | /v0/cards/{card_id}/lost | Report the card lost | sr:us:pint:cards:manage |
POST | /v0/cards/{card_id}/stolen | Report the card stolen | sr:us:pint:cards:manage |
POST | /v0/cards/{card_id}/activate | Activate a pending card | sr:us:pint:cards:manage |
external_id (a card-{uuid} string), not the internal numeric primary key.
The state machine
A card’s state is a(status, sub_status) pair. Reads return the current pair; lifecycle actions transition between pairs. The state machine has four top-level statuses.
| Status | Meaning |
|---|---|
pending | Card record exists but is not yet usable — issuing in progress, awaiting activation, or KYC outstanding |
active | Card is usable for transactions |
suspended | Card is temporarily blocked — by the user (frozen, lost), by the system (fraud watch), or by compliance |
closed | Card is permanently terminated — expired, replaced, voluntarily closed, fraud confirmed, or compliance close |
Sub-statuses
User-initiated transitions
The lifecycle endpoints map to a restricted set of transitions a user (or a partner acting on their behalf) is allowed to make. System and compliance transitions exist in the underlying state machine but aren’t exposed to partners.| Endpoint | From state | To state |
|---|---|---|
POST /freeze | (active, *) | (suspended, wallet_suspended) |
POST /unfreeze | (suspended, wallet_suspended) or (suspended, lost) | (active, reinstated) |
POST /lost | (active, *) | (suspended, lost) |
POST /stolen | (active, *) | (suspended, stolen), then auto-escalates to (suspended, fraud_suspected) |
POST /activate | (pending, activation_required) | (active, verified) |
Reporting a card stolen is a two-step transition on the server side. The card moves to
(suspended, stolen), then the system attempts a follow-up transition to (suspended, fraud_suspected). The response always reflects the final state. If the escalation fails, the card stays at (suspended, stolen) and the failure is logged.Discoverable next actions
Each card response includes a_links object with the actions available from the current state. A frozen card surfaces an unfreeze link; an active card surfaces freeze, lost, and stolen links; a pending card awaiting activation surfaces an activate link. Drive UI off these links rather than computing legality client-side.
Reference
List cards
GET /v0/cards/
Returns every card belonging to the authenticated user, with current status and the linked funding wallet address inlined for each card.
200 OK
Get card
GET /v0/cards/{card_id}
Returns a single card by its external_id. Pass include_history=true to inline the full status change history.
The card’s external identifier (
card-{uuid}).When
true, returns the full ordered status history (most recent first) on status_history.External card ID.
Last four digits of the PAN.
Card brand — one of
sumvin, visa, mastercard, amex, discover, unknown.Expiry month (1–12).
Expiry year (4 digits).
Cardholder name as printed.
One of
virtual, physical, metal.Whether this is the user’s primary card.
Address of the funding wallet backing this card.
Creation timestamp (epoch ms).
Current
(status, sub_status, changed_by, created_at) pair.Full status history when
include_history=true.The PAN, CVV, and other sensitive card data are never returned by the Card Management API. Surfacing the full PAN is part of the issuance flow and lives behind a separate, secured surface.
Freeze
POST /v0/cards/{card_id}/freeze
Suspends an active card. Transitions the card to (suspended, wallet_suspended). Reversible via unfreeze.
200 OK
Unfreeze
POST /v0/cards/{card_id}/unfreeze
Reinstates a card from (suspended, wallet_suspended) or (suspended, lost) to (active, reinstated). Returns the same CardActionResponse shape as freeze.
Report lost
POST /v0/cards/{card_id}/lost
Transitions an active card to (suspended, lost). The card can be reinstated with unfreeze if the user finds it, or replaced through the issuance rail.
Report stolen
POST /v0/cards/{card_id}/stolen
Transitions an active card to (suspended, stolen) and then auto-escalates to (suspended, fraud_suspected). This action is intentionally less recoverable than lost — reinstating from a stolen state requires going through fraud review, not a simple unfreeze.
Activate
POST /v0/cards/{card_id}/activate
Activates a card sitting at (pending, activation_required), transitioning it to (active, verified). Use this when the issuance rail has provisioned the card and the user has confirmed receipt.
Errors
All errors follow RFC 7807 Problem Details.| Code | Status | Meaning |
|---|---|---|
CRD-404-001 | 404 | Card not found |
CRD-404-002 | 404 | No status record exists for this card (internal — should not occur for healthy cards) |
CRD-403-001 | 403 | Card belongs to a different user |
CRD-403-002 | 403 | The transition is not allowed for the user (e.g. trying to activate a card that isn’t pending) |
CRD-400-001 | 400 | The requested transition is not valid from the current state |
Related
- Card issuing overview
- Funding wallets — what backs card spend
- Card issuing concept — the model behind the API
- Safes and identity — the on-chain identity anchor
- PAN (glossary)
- Issue a card quickstart
- Crypto wallet card use case