Webhook events list
Kulipa produces event details that can be relayed to notify you about activities in your account.
Whenever an event occurs, Kulipa creates a new Event entity. A singular API call might lead to the inception of several events. For instance, blocking a card results in event like card.blocked.
By defining webhook endpoints in your Kulipa profile, you grant Kulipa the capability to autonomously dispatch Event entities via POST requests to the webhook endpoint anchored in your system.
Once your webhook endpoint receives the Event, your system can execute backend operations
(such as, sending a notification to the end user regarding payment with their card).
Event Entity
The Event entity dispatched to your webhook endpoint offers a snapshot of the altered entity.
List of events
Common event payload schema
These event fields will be present on any Kulipa event
{
eventTargetId: string, // uuid of the related object (e.g. card, cardAuthorization)
eventId: string, // uuid of the webhook event
eventName: string, // Event enum list below
// For user events and anything associated (cards, transactions, ...), a userId will also be provided.
userId: string // User associated with this event (format is `usr-<uuid>`)
}
cardAuthorization.confirmed
Occurs whenever a payment with a card is confirmed.
A hold is placed on the relevant funds, but the transaction is still not final.
Suggested use : Display a notification to the user about a pending payment or refund
Schema:
{
...Common event fields
cardId: string, // Card used in the payment
merchantName: string, // Merchant name
merchantMcc: string, // Merchant category code
amount: number, // decimal in currency units (e.g. 1.5, 108.62)
currency: string, // ISO 4217 currency codes
merchantAmount: string, // original transaction amount
merchantCurrency: string, // original transaction currency (ISO 4217)
merchant: {
name: string, // Merchant Name
city: string, // Merchant City
country: string, // Merchant Country
mcc: string, // Merchant Category Code
mid?: string, // Merchant ID (Optional)
},
type: 'payment' | 'refund',
fee: {
fx?: number, // Foreign exchange fee in 6 decimal places, i.e. 1,500,000 = 1.50 USD (Optional)
atm?: number, // ATM fee in 6 decimal places, i.e. 1,500,000 = 1.50 USD (Optional)
auth?: number, // Authorization fee in 6 decimal places, i.e. 1,500,000 = 1.50 USD (Optional)
},
decidedAt: string | undefined // Time of decision, YYYY-MM-DDTHH:mm:ss.sssZ
}
cardAuthorization.rejected
Occurs whenever a payment with a card is rejected.
Suggested use : Display a notification to the user
Schema:
{
...CommonEventFields,
cardId: string, // Card used in the payment
merchantName: string, // Merchant name
merchantMcc: string, // Merchant category code
amount: number, // decimal in currency units (e.g. 1.5, 108.62)
currency: string,// ISO 4217 currency codes
merchantAmount: string, // original transaction amount
merchantCurrency: string, // original transaction currency (ISO 4217)
merchant: {
name: string, // Merchant Name
city: string, // Merchant City
country: string, // Merchant Country
mcc: string, // Merchant Category Code
mid?: string, // Merchant ID (Optional)
},
type: 'payment' | 'refund'
fee: {
fx?: number, // Foreign exchange fee in 6 decimal places, i.e. 1,500,000 = 1.50 USD (Optional)
atm?: number, // ATM fee in 6 decimal places, i.e. 1,500,000 = 1.50 USD (Optional)
auth?: number, // Authorization fee in 6 decimal places, i.e. 1,500,000 = 1.50 USD (Optional)
},
declineReasonCode: 'insufficientFund' | 'failedControl' | 'notActive' | 'other', // Decline reason code,
decidedAt: string | undefined // Time of decision, YYYY-MM-DDTHH:mm:ss.sssZ
}
card.created
A card has been created for the user.
Suggested use : If a card was not created in the app recently, display a warning notification to the user.
Schema:
{
...CommonEventFields,
}
card.frozen
A user's card has been frozen.
Suggested use : If a card was not frozen in the app recently, display a warning notification to the user.
Schema:
{
...CommonEventFields,
}
card.unfrozen
A user's card has been unfrozen.
Suggested use : If a card was not unfrozen in the app recently, display a warning notification to the user.
Schema:
{
...CommonEventFields,
}
card.trackingNumberUpdated
A tracking number has been assigned to or changed on a physical card's shipment.
Suggested use : Display a notification to the user with the tracking number so they can track delivery.
Schema:
{
...CommonEventFields,
trackingNumber: string, // Carrier tracking number assigned to the shipment
requestedShippingMethod?: string, // Shipping method requested at card creation (Optional)
actualShippingMethod?: string, // Shipping method actually used (Optional)
}
user.created
A new user has been created in the system.
Suggested use : If this is not expected, escalate to your support team.
Schema:
{
...CommonEventFields,
}
user.phoneNumberSet
A phone number has been added to the user's account.
Suggested use : If this is not expected, escalate to your support team.
Schema:
{
...CommonEventFields,
phone: {
country: string, // User's phone number country prefix (for instance, +33)
number: string, // User's phone number, not including the country prefix
}, // Currently set phone number
}
kyc.created
A new KYC has been created.
Suggested use : Call Retrieve a KYC Process with the eventTargetId to obtain the access.url, then direct the user to that URL to begin their verification process.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: string, // KYC status
provider: string, // KYC provider name
referenceId: string, // Reference ID for the KYC
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'. Indicates the reason for the RFI request.
}
kyc.pending
A new KYC request has been created and is pending user input.
Suggested use : If this is not expected, escalate to your support team.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'pending',
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
kyc.completed
A KYC has been completed (filled) by a user. The meaning depends on the type field:
full(orlight): The user has submitted their identity verification. The KYC is pending review; the user status did not change from its previous one.shipping: The user has submitted their shipping address. The address is pending approval and processing; do not create a physical card untilkyc.completed(withtype: 'shipping') is received.
Suggested use : Do not attempt to re-enter the KYC form, inform the user they will receive a response soon.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'completed',
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
kyc.verified
The KYC has been verified (approved) successfully. The meaning depends on the type field:
full(orlight): The user's identity has been approved. The user can now create cards (both virtual and physical, subject to other preconditions).import: The user's imported KYC has been approved.shipping: The shipping address has been approved and the user entity has been updated with the new address. You may now create a physical card; it will be shipped to this address.
Note: User activation may be skipped even when the KYC is verified. Check userActivated to determine whether the user was actually activated. When userActivated is false, the userNotActivatedReason field provides the reason (e.g. a previous declined inquiry exists, or user details are incomplete).
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'verified',
userActivated: boolean, // Whether the user was activated as part of this verification
userNotActivatedReason?: string, // Reason activation was skipped, if applicable
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
kyc.declined
The user's KYC request has been declined. Depending on the payload, a follow-on KYC needs to happen, or the user simply
cannot open a Kulipa account at this time.
Suggested use : Display a notification to the user.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'declined',
declinedCode?: 'address' | 'dateofBirth' | 'name' | 'identity' | 'unknown' | 'prohibitedCountry' | 'phoneNumber',
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
kyc.failed
The user's KYC request has failed processing.
Suggested use : Contact Kulipa support.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'failed',
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
kyc.expired
The user's KYC request has expired and in order to proceed with it, it must be renewed.
Suggested use : Contact Kulipa support.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'expired',
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
kyc.revoked
The user's KYC request has been revoked. This means the KYC request has been closed prior to completion.
Suggested use : Contact Kulipa support.
Schema:
{
...CommonEventFields,
type: string, // KYC type, e.g. 'full', 'rfi'
status: 'revoked',
rfiSubtype?: 'onboarding' | 'transaction_monitoring' | 'additional_id' // Only present when type is 'rfi'
}
withdrawal.confirmed (prepaid accounts only)
The user's Withdrawal request has been confirmed. This means the withdrawal request has been completed successfully on-chain.
Suggested use : Display a notification to the user.
Schema:
{
...CommonEventFields,
blockHeight: number, // Block height at which the withdrawal was confirmed
rawTxReceipt: string, // Raw transaction receipt
hash: string // Transaction hash of the withdrawal confirmation transaction
}
withdrawal.rejected (prepaid accounts only)
The user's Withdrawal request has been rejected on-chain
Suggested use : Contact Kulipa support.
Schema:
{
...CommonEventFields,
reason: string, // Reason for rejection
hash: string | null // Transaction hash of the withdrawal
}
cardAuthentication.created
An OOB 3DS request has been sent - the user would need to respond to it in order to confirm the transaction.
3DS requests can be for payment verification, or card verification. In case of card verification, merchant amount and currency can be null.
(OOB 3DS is a second factor in-app authorization for online transactions)
Suggested use : Display a notification to the user asking them to confirm their transaction.
Schema:
{
...CommonEventFields,
userId: string, // User id
cardId: string, // Card id
walletId: string, // Wallet id
merchantName: string, // Merchant name
maskedPan: string, // Masked pan
merchantAmount: string, // merchant amount. This can be null
merchantCurrency: string, // merchant currency (ISO 4217). This can be null
walletAddress: string, // Wallet address
threedsRequestorAppUrl: string, // 3DS requestor app URL for deep-linking
}
cardTokenization.deliverActivationCode
The activation code generated by the Token Service Provider (TSP).
The code should be emailed or sent via sms to the end user to input into the Apply Pay or Google Pay validation screen.
Note: this event is only sent when a user manually enters their card details into the Digital Wallet and chooses to authenticate using either email or sms from the options provided.
How to consume : Send an email or sms containing the code to the end user.
Schema:
{
...CommonEventFields,
cardId: string, // Card id
consumerFacingEntityName: string, // can be null
digitalWalletName: string, // 'applePay' | 'googlePay'
activationMethod: string, // 'email' | 'sms'
activationCode: string, // Code required to activate the tokenization
emailAddress: string, // email address of the owner of the card. Only provided if activationMethod is 'email'
phone: {
country: string, // User's phone number country prefix (for instance, +33)
number: string, // User's phone number, not including the country prefix
}, // phone number of the owner of the card. Only provided if activationMethod is 'sms'
}
cardTokenization.activated
A card's token has been successfully activated.
This is sent for both manual provisioned and push provisioned tokens.
How to consume : Send a confirmation to the end user to inform them of the activation.
Schema:
{
...CommonEventFields,
cardId: string, // Card id
consumerFacingEntityName: string, // can be null
digitalWalletName: string, // 'applePay' | 'googlePay' | 'remoteCommercePrograms'
}
blockchainTransaction.confirmed
Occurs whenever a blockchain transaction is confirmed on-chain.
Suggested use : Display a notification to the user about a confirmed blockchain transaction or update your internal records.
Schema:
{
...CommonEventFields,
userId: string, // User id
walletId: string, // Wallet id
type: string, // type of transaction: "settlement" | "refund" | "deposit" | "transferOutOrApproval" | "withdraw"
blockNumber: number, // Block number
amount: number, // Amount in token's minor units (e.g. 6 decimals for USDC)
transactionHash: string, // hash of the transaction
}
card.revoked
A user's card has been revoked.
Suggested use : If a card was not revoked (cancelled) in the app recently, display a warning notification to the user.
user.revoked
The user's account has been permanently revoked.
Suggested use : Display a notification to the user that their account has been revoked. This is a terminal status — the account cannot be reactivated.
Schema:
{
...CommonEventFields,
"status": "revoked"
}
user.activated
The user's account has been activated.
Suggested use : Notify the user that their account is now active and they can begin using services.
Schema:
{
...CommonEventFields,
"status": "active"
}
user.frozen
The user's account has been frozen.
Suggested use : Display a notification to the user that their account has been temporarily frozen. They may need to contact support.
Schema:
{
...CommonEventFields,
"status": "frozen"
}
user.disabled
The user's account has been disabled.
Suggested use : Display a notification to the user that their account has been disabled.
Schema:
{
...CommonEventFields,
"status": "disabled"
}
user.unverified
The user's account has been moved to unverified status.
Suggested use : This event is provided for completeness but is never expected to fire for users.
Schema:
{
...CommonEventFields,
"status": "unverified"
}
user.deleted
The user's account has been deleted.
Suggested use : This kind of operation is usually done for technical reasons and the webhook typically should not be shown to the user.
Schema:
{
...CommonEventFields,
"status": "deleted"
}
user.shippingAddressUpdated
The user's shipping address has been successfully updated.
Suggested use : If using a shipping KYC to capture the shipping address, wait for this event to confirm
successful capture of the address, before creating a card.
Events without a user ID attached
webhookSubscription.created
A webhook subscription has been created in the system. This event is provided in order to alert in case this is not expected.
Suggested use : If this is not expected, escalate to your support team.
webhookSubscription.verified
A webhook subscription has been verified (activated) in the system. This event is provided in order to alert in case this is not expected.
Suggested use : If this is not expected, escalate to your support team.
webhookSubscription.deleted
A webhook subscription has been deleted in the system. This event is provided in order to alert in case this is not expected.
Suggested use : If this is not expected, escalate to your support team.
webhookSubscription.updated
A webhook subscription has been updated in the system. This event is provided in order to alert in case this is not expected.
Suggested use : If this is not expected, escalate to your support team.
webhookSubscription.disabled
A webhook subscription has been disabled in the system. This event is provided in order to alert in case this is not expected.
Suggested use : If this is not expected, escalate to your support team.
