Documentation Index
Fetch the complete documentation index at: https://docs.cryptomate.me/llms.txt
Use this file to discover all available pages before exploring further.
Overview
CryptoMate pushes real-time events to an HTTPS endpoint you register. Every event (card authorization, deposit, withdraw, transfer, ramp, KYC status change, and more) is sent as aPOST with a JSON envelope and an event-specific data payload.
All JSON field names use snake_case.
Setup
Expose an HTTPS endpoint
Host a publicly reachable HTTPS URL that accepts
POST requests with a JSON body.Register the URL
Configure the webhook URL on your company via the Subscribe webhook URL endpoint, or from the Portal.
Configure a webhook_key secret
Set a shared secret via the Subscribe webhook key endpoint. CryptoMate sends this value in the
X-Webhook-Key header on every request so your endpoint can authenticate it.Acknowledge quickly
Return
200 OK with the expected body as soon as possible. Heavy processing should happen asynchronously.Authentication
CryptoMate authenticates itself to your endpoint using a shared secret — yourwebhook_key.
On every request, CryptoMate sets:
| Header | Value |
|---|---|
X-Webhook-Key | Your webhook_key secret |
X-Request-Timestamp | Epoch milliseconds of when the request was sent |
Content-Type | application/json |
X-Webhook-Key header against the secret you stored when you configured it. Reject any request where the value does not match.
Rotate the key at any time via the Subscribe webhook key endpoint. CryptoMate uses the new value on the very next delivery.
Request envelope
Every webhook body has the same top-level shape:| Field | Type | Description |
|---|---|---|
product | string | One of treasury, virtual_wallets, cards, company_activity |
event_type | string | Specific event — see the catalog below |
operation_id | string | Unique identifier for this event. Use it for idempotent processing. |
status | string | One of pending, success, failed, canceled, time_canceled, manual_check |
data | object | Event-specific payload. Shape varies per event_type — see catalog. |
Example envelope
Expected response
Respond with HTTP200 OK and a JSON body:
200 status is treated as a delivery failure and triggers a retry (except on the card authorization path — see below).
Card external authorization response
Whenproduct=cards and event_type=authorization, the response_code you return determines whether the card transaction is approved or declined:
response_code | Meaning |
|---|---|
"00" or "SUCCESS" | Approve the transaction |
"05" | Decline — do not authorize |
| any other value | Passed through to the card network as the decline reason code (ISO 8583 response code) |
Delivery and retries
| Scenario | Timeout | Retries |
|---|---|---|
Card authorization (external authorization) | 1,200 ms hard deadline on the response | None — a missed deadline applies the card’s default behavior |
| Regular events (most webhooks) | 30 s HTTP timeout | Up to 10 attempts with exponential backoff (initial 1 s, multiplier 2x) |
Non-retriable informational events (e.g. notification_3ds_authorization) | 30 s | None |
- The authorization path uses a pre-warmed HTTP/2 client with TLS 1.3 and connection pooling — but the business deadline for your full response is 1,200 ms.
- CryptoMate may deliver the same event more than once (after retries, or following an internal redelivery). Always deduplicate using
operation_id. X-Request-Timestamplets you measure network skew and reject events that arrive well past their useful window.
Event catalog
Cards
Emitted withproduct: "cards".
authorization — external authorization request
Sent when a card transaction needs your approval before it is authorized by the network. Your response’s response_code drives the decision. Hard 1,200 ms deadline, no retries.
data additionally carries a signature field.
authorized — transaction authorized
Sent after a transaction has been approved and is being processed internally. No approval decision required.
cleared — transaction cleared
Sent when a previously authorized transaction clears (settles). Same data shape as authorized.
declined — transaction declined
Sent when a transaction is declined by the network or by CryptoMate. data shape as authorized, with decline_reason populated:
reversal — authorization reversed
Sent when a prior authorization is reversed (released) by the network. Same data shape as authorized.
refund — refund received
Sent when a merchant issues a refund. Same data shape as authorized.
deposit — card deposit credited
Sent when a deposit is credited to the card-linked wallet (after fees).
visa_direct_deposit — Visa Direct deposit credited
Sent when a Visa Direct push funds transfer credits the card. data mirrors the authorized transaction shape.
warranty_withdraw — warranty withdrawal
Sent on a warranty/holding-wallet withdrawal, success or failure (see status).
card_blocked_by_velocity — card blocked by velocity rule
Sent exactly once when a card transitions from ACTIVE to BLOCKED because a velocity rule was triggered. Indicates a possible fraud attempt or card probing. Up to 10 retries with exponential backoff.
data field | Type | Description |
|---|---|---|
card_id | uuid | Internal identifier of the blocked card |
company_id | uuid | Company that owns the card |
blocked_at | ISO 8601 (UTC) | Exact moment the card was blocked on the server |
triggered_rule.max_authorizations | integer | Maximum approved authorizations the rule allowed |
triggered_rule.time_window_seconds | integer | Sliding time window the rule applied to |
last_authorization_id | string | null | lifecycleEventId of the authorization that triggered the rule. May be null. |
operation_idequalscard_idbecause the block is not tied to a specific transaction.- Subsequent authorizations on an already-blocked card do not emit another
card_blocked_by_velocity— they are declined via the normal card status flow. - Use the tuple
(company_id, card_id, blocked_at)as an idempotency key in your handler. - To unblock the card, call
PATCH /api/cards/{id}/unblock. Unblocking also resets the velocity counter.
- Notify the cardholder by email or SMS.
- Optionally block other cards linked to the same user in your system.
- Open a case in your fraud management system for investigation.
notification_3ds_authorization — 3DS challenge code
Informational event containing the code the cardholder needs for a 3DS challenge. No retry, no approval decision.
Virtual Wallets
Emitted withproduct: "virtual_wallets".
deposit — on-chain deposit detected
withdraw — withdrawal executed
Sent on both success and failure (see status). reason is populated on failures.
ramp_on — fiat-to-crypto ramp credited
Sent when a fiat deposit has been converted to crypto and credited to the customer’s wallet.
Treasury
Emitted withproduct: "treasury".
transfer — treasury transfer executed
Sent on both success and failure (see status).
ramp_on — fiat-to-crypto ramp credited
Same shape as the Virtual Wallets ramp_on event, with product: "treasury".
Company Activity
Emitted withproduct: "company_activity".
client_status — customer KYC status changed
Sent when a company client’s KYC/KYB status changes (for example, rejected by the ramp provider). status is failed when the client is rejected; data is the full client record with status, rejection_code and rejection_description populated.
data object carries the full CompanyClient record; additional fields (address, document type, business fields, etc.) are included when present.
