Documentation Index
Fetch the complete documentation index at: https://docs.leokit.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
LeoKit webhooks push real-time event notifications to your server as swaps progress through their lifecycle. Discord and Slack webhook URLs are auto-detected and receive formatted embeds/blocks instead of raw JSON.
Supported Events
| Event | Description | When it fires |
|---|
quote.created | A quote was requested | After /leokit/quote responds and the quote is saved |
deposit.initiated | A deposit was built | After /leokit/deposit returns transaction data |
swap.pending | Transaction submitted | After /leokit/save-transaction records the tx hash |
swap.success | Swap completed | Status polling detects completion |
swap.failed | Swap failed | Status polling detects failure |
swap.refunded | Swap refunded | Status polling detects refund |
Webhook Types
| Type | Auto-detected | Payload format | Signing |
|---|
standard | Default | Raw JSON | HMAC-SHA256 |
discord | discord.com / discordapp.com URLs | Discord embed | None |
slack | hooks.slack.com URLs | Slack Block Kit | None |
POST /leokit/webhooks
Register a new webhook endpoint.
Authentication
Requires Api-Key header.
Request Body
{
"url": "https://your-server.com/webhooks/leokit",
"events": ["swap.success", "swap.failed", "swap.refunded"],
"type": "standard"
}
| Field | Type | Required | Description |
|---|
url | string | Yes | HTTPS endpoint URL. Discord/Slack URLs are auto-detected. |
events | string[] | No | Events to subscribe to. Defaults to all 6 events. |
type | string | No | standard, discord, or slack. Auto-detected from URL if omitted. |
Response
Status Code: 200 OK
{
"data": {
"id": "01953c9a-...",
"url": "https://your-server.com/webhooks/leokit",
"events": ["swap.success", "swap.failed", "swap.refunded"],
"type": "standard",
"is_active": true,
"created_at": "2026-02-07T12:00:00.000Z",
"secret": "a1b2c3d4e5f6..."
}
}
Important: The secret is only returned on creation. Save it immediately — you’ll need it to verify webhook signatures.
GET /leokit/webhooks
List all webhooks for the authenticated client.
Authentication
Requires Api-Key header.
Response
{
"data": {
"webhooks": [
{
"id": "01953c9a-...",
"url": "https://your-server.com/webhooks/leokit",
"events": ["swap.success", "swap.failed", "swap.refunded"],
"type": "standard",
"is_active": true,
"created_at": "2026-02-07T12:00:00.000Z",
"updated_at": "2026-02-07T12:00:00.000Z"
}
]
}
}
DELETE /leokit/webhooks?id=
Delete a webhook by ID.
Authentication
Requires Api-Key header.
Query Parameters
| Parameter | Type | Required | Description |
|---|
id | string | Yes | Webhook ID to delete |
Response
{
"data": {
"deleted": true
}
}
Webhook Payload (Standard)
Standard webhooks receive a JSON payload with HMAC-SHA256 signature headers.
| Header | Description |
|---|
X-LeoKit-Event | Event type (e.g., swap.success) |
X-LeoKit-Signature | HMAC-SHA256 signature: sha256=<hex> |
X-LeoKit-Delivery-ID | Unique delivery ID |
X-LeoKit-Timestamp | Unix timestamp (seconds) |
Body
{
"event": "swap.success",
"timestamp": "2026-02-07T12:30:00.000Z",
"data": {
"quote_id": "01953c9a-...",
"protocol": "chainflip",
"status": "completed",
"from_asset": "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"to_asset": "BTC.BTC",
"from_address": "0x1234...",
"to_address": "bc1q...",
"tx_hash": "0xabc...",
"scanner_url": "https://etherscan.io/tx/0xabc..."
}
}
Verifying Signatures
Compute HMAC-SHA256 of the raw request body using your webhook secret, then compare to the X-LeoKit-Signature header:
import crypto from "crypto";
function verifyWebhook(body, secret, signature) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
Delivery & Retry
- Timeout: 10 seconds per delivery attempt
- Max attempts: 5
- Backoff schedule: 30s, 1m, 5m, 15m, 1h
- Final state: Marked as
failed after 5 failed attempts
Deliveries are processed by a background worker on the leader instance.
Rate Limits
- Webhooks per client: 20 active webhooks max
- Events per webhook: No per-event rate limit; high-volume clients may see deliveries batched within the same backoff window
- TLS required:
url must be https:// (Discord/Slack URLs are also enforced as HTTPS)
Discord Webhooks
Discord webhook URLs (discord.com/api/webhooks/...) automatically receive formatted embed payloads with color-coded event types:
- Green:
swap.success
- Red:
swap.failed
- Yellow:
swap.refunded
- Blue:
quote.created, deposit.initiated, swap.pending
No signature verification — Discord handles authentication via the webhook URL secret.
Slack Webhooks
Slack incoming webhook URLs (hooks.slack.com/services/...) automatically receive Block Kit formatted payloads with header blocks, mrkdwn fields, and contextual metadata.
Examples
Register a Discord webhook
curl -X POST https://api.leokit.dev/leokit/webhooks \
-H "Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://discord.com/api/webhooks/123/abc"}'
Response will show "type": "discord" (auto-detected).
Register for specific events only
curl -X POST https://api.leokit.dev/leokit/webhooks \
-H "Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/hook",
"events": ["swap.success", "swap.failed"]
}'
List webhooks
curl https://api.leokit.dev/leokit/webhooks \
-H "Api-Key: YOUR_API_KEY"
Delete a webhook
curl -X DELETE "https://api.leokit.dev/leokit/webhooks?id=01953c9a-..." \
-H "Api-Key: YOUR_API_KEY"