Card issuing events
The events a card issuing program emits. The envelope they arrive in, test deliveries and the rule for unknown types are on the event catalog and apply to every product.
Each event has its own anchor. For example,
/docs/webhooks/events-card-issuing#card.frozen goes straight to card.frozen.
Cardholder
data.object is a cardholder with
id, object, type, kyc_status, has_identity_document, created_at,
updated_at, plus first_name, last_name, email, and reference when
those fields are set.
Sensitive identity information isn't included in webhook payloads. The identity
document number is never returned; has_identity_document only tells you
whether a document is on file. The address, phone number, and date of birth
aren't included either.
{
"id": "evt_01HX8ZQ2K4M7P9RSTV",
"object": "event",
"type": "cardholder.kyc_approved",
"api_version": "2026-08-01",
"environment": "sandbox",
"created_at": "2026-07-29T14:35:02Z",
"data": {
"object": {
"id": "chd_01HX8ZQ2K4M7P9RSTV",
"object": "cardholder",
"type": "individual",
"kyc_status": "approved",
"has_identity_document": true,
"first_name": "Test",
"last_name": "Approved",
"email": "test.approved@example.com",
"reference": "user-4471",
"created_at": "2026-07-29T14:32:05Z",
"updated_at": "2026-07-29T14:35:02Z"
}
}
}
cardholder.created
A new cardholder record was created.
cardholder.updated
A mutable cardholder field changed. This includes changes to kyc_status.
cardholder.kyc_approved
The cardholder's identity verification was approved.
cardholder.kyc_rejected
The cardholder's verification was definitively rejected.
Account
data.object is an account with id,
object, cardholder_id, program_id, currency, status, ledger_balance,
held_balance, available_balance, created_at, and updated_at, plus
reference when set.
The three balance fields are integers in the minor units of currency. This is
different from the REST API representation, where monetary values use {amount, currency} objects.
The processor's own account number is never included in an event payload.
{
"id": "evt_01HX8ZQ2K4M7P9RSTW",
"object": "event",
"type": "account.funded",
"api_version": "2026-08-01",
"environment": "sandbox",
"created_at": "2026-07-29T14:36:10Z",
"data": {
"object": {
"id": "acct_01HX8ZQ2K4M7P9RSTV",
"object": "account",
"cardholder_id": "chd_01HX8ZQ2K4M7P9RSTV",
"program_id": "prog_01HX8ZQ2K4M7P9RSTVWXYZABCD",
"currency": "SGD",
"status": "active",
"ledger_balance": 25000,
"held_balance": 0,
"available_balance": 25000,
"created_at": "2026-07-29T14:32:06Z",
"updated_at": "2026-07-29T14:36:10Z"
}
}
}
The balances reflect the account at the time the event is created. For
account.funded, that means the values have been read back after the credit was
applied rather than coming from the account's previous state.
account.created
An account was opened.
account.updated
The account changed. This includes status changes, such as an account being blocked or unblocked, as well as changes reported by the processor or a debit from the account.
account.funded
Value was credited to the account. The balance fields contain the values after the credit was applied.
Card
data.object is a card with id,
object, cardholder_id, account_id, program_id, form_factor, status,
currency, is_default, created_at, and updated_at, plus last_four,
embossed_name, expires_at, and reference when set.
{
"id": "evt_01HX8ZQ2K4M7P9RSTX",
"object": "event",
"type": "card.created",
"api_version": "2026-08-01",
"environment": "sandbox",
"created_at": "2026-07-29T14:32:08Z",
"data": {
"object": {
"id": "card_01HX8ZQ2K4M7P9RSTV",
"object": "card",
"cardholder_id": "chd_01HX8ZQ2K4M7P9RSTV",
"account_id": "acct_01HX8ZQ2K4M7P9RSTV",
"program_id": "prog_01HX8ZQ2K4M7P9RSTVWXYZABCD",
"form_factor": "virtual",
"status": "active",
"currency": "SGD",
"last_four": "4242",
"expires_at": "2029-04-30T23:59:59Z",
"is_default": true,
"created_at": "2026-07-29T14:32:08Z",
"updated_at": "2026-07-29T14:32:08Z"
}
}
}
The full card number and CVV are never included in webhook payloads. last_four
is the only part of the card number exposed here.
card.created means the card request was accepted. card.issued means the card
now exists and can be activated. card.activated means it can be used.
Every card follows the same path, on every program:
| Event | status in the payload | What to do |
|---|---|---|
card.created | pending, or inactive if the card was issued at once | Nothing yet |
card.issued | inactive | Call POST /v1/cards/{id}/activate when you want the card to start working |
card.activated | active | The card can be used |
card.created fires for every card. card.issued fires when a card moves out
of pending. A card that was issued at once is inactive already in the
card.created payload and has no card.issued event, so use the status in the
payload rather than relying on the event name.
card.created
Your request to issue a card was accepted and the card record now exists. It fires once for every card, on every program.
The status tells you what happened:
pending— the request was accepted, but the card isn't ready yet.card.issuedfollows once it is.inactive— the card was issued at once and is ready to be activated.
card.issued
A pending card now exists at the processor. Its status is inactive: the
card is ready to be activated, and can't be used yet.
The card may take a few minutes to appear, and sometimes closer to an hour. We
check for it for you and send the event once it's ready, so there's no need to
poll. The payload carries last_four and expires_at when the processor
reports them.
Activate the card with POST /v1/cards/{card_id}/activate when you're ready for
it to be used.
card.activated
The card is now active and can be used. It fires when you activate a card
with POST /v1/cards/{card_id}/activate, for virtual and physical cards alike.
Unfreezing a card does not trigger card.activated. It triggers
card.unfrozen.
card.frozen
The card was temporarily blocked.
card.unfrozen
A temporary card block was removed.
card.closed
The card was permanently terminated.
Authentication
data.object is an
authentication with id,
object, status, method, card_id, cardholder_id, amount,
created_at, and updated_at, plus merchant and expires_at when the Access
Control Server provides them.
Unlike the account balance fields, amount uses the normal {amount, currency}
format.
{
"id": "evt_01HX8ZQ2K4M7P9RSTX",
"object": "event",
"type": "authentication.challenged",
"api_version": "2026-08-01",
"environment": "sandbox",
"created_at": "2026-07-29T14:38:00Z",
"data": {
"object": {
"id": "authn_01HX8ZQ2K4M7P9RSTV",
"object": "authentication",
"status": "pending",
"method": "out_of_band",
"card_id": "card_01HX8ZQ2K4M7P9RSTV",
"cardholder_id": "chd_01HX8ZQ2K4M7P9RSTV",
"merchant": { "name": "Kopi Roastery" },
"amount": { "amount": 4250, "currency": "SGD" },
"created_at": "2026-07-29T14:38:00Z",
"updated_at": "2026-07-29T14:38:00Z"
}
}
}
Only out-of-band challenges produce authentication events. Passcode challenges are handled entirely inside the ACS and don't create an authentication object or webhook event.
An authentication can have a status of pending, approved, or declined.
authentication.challenged
A challenge is waiting for an answer from your application. The response window is only a few minutes, so this should be treated as a high-priority event.
authentication.approved
The challenge was approved and the authentication now has an approved status.
This doesn't mean the purchase is complete. The authorization happens separately and can still be declined because of the card state, available funds, or other controls.
authentication.declined
The challenge was declined, either by the cardholder or because your step-up flow failed. The merchant transaction will fail as a result.
Related
- Event catalog — the envelope, test deliveries, and unknown types
- Card issuing concepts — the objects these events carry