1. Webhook's
Artha All Module Api's
  • Introduction
  • Authentication
  • KYC/KYB Requirements
  • API Setup Guide
  • Products
    • List Products
      GET
    • Get Product
      GET
    • Get Customer Product Status
      GET
  • Customers
    • Create Customer
      POST
    • List Customers
      GET
    • Get Customer
      GET
    • Submit Applicant (KYC/KYB)
      POST
    • Create Onboarding Session
      POST
  • Wallets
    • Beneficiary
      • Create Crypto Beneficiary
      • Update Crypto Beneficiary
      • List Crypto Withdraw Beneficiaries
    • Create Wallet
      POST
    • Get Wallet Address
      GET
    • Get Customer Balances
      GET
    • List Wallets
      GET
    • List Withdrawals
      GET
    • List Withdrawal Networks
      GET
    • Preview Withdrawal Summary
      POST
    • Create Crypto Withdrawal
      POST
  • Cards
    • Issuance
      • Issue Card
      • List Cards
      • List Customer Cards
      • Get Card Details
      • Get Sensitive Card Details
    • Funding
      • Top Up Card
      • Get Card Balance
      • Get Top-Up Status
      • List Top-Up History
    • Operations
      • Resend Activation Code
      • Activate Card
      • Set Card PIN
      • Change Card PIN
      • Update Card Limits
      • Freeze Card
      • Unfreeze Card
      • Replace Card
      • Cancel Card
      • Get Card Limits
      • Show Card PIN Details
      • Get PIN View Iframe URL
      • Get PIN Change Iframe URL
      • Get PIN Set Iframe URL
      • Get Card View Iframe URL
      • Show Card PIN
  • Payees
    • Create a payee for a customer.
    • List a customer's payees.
    • Update a payee.
    • Retrieve a payee by id.
    • Look up an existing payee.
    • List the currencies a payee can be created in.
    • List the accepted payment purpose codes for a payee.
    • List the countries a payee can be created in.
    • List currency/country pairings for payees.
    • List the accepted beneficiary relationship codes.
  • Payments
    • Onboarding
      • List the customer's payout-currency configuration sections.
      • Enable a payout-currency section for the customer.
      • Get the customer's terms-of-service acceptance status.
      • Enable or disable a payout-currency section.
    • Quote
      • List the currencies a beneficiary can be paid in under a product.
      • List the payout rails available for a product and beneficiary.
      • Create an FX quote giving the rate and fee for a cross-currency payout.
    • Order
      • Submit a payout order to send money to a beneficiary.
      • Retrieve the on-chain address to fund an order.
      • Retrieve the status and settlement detail of a payout order.
    • Lookups
      • List the accepted payment purpose codes for a payout.
      • List the accepted source-of-funds codes for a payout.
      • List the document types accepted on a payout order.
  • Banks
    • Accounts
      • Create Bank Account
      • Get Account Details
      • Get Account Issuance Status
    • Withdraw
      • Create Withdrawal Quote
      • List Withdrawal Purposes
      • Get Payment Schemes
      • Execute Withdrawal
  • Exchange
    • Quote
      • Get Exchange Rate
      • Create Price Quote
    • Order
      • Place Exchange Order
  • Transactions
    • List Transactions
    • Get Transaction Details
  • Utilities
    • List Currencies
    • List Countries
    • Get Fee Schedule
    • List Product Occupations
    • List Product Industry Codes
    • Upload File
  • Webhook's
    • Wallets Webhooks
    • Banks Webhooks
    • Payments Webhooks
    • Exchange Webhooks
    • Card Webhooks
  1. Webhook's

Card Webhooks

Overview#

This document describes all outgoing card webhook event payloads sent by the platform. Webhooks are HTTP POST requests with a Content-Type: application/json header delivered to your configured endpoint URL.
There are 26 card events across five categories. Subscribe to them individually, or use * to receive everything.

Payload Conventions#

ConventionDetail
FormatJSON
HTTP MethodPOST
Content-Typeapplication/json
Field namingcamelCase on every event
Null fieldsIncluded as null (not omitted)
TimestampsISO 8601 — YYYY-MM-DDTHH:mm:ssZ
AmountsDecimal string or number in the currency's minor/major unit as configured
Card numbersMasked — last four digits only. Full PAN is never sent

Envelope#

Every event has the same four top-level keys. Only data changes shape between categories.
{
  "id": "evt_371ef0989512474abb2889da89417d36",
  "type": "card.approved",
  "createdAt": "2026-08-22T14:12:59.8432749Z",
  "data": { }
}
FieldTypeDescription
idstringUnique event id, prefixed evt_. Use it to deduplicate — a redelivered event keeps the same id
typestringThe event name. Identical to the X-Event-Type header
createdAtstringISO 8601 UTC timestamp the event was created
dataobjectEvent payload. Shape depends on the category

Headers#

HeaderExampleDescription
Content-Typeapplication/jsonAlways JSON
X-Webhook-Idwh_9f2c1a4b6d8e4f0a9b3c5d7e1f2a3b4cThe subscription this was delivered for
X-Webhook-Signature4a7f2c8e91b0…Lowercase hex HMAC-SHA256. See below
X-Webhook-Timestamp1787654021Unix epoch seconds. Part of the signed string
X-Event-Typecard.freezeThe event name, duplicated from the payload's type

Verifying the Signature#

Always verify before acting on an event. The signed string is the timestamp, a literal dot, then the raw request body:
HMAC-SHA256( secret, "{X-Webhook-Timestamp}.{rawBody}" )
Hex-encode lowercase and compare against X-Webhook-Signature using a constant-time comparison. The secret is the one issued when your subscription was created.
Sign the body exactly as received. Parsing the JSON and re-serialising it changes whitespace and key order, and the signature will not match.
This is not the REST API's signing scheme. The API uses X-Signature / X-Timestamp / X-Nonce / X-Body-Hash with a different secret, a different signed string and a different encoding. Verifying a webhook with the API-request scheme can never succeed.

Delivery, Retries and Ordering#

RuleDetail
SuccessAny 2xx. Return it as soon as the event is stored — do your processing afterwards
Timeout30 seconds. A slower response counts as a failure
Retries5 attempts: after 1 min, 5 min, 30 min, 2 hours, then 24 hours
ExhaustedAfter the fifth attempt the event is marked Failed and never retried
Auto-disable50 consecutive failures deactivates your subscription
OrderingEvents are not ordered and may arrive more than once
Make your handler idempotent. Key on the envelope's id and treat an already-applied state as a no-op. A retried transaction.settled must not book twice.

Event Categories#

#CategoryEvents
1Cardholder Applicationcardholder.reviewing , cardholder.needinformation , cardholder.approved , cardholder.rejected
2Card Statuscard.created , card.under.review , card.approved , card.rejected
3Card Actioncard.activate , card.freeze , card.unfreeze , card.cancel , card.replaced , card.set.pin , card.limit.updated , card.3DS , card.resend.code
4Card Top-upcard.topup.completed , card.topup.failed
5Transactiontransaction.authorized , transaction.settled , transaction.declined , transaction.reversed , transaction.refunded , transaction.maintainfee , transaction.overdraft

1. Cardholder Application Events#

Applicable event types: cardholder.reviewing · cardholder.needinformation · cardholder.approved · cardholder.rejected
Fired as a KYC (individual) or KYB (business) application moves through review to a final decision.

Payload#

{
  "id": "evt_1ef4af8115c84926a0928f43874fe418",
  "type": "cardholder.approved",
  "createdAt": "2026-08-22T10:22:39.5378959Z",
  "data": {
    "customerId": "a636169d-8d5a-4461-b622-82a83df8d037",
    "firstName": "Sabrina",
    "lastName": "Marie",
    "email": "sabrina.marie@example.com",
    "applicationStatus": "cardholder.approved",
    "applicationReason": "Approved"
  }
}

Fields#

FieldTypeDescription
customerIdstringUUID of the customer the application belongs to
firstNamestringApplicant's first name
lastNamestringApplicant's last name
emailstringApplicant's email
applicationStatusstringThe resulting status. Echoes the event name
applicationReasonstringHuman-readable reason. Carries the rejection or need-information detail

Event behaviour#

typeMeaningAction required
cardholder.reviewingUnder reviewShow the applicant it is in progress
cardholder.needinformationMore information requiredRead applicationReason, then call Resubmit KYC/KYB Applicant
cardholder.approvedApprovedThe card can now proceed
cardholder.rejectedRejectedRead applicationReason

Need-information example#

{
  "id": "evt_5c81a0d33b7e4d9fa2e6b4c8d0f13579",
  "type": "cardholder.needinformation",
  "createdAt": "2026-08-22T10:20:11.4471002Z",
  "data": {
    "customerId": "a636169d-8d5a-4461-b622-82a83df8d037",
    "firstName": "Sabrina",
    "lastName": "Marie",
    "email": "sabrina.marie@example.com",
    "applicationStatus": "cardholder.needinformation",
    "applicationReason": "Proof of address is unreadable. Please upload a clearer copy."
  }
}

2. Card Status Events#

Applicable event types: card.created · card.under.review · card.approved · card.rejected
The card itself being issued, approved or declined — distinct from the cardholder's KYC decision in category 1.

Payload#

{
  "id": "evt_371ef0989512474abb2889da89417d36",
  "type": "card.approved",
  "createdAt": "2026-08-22T14:12:59.8432749Z",
  "data": {
    "customerId": "3a8c0d54-7c83-4b69-9cc4-e234a6cd41ec",
    "cardId": "924df277-82ad-49e3-b57e-30db104e74f8",
    "cardType": "Virtual",
    "cardNumber": "XXXX XXXX XXXX 9315",
    "taskId": null,
    "applicationStatus": "card.approved",
    "applicationReason": "Success"
  }
}

Fields#

FieldTypeDescription
customerIdstringUUID of the card owner. For an employee card this is the company, not the employee
cardIdstringUUID of the card
cardTypestringVirtual or Physical
cardNumberstringMasked PAN, last four visible. null on card.created and card.under.review, because the issuer has not returned a number yet. Populated from card.approved onward
taskIdstringPresent only when an operation triggered the status change. null on a normal issuance
applicationStatusstringThe resulting status. Echoes the event name
applicationReasonstringHuman-readable reason

Rejection example#

{
  "id": "evt_84f0b1c6e9d24a7b8c3f5e0a1d269473",
  "type": "card.rejected",
  "createdAt": "2026-08-22T14:31:08.2260517Z",
  "data": {
    "customerId": "3a8c0d54-7c83-4b69-9cc4-e234a6cd41ec",
    "cardId": "924df277-82ad-49e3-b57e-30db104e74f8",
    "cardType": "Virtual",
    "cardNumber": null,
    "taskId": null,
    "applicationStatus": "card.rejected",
    "applicationReason": "Issuer declined the application"
  }
}

3. Card Action Events#

Applicable event types: card.activate · card.freeze · card.unfreeze · card.cancel · card.replaced · card.set.pin · card.limit.updated · card.3DS · card.resend.code
Confirmation that an operation you requested has completed at the issuer. The REST call that started it returns immediately — this event is the real outcome. Match it to your request using taskId.

Payload#

{
  "id": "evt_123c649c9e674a9ab89c2f4533dfc983",
  "type": "card.freeze",
  "createdAt": "2026-08-22T10:17:58.0661445Z",
  "data": {
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "cardId": "4dd662bb-3730-4459-b905-402d449b62ce",
    "cardType": "Virtual",
    "cardNumber": null,
    "taskId": "9eeee0e6-0c35-4af7-912a-ef865e70ee9f",
    "applicationStatus": "Frozen",
    "applicationReason": "Card frozen successfully."
  }
}

Fields#

FieldTypeDescription
customerIdstringUUID of the card owner
cardIdstringUUID of the card. This identifies the card — use it, not cardNumber
cardTypestringVirtual or Physical
cardNumberstringMasked PAN. null on every action except card.replaced — see the note below
taskIdstringThe id returned by the REST call that started this operation. Use it to match the event to your request
applicationStatusstringThe resulting state — see Status Values
applicationReasonstringHuman-readable message
Why cardNumber is null here. These events report a state change on a card you already know about — freezing it does not change its number, so none is sent. The one exception is card.replaced, which mints a new card and therefore carries the new masked PAN. Identify the card by cardId in every case.

card.replaced — carries the new card number#

{
  "id": "evt_6b0d29e7c1f34a58a9d3e5b7c2408f16",
  "type": "card.replaced",
  "createdAt": "2026-08-22T11:02:33.7714920Z",
  "data": {
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "cardId": "7f1a44cd-9b02-4e77-8c15-6ad3e0b91742",
    "cardType": "Physical",
    "cardNumber": "XXXX XXXX XXXX 4471",
    "taskId": "c31b7e90-52aa-4f18-90d7-1e6b8a2f4c05",
    "applicationStatus": "Replacement Requested",
    "applicationReason": "Card replacement requested."
  }
}

card.resend.code — adds two fields#

FieldTypeDescription
activationCodestringThe activation code
activationCodeExpiresAtstringISO 8601 UTC expiry, when the issuer supplies one
The activation code is delivered only on this event. It is never returned on the REST response. Without handling this event you cannot complete a physical card activation.
{
  "id": "evt_e40a7c92b6d84f1cae35d9f087b21460",
  "type": "card.resend.code",
  "createdAt": "2026-08-22T11:40:05.3392118Z",
  "data": {
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "cardId": "4dd662bb-3730-4459-b905-402d449b62ce",
    "cardType": "Physical",
    "cardNumber": null,
    "taskId": "1d90cf62-77b4-4a03-9c58-b0e14f5a2d38",
    "applicationStatus": "Active",
    "applicationReason": "Activation code resent successfully.",
    "activationCode": "483920",
    "activationCodeExpiresAt": "2026-08-22T12:10:05Z"
  }
}

4. Card Top-up Events#

Applicable event types: card.topup.completed · card.topup.failed
The outcome of a card top-up.

Payload#

{
  "id": "evt_9c4e17a05b8d43f2b71c6ade90f3527b",
  "type": "card.topup.completed",
  "createdAt": "2026-08-22T13:05:44.6620391Z",
  "data": {
    "transactionId": "0f2a6d31-88ce-4b17-9a05-3d7f2e4c8b60",
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "cardId": "7c290ef9-9d3f-4ef0-bb54-831ddc336a54",
    "taskId": "TX20260822130544",
    "amount": 250.00,
    "currency": "USDT",
    "status": "SUCCESS",
    "remarks": "Card top-up completed"
  }
}

Fields#

FieldTypeDescription
transactionIdstringUUID of the top-up transaction
customerIdstringUUID of the card owner
cardIdstringThe card at the issuer
taskIdstringCorrelates with the top-up request
amountnumberAmount credited
currencystringCurrency of the amount
statusstringSUCCESS or FAILED
remarksstringHuman-readable detail. Carries the failure reason on card.topup.failed

Failure example#

{
  "id": "evt_3d70b8f1a5c94e26b09e4c7d1f83a052",
  "type": "card.topup.failed",
  "createdAt": "2026-08-22T13:09:12.8830476Z",
  "data": {
    "transactionId": "9b4e17c2-60da-4f83-a715-2e8c05d3f194",
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "cardId": "7c290ef9-9d3f-4ef0-bb54-831ddc336a54",
    "taskId": "TX20260822130912",
    "amount": 250.00,
    "currency": "USDT",
    "status": "FAILED",
    "remarks": "Insufficient wallet balance"
  }
}

5. Transaction Events#

Applicable event types: transaction.authorized · transaction.settled · transaction.declined · transaction.reversed · transaction.refunded · transaction.maintainfee · transaction.overdraft
Fired whenever a transaction lifecycle action occurs on a card.

Payload#

{
  "id": "evt_2fb85a0c7d1e44639ac0b3e51d78f204",
  "type": "transaction.settled",
  "createdAt": "2026-08-22T15:48:20.5514773Z",
  "data": {
    "event": "settlement",
    "transactionId": "b5c81f04-3a92-4d17-90e6-7c2f5a8b1d43",
    "cardId": "7c290ef9-9d3f-4ef0-bb54-831ddc336a54",
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "originalTransactionId": null,

    "localCurrency": "GBP",
    "localAmount": "42.50",

    "authorizedAmount": "53.10",
    "authorizedCurrency": "USD",
    "authorizationCode": "AUTH004512",
    "authorizedAt": "2026-08-22T15:41:02Z",

    "fee": "0.30",
    "feeCurrency": "USD",

    "crossborderFee": "0.53",
    "crossborderFeeCurrency": "USD",

    "settleAmount": "53.93",
    "settleCurrency": "USD",
    "settleDate": "2026-08-23",

    "merchantName": "Deliveroo",
    "merchantCategoryCode": "5812",
    "merchantCountry": "GB",
    "merchantCity": "London",

    "type": "settlement",
    "subType": "settlement",
    "status": "SETTLED",
    "description": "Card purchase"
  }
}

Fields#

FieldTypeDescription
eventstringThe transaction lifecycle action
transactionIdstringUUID of this transaction
cardIdstringThe card at the issuer
customerIdstringUUID of the card owner
originalTransactionIdstringThe transaction being refunded or reversed. null on an original transaction
localCurrencystringISO 4217 currency code of the transaction at the point of sale
localAmountstringAmount in the local currency
authorizedAmountstringAmount authorized in the card's billing currency
authorizedCurrencystringISO 4217 code of the card's billing/wallet currency
authorizationCodestringAuthorization code returned by the network
authorizedAtstringISO 8601 timestamp when authorization was issued
feestringPlatform or card fee applied
feeCurrencystringCurrency of the fee
crossborderFeestringCross-border/FX conversion fee, if applicable
crossborderFeeCurrencystringCurrency of the cross-border fee
settleAmountstringPre-settlement amount
settleCurrencystringCurrency of the settlement amount
settleDatestringISO 8601 expected or actual settlement date
merchantNamestringName of the merchant
merchantCategoryCodestringISO 18245 MCC code
merchantCountrystringISO 3166-1 alpha-2 merchant country code
merchantCitystringMerchant city
typestringTransaction type
subTypestringTransaction sub-type
statusstringTransaction status
descriptionstringFree-text remarks

Refund example#

A refund carries originalTransactionId pointing at the transaction being refunded.
{
  "id": "evt_7a1c9e04d3b8452fae06c92d14f7b385",
  "type": "transaction.refunded",
  "createdAt": "2026-08-23T09:12:41.2049167Z",
  "data": {
    "event": "refund",
    "transactionId": "e40c9a72-1f68-4b35-8d02-9c7a5e13f860",
    "cardId": "7c290ef9-9d3f-4ef0-bb54-831ddc336a54",
    "customerId": "ee22ee94-0523-4b7b-8426-4f5589f4a56f",
    "originalTransactionId": "b5c81f04-3a92-4d17-90e6-7c2f5a8b1d43",

    "localCurrency": "GBP",
    "localAmount": "42.50",

    "authorizedAmount": "53.10",
    "authorizedCurrency": "USD",
    "authorizationCode": "AUTH004512",
    "authorizedAt": "2026-08-23T09:12:38Z",

    "fee": "0.00",
    "feeCurrency": "USD",

    "crossborderFee": "0.00",
    "crossborderFeeCurrency": "USD",

    "settleAmount": "53.10",
    "settleCurrency": "USD",
    "settleDate": "2026-08-24",

    "merchantName": "Deliveroo",
    "merchantCategoryCode": "5812",
    "merchantCountry": "GB",
    "merchantCity": "London",

    "type": "refund",
    "subType": "refund",
    "status": "REFUNDED",
    "description": "Order cancelled by merchant"
  }
}

Status Values Quick Reference#

The value in applicationStatus, per event.
EventapplicationStatus
card.activateActive
card.freezeFrozen
card.unfreezeActive
card.cancelpending, then success on the follow-up event
card.replacedReplacement Requested
card.set.pinPIN Set or PIN Changed
card.limit.updatedLimit Updated
card.3DSCode Sent
card.resend.codeThe card's current state
card.approved · card.rejected · card.under.reviewEchoes the event name
cardholder.*Echoes the event name
applicationReason always carries the human-readable detail — read it on any rejection or need-information event.

Error Handling#

A 4xx or 5xx from your endpoint, or no response within 30 seconds, is a failed delivery. The payload is not altered between attempts — the envelope id stays the same, which is what makes deduplication reliable.
Your responseResult
2xxDelivered. No retry
4xx / 5xxRetried on the schedule above
Timeout (>30s)Retried on the schedule above
5 failed attemptsEvent marked Failed. Not retried
50 consecutive failuresSubscription deactivated
Modified at 2026-08-23 12:07:29
Previous
Exchange Webhooks
Built with