Kaskade Pay API
The Kaskade Pay API lets you accept and send cryptocurrency from your own app or backend. Price in USD, let customers pay in 300+ coins, reconcile with signed webhooks, and pay out to external wallets — all behind one stable, JSON-over-HTTPS contract.
Quick start →
Your first payment in two requests.
Authentication →
Bearer keys or HMAC request signing.
API routes →
Payments, invoices, balances, payouts.
Webhooks →
Real-time, signed settlement events.
Postman →
Import the collection and start calling.
Stability →
Why your integration never breaks.
Infrastructure & stability
Kaskade Pay is a contract-first API. The endpoints, fields and webhook events on this page are the product — the settlement engine behind them is an implementation detail that you never touch. Your keys are Kaskade Pay keys, your objects are Kaskade Pay objects, and your webhooks are signed with your Kaskade Pay secret.
That separation is deliberate. Today settlement runs on a third-party custody provider; as volume grows we move to self-custody on an MPC platform (e.g. Fireblocks-class infrastructure) with our own on-chain wallets, treasury and payout signing. None of that changes a single request you make.The base URL, authentication, payment object, statuses and webhook payloads are guaranteed stable across that migration.
| Field | Type | Required | Description |
|---|---|---|---|
Base URL & version | — | required | https://kaskade.com/api/v1 stays; breaking changes only ever ship under a new version prefix. |
Authentication | — | required | Bearer keys and HMAC signing are unaffected by backend changes. |
Object shapes | — | required | Existing fields are never removed or repurposed; we only add new optional fields. |
Webhook events | — | required | Event names, payload shape and signature scheme stay constant. |
Statuses | — | required | The payment status vocabulary is fixed (new states, if any, are additive). |
Base URL & environments
All endpoints are served over HTTPS from one versioned base URL. Plain HTTP is rejected.
https://kaskade.com/api/v1| Field | Type | Required | Description |
|---|---|---|---|
Content-Type | header | required | All request and response bodies are application/json. |
Amounts | number | optional | Fiat amounts are decimal USD. Crypto amounts are decimal in the coin's own unit. |
Timestamps | string | optional | ISO-8601 in UTC, e.g. 2026-06-20T12:34:56.000Z. |
IDs | string | optional | Opaque strings — never parse or assume a format. |
Versioning & changelog
The current version is v1, pinned in the URL path. We treat the following as backward-compatible and may ship them without a version bump:
- Adding new endpoints, optional request fields, or response fields.
- Adding new webhook event types or new enum values.
- Changing an endpoint's availability tag from Planned → Beta → Live.
Anything breaking (removing a field, changing a type) would only ship under a new prefix such as /api/v2, and v1 would keep running. Material changes are listed in the dashboard changelog.
Quick start
- Create an API key. In your dashboard, open Developers and create a key. Copy the secret — shown only once.
- Create a payment. POST a USD price and the coin to pay in; you get a deposit address and the exact crypto amount.
- Collect payment. Show the address (or our hosted page) to your customer.
- Fulfil on webhook. Act when you receive a
payment.updatedevent with statusfinished.
curl -X POST https://kaskade.com/api/v1/payments \
-H "Authorization: Bearer ks_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"priceUsd": 50,
"payCurrency": "btc",
"orderId": "ORDER-123",
"orderDescription": "Premium plan"
}'Authentication
Every request must be authenticated. Two schemes grant the same access — use whichever fits your stack.
- Bearer key — simplest; send your secret key in a header.
- Request signing (HMAC) — strongest; sign each request so the key is never transmitted.
Bearer keys
Pass your key (ks_live_…) in the Authorization header. x-api-key: ks_live_… is also accepted.
Authorization: Bearer ks_live_xxxRequest signing (HMAC)
Sign each request with your key's client secret; the secret never leaves your server. Enable a signing secret on any key in the dashboard — your Client ID is the key's Public ID.
| Field | Type | Required | Description |
|---|---|---|---|
X-Pharosgate-Client | string | required | Your Client ID (the key's Public ID). |
X-Pharosgate-Timestamp | string | required | ISO-8601 UTC time, within 5 minutes of server time (replay protection). |
X-Pharosgate-Signature | string | required | Base64 HMAC-SHA256 of the canonical string, keyed with your client secret. |
Build the canonical string by concatenating six parts in order, with no separators:
BOM + METHOD + fullURL + clientId + timestamp + rawBody| Field | Type | Required | Description |
|---|---|---|---|
BOM | constant | required | The Unicode byte-order mark . |
METHOD | string | required | Upper-case HTTP method, e.g. POST. |
fullURL | string | required | Full request URL as called, e.g. https://kaskade.com/api/v1/payments. |
clientId | string | required | Same as the X-Pharosgate-Client header. |
timestamp | string | required | Same as the X-Pharosgate-Timestamp header. |
rawBody | string | required | Exact JSON body; empty string "" for GET. |
import crypto from "crypto";
const clientId = "YOUR_CLIENT_ID"; // = your key's Public ID
const clientSecret = "pg_sk_xxx"; // shown once when you enable signing
const method = "POST";
const url = "https://kaskade.com/api/v1/payments"; // the full URL, exactly as called
const ts = new Date().toISOString();
const body = JSON.stringify({ priceUsd: 50, payCurrency: "btc", orderId: "ORDER-123" });
// canonical = BOM + METHOD + URL + clientId + timestamp + body
const canonical = "\ufeff" + method + url + clientId + ts + body;
const signature = crypto.createHmac("sha256", clientSecret)
.update(canonical, "utf8").digest("base64");
const res = await fetch(url, {
method,
headers: {
"Content-Type": "application/json",
"X-Pharosgate-Client": clientId,
"X-Pharosgate-Timestamp": ts,
"X-Pharosgate-Signature": signature,
},
body,
});Errors & status codes
Conventional HTTP status codes; errors carry a human-readable error message.
{ "error": "priceUsd (number) and payCurrency (string) are required" }| Code | Meaning |
|---|---|
200 | OK. |
400 | Bad request — invalid params or below the coin's minimum. |
401 | Unauthorized — missing, invalid, or unsigned credentials. |
404 | Not found — resource doesn't exist or isn't yours. |
409 | Conflict — idempotency key reused with a different body. |
429 | Too many requests — slow down (see rate limits). |
500 | Server error. |
502 | Upstream settlement error — safe to retry. |
Idempotency Planned
To safely retry POST requests without creating duplicates, send an Idempotency-Key header with a unique value (e.g. a UUID) per logical operation. We store the first response for 24 hours and replay it for any retry with the same key.
Idempotency-Key: 9f1c8a3e-1b2d-4c5f-8a90-abc123def456Reusing a key with a different body returns 409 Conflict. Until this ships, dedupe on your side using orderId (we surface it on the payment).
Pagination
List endpoints return the most recent items (currently up to 100, newest first). Cursor pagination via limit and starting_after is the committed contract and rolls out with the same response envelope:
{
"data": [ /* … items … */ ],
"has_more": true,
"next_cursor": "cmq7c0aa0000abc"
}Today, list responses return a plain array under a resource key (e.g. payments). The cursor envelope is additive and tagged Planned.
Rate limits
Limits protect the platform and are applied per API key. When exceeded you receive 429 Too Many Requests; back off and retry with jitter.
| Field | Type | Required | Description |
|---|---|---|---|
X-RateLimit-Limit | int | optional | Requests allowed in the current window. |
X-RateLimit-Remaining | int | optional | Requests left in the window. |
Retry-After | int | optional | Seconds to wait before retrying (on 429). |
Generous defaults suit normal checkout traffic. Need a higher limit for batch jobs? Talk to us.
Currencies
Prices are set in USD and converted at a live rate. Customers can pay in 300+ coins and tokens across major networks. Pass a coin's ticker as payCurrency when creating a payment; network-specific tickers select the chain.
List currencies
/currenciesLiveReturns the coins your account can accept, with display name and network. For a coin's live minimum payable amount, call Get a currency.
curl https://kaskade.com/api/v1/currencies \
-H "Authorization: Bearer ks_live_xxx"{
"currencies": [
{ "code": "btc", "name": "Bitcoin", "network": "bitcoin", "enabled": true },
{ "code": "usdttrc20", "name": "Tether (TRC-20)", "network": "tron", "enabled": true }
]
}Get a currency
/currencies/:codeLiveMetadata for a single coin, including the current minimum payable amount in USD (the same minimum enforced by Create a payment).
curl https://kaskade.com/api/v1/currencies/btc \
-H "Authorization: Bearer ks_live_xxx"{
"currency": { "code": "btc", "name": "Bitcoin", "network": "bitcoin", "minUsd": 18.92, "enabled": true }
}Rates
Get a live conversion estimate before creating a payment — useful to preview the crypto amount a customer will owe for a given USD price.
Estimate a rate
/rates/estimateLiveQuotes how much of currency equals a given USD amount at the current rate.
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | required | USD amount to convert. |
currency | string | required | Target coin ticker (e.g. btc). |
curl https://kaskade.com/api/v1/rates/estimate?amount=50¤cy=btc \
-H "Authorization: Bearer ks_live_xxx"{
"amountUsd": 50,
"currency": "btc",
"estimatedAmount": 0.00052471,
"rate": 95291.41
}Fees
Kaskade Pay charges a transparent percentage on successful payments. Your effective rate and fee mode (absorb vs. add-on) are configured per account in the dashboard.
Get fees
/feesLiveReturns the fee schedule that applies to your account.
curl https://kaskade.com/api/v1/fees \
-H "Authorization: Bearer ks_live_xxx"{
"platformFeePercent": 1.5,
"merchantExtraPercent": 0,
"feeMode": "absorb",
"currency": "USD"
}The payment object
A payment is a single request for funds — created in USD, paid in crypto.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | optional | Kaskade Pay payment id — use it to look the payment up later. |
status | string | optional | Current state. See statuses. |
priceUsd | number | optional | Amount charged, in USD. |
payCurrency | string | optional | Coin the customer pays in. |
payAmount | number | optional | Exact crypto amount due. |
payAddress | string | optional | Deposit address to show the customer. |
payInHash | string | null | optional | On-chain deposit transaction hash, once detected. |
actuallyPaid | number | optional | Amount received so far (handles underpayment). |
orderId | string | null | optional | Your reference, echoed back. |
expiresAt | string | null | optional | When the quote/address expires. |
createdAt | string | optional | ISO-8601 creation time. |
Payment statuses
| Status | Meaning |
|---|---|
waiting | Created; awaiting the customer's funds. |
confirming | Deposit seen on-chain; awaiting confirmations. |
confirmed | Confirmed on-chain; settling. |
sending | Funds routing to settlement. |
partially_paid | Underpaid; remainder still pending. |
finished | Settled. Fulfil the order here. |
failed | Payment failed. |
refunded | Payment refunded. |
expired | No funds before the quote expired. |
Create a payment
/paymentsLiveCreates a payment priced in USD and returns a deposit address and the exact crypto amount.
| Field | Type | Required | Description |
|---|---|---|---|
priceUsd | number | required | USD amount to charge. Must meet the coin's minimum. |
payCurrency | string | required | Coin to pay in (btc, eth, usdttrc20, usdc…). |
orderId | string | optional | Your order reference (≤ 200 chars). Echoed back and in webhooks. |
orderDescription | string | optional | Human-readable description (≤ 500 chars). |
curl -X POST https://kaskade.com/api/v1/payments \
-H "Authorization: Bearer ks_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"priceUsd": 50,
"payCurrency": "btc",
"orderId": "ORDER-123",
"orderDescription": "Premium plan"
}'{
"payment": {
"id": "cmq7c1ab0000xyz",
"npPaymentId": "4912345678",
"priceUsd": 50,
"payCurrency": "btc",
"payAmount": 0.00052471,
"payAddress": "bc1qexampleaddressxxxxxxxxxxxxxxxxxxxx",
"status": "waiting",
"expiresAt": "2026-06-20T12:34:56.000Z"
}
}List payments
/paymentsLiveReturns your most recent payments (up to 100), newest first.
curl https://kaskade.com/api/v1/payments \
-H "Authorization: Bearer ks_live_xxx"{
"payments": [
{ "id": "cmq7c1ab0000xyz", "status": "finished", "priceAmount": 50, "payCurrency": "btc", "payInHash": "f4a1…", "createdAt": "2026-06-20T12:00:00.000Z" },
{ "id": "cmq7c0aa0000abc", "status": "waiting", "priceAmount": 25, "payCurrency": "usdttrc20", "createdAt": "2026-06-20T11:40:00.000Z" }
]
}Retrieve a payment
/payments/:idLiveFetches one payment by id and refreshes its status live before returning, so it always reflects the latest on-chain state.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | required | The payment id from Create a payment. |
curl https://kaskade.com/api/v1/payments/cmq7c1ab0000xyz \
-H "Authorization: Bearer ks_live_xxx"{
"payment": {
"id": "cmq7c1ab0000xyz",
"status": "finished",
"priceAmount": 50,
"payCurrency": "btc",
"payAmount": 0.00052471,
"actuallyPaid": 0.00052471,
"payAddress": "bc1qexampleaddressxxxxxxxxxxxxxxxxxxxx",
"payInHash": "f4a1c9b2…",
"createdAt": "2026-06-20T12:00:00.000Z"
}
}The invoice object Live
An invoice is a hosted, shareable request for payment. It produces a checkout URL your customer opens to pay in any supported coin, and emits the same payment.updated webhooks under the hood.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | optional | Invoice id. |
status | string | optional | draft | open | paid | expired | void. |
amountUsd | number | optional | Amount requested, in USD. |
url | string | optional | Hosted checkout URL to share with the customer. |
orderId | string | null | optional | Your reference. |
customerEmail | string | null | optional | Optional; receipt is emailed here. |
paymentId | string | null | optional | Linked payment once the customer pays. |
expiresAt | string | null | optional | When the invoice expires. |
createdAt | string | optional | ISO-8601 creation time. |
Create an invoice
/invoicesLiveCreates a hosted invoice and returns a shareable checkout URL.
| Field | Type | Required | Description |
|---|---|---|---|
amountUsd | number | required | USD amount to request. |
orderId | string | optional | Your order reference. |
orderDescription | string | optional | Shown on the checkout page. |
customerEmail | string | optional | Emails a receipt and reminders. |
payCurrency | string | optional | Lock to one coin; omit to let the customer choose. |
curl -X POST https://kaskade.com/api/v1/invoices \
-H "Authorization: Bearer ks_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "amountUsd": 120, "orderId": "INV-2026-014", "customerEmail": "buyer@example.com" }'{
"invoice": {
"id": "inv_8f2a1c",
"status": "open",
"amountUsd": 120,
"url": "https://kaskade.com/i/8f2a1c",
"orderId": "INV-2026-014",
"customerEmail": "buyer@example.com",
"expiresAt": "2026-06-21T12:00:00.000Z",
"createdAt": "2026-06-20T12:00:00.000Z"
}
}List invoices
/invoicesLiveReturns your invoices, newest first.
curl https://kaskade.com/api/v1/invoices \
-H "Authorization: Bearer ks_live_xxx"Retrieve an invoice
/invoices/:idLiveFetch one invoice; its status reconciles from the linked payment before returning.
curl https://kaskade.com/api/v1/invoices/inv_8f2a1c \
-H "Authorization: Bearer ks_live_xxx"Get balances
/balanceLiveReturns your available balance per coin.
curl https://kaskade.com/api/v1/balance \
-H "Authorization: Bearer ks_live_xxx"{
"balances": {
"btc": 0.01340000,
"usdttrc20": 250.50
}
}Wallet addresses Planned
/wallets/addressesPlanned| Field | Type | Required | Description |
|---|---|---|---|
currency | string | required | Coin/network for the address. |
label | string | optional | Your reference for attribution (e.g. user id). |
curl -X POST https://kaskade.com/api/v1/wallets/addresses \
-H "Authorization: Bearer ks_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "currency": "usdttrc20", "label": "user_4821" }'{
"address": {
"id": "addr_19be4",
"currency": "usdttrc20",
"address": "TXexampleaddressxxxxxxxxxxxxxxxxxxx",
"label": "user_4821",
"createdAt": "2026-06-20T12:00:00.000Z"
}
}The payout object Planned
A payout sends crypto from your balance to an external wallet. In self-custody mode these are signed by Kaskade Pay's own treasury; under thresholds they auto-sign, above them they await approval.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | optional | Payout id. |
status | string | optional | pending | approved | sent | failed. |
currency | string | optional | Coin/network sent. |
amount | number | optional | Crypto amount sent. |
address | string | optional | Destination wallet address. |
txHash | string | null | optional | On-chain transaction hash once broadcast. |
orderId | string | null | optional | Your reference. |
createdAt | string | optional | ISO-8601 creation time. |
Create a payout
/payoutsPlanned| Field | Type | Required | Description |
|---|---|---|---|
currency | string | required | Coin/network to send. |
amount | number | required | Crypto amount to send. |
address | string | required | Destination wallet address. |
orderId | string | optional | Your reference for reconciliation. |
curl -X POST https://kaskade.com/api/v1/payouts \
-H "Authorization: Bearer ks_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9f1c8a3e-1b2d-4c5f-8a90-abc123def456" \
-d '{ "currency": "usdttrc20", "amount": 100, "address": "TXdest…", "orderId": "WD-771" }'{
"payout": {
"id": "po_5c1a9d",
"status": "pending",
"currency": "usdttrc20",
"amount": 100,
"address": "TXdest…",
"orderId": "WD-771",
"createdAt": "2026-06-20T12:00:00.000Z"
}
}List payouts
/payoutsPlannedcurl https://kaskade.com/api/v1/payouts \
-H "Authorization: Bearer ks_live_xxx"Webhooks
Set a webhook URL in your dashboard; we POST an event every time a payment changes status. This is the reliable way to know when to fulfil — never rely on the customer's browser returning.
{
"event": "payment.updated",
"payment": {
"id": "cmq7c1ab0000xyz",
"status": "finished",
"orderId": "ORDER-123",
"priceAmount": 50,
"payCurrency": "btc",
"payInHash": "f4a1c9b2…"
}
}Event types
| Event | When | |
|---|---|---|
payment.updated | A payment changes status (incl. finished). | Live |
invoice.paid | A hosted invoice is fully paid. | Live |
payout.updated | A payout changes status (sent/failed). | Planned |
All events share the same envelope (event + resource object) and the same signature scheme, so one handler covers them all.
Verifying signatures
Each delivery carries an x-kaskade-signature header — HMAC-SHA256 (hex) of the raw request body, keyed with your webhook signing secret. Always verify before trusting the event.
import crypto from "crypto";
// Express raw-body handler for POST /webhooks/kaskade
app.post("/webhooks/kaskade", (req, res) => {
const signature = req.headers["x-kaskade-signature"];
const expected = crypto
.createHmac("sha256", process.env.KASKADE_WEBHOOK_SECRET)
.update(req.rawBody) // the exact bytes we sent
.digest("hex");
if (signature !== expected) return res.status(401).end();
const { event, payment } = JSON.parse(req.rawBody);
if (payment.status === "finished") {
// ✅ fulfil the order (idempotently)
}
res.status(200).end();
});Delivery & retries
payment.id + status).Official SDKs Planned
Thin, typed clients that wrap auth (including request signing) and every endpoint on this page. Until they ship, the code examples below are copy-paste ready in any language — the API is plain HTTPS + JSON.
| Field | Type | Required | Description |
|---|---|---|---|
Node.js | npm | optional | npm i @kaskade/sdk |
PHP | composer | optional | composer require kaskade/sdk |
Python | pip | optional | pip install kaskade |
Postman collection
Import the collection to call every endpoint with your key pre-wired. It includes a baseUrl variable and an apiKey variable — set them once and go.
In Postman: Import → Upload Files → select the file, then set the collection variables baseUrl and apiKey.
Code examples
Create a payment
curl -X POST https://kaskade.com/api/v1/payments \
-H "Authorization: Bearer ks_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"priceUsd": 50,
"payCurrency": "btc",
"orderId": "ORDER-123",
"orderDescription": "Premium plan"
}'Authenticate with request signing
import crypto from "crypto";
const clientId = "YOUR_CLIENT_ID"; // = your key's Public ID
const clientSecret = "pg_sk_xxx"; // shown once when you enable signing
const method = "POST";
const url = "https://kaskade.com/api/v1/payments"; // the full URL, exactly as called
const ts = new Date().toISOString();
const body = JSON.stringify({ priceUsd: 50, payCurrency: "btc", orderId: "ORDER-123" });
// canonical = BOM + METHOD + URL + clientId + timestamp + body
const canonical = "\ufeff" + method + url + clientId + ts + body;
const signature = crypto.createHmac("sha256", clientSecret)
.update(canonical, "utf8").digest("base64");
const res = await fetch(url, {
method,
headers: {
"Content-Type": "application/json",
"X-Pharosgate-Client": clientId,
"X-Pharosgate-Timestamp": ts,
"X-Pharosgate-Signature": signature,
},
body,
});Verify a webhook
import crypto from "crypto";
// Express raw-body handler for POST /webhooks/kaskade
app.post("/webhooks/kaskade", (req, res) => {
const signature = req.headers["x-kaskade-signature"];
const expected = crypto
.createHmac("sha256", process.env.KASKADE_WEBHOOK_SECRET)
.update(req.rawBody) // the exact bytes we sent
.digest("hex");
if (signature !== expected) return res.status(401).end();
const { event, payment } = JSON.parse(req.rawBody);
if (payment.status === "finished") {
// ✅ fulfil the order (idempotently)
}
res.status(200).end();
});Integration options
There's more than one way to accept crypto with Kaskade Pay — from sharing a link in seconds to wiring the full API into your platform. Pick the lightest option that meets your need; you can mix them, and they all settle to the same account and emit the same webhooks.
| Option | Best for | Effort |
|---|---|---|
| Hosted invoice | One-off bills, freelancers, "send me a payment link" | No code |
| Payment links & buttons | A fixed-price product or donate/checkout button on any site | Copy-paste |
| POS terminal | Taking crypto in person at a counter | No code |
| Donations | Tips, fundraising, "pay what you want" | No code |
| Subscriptions | Recurring/membership billing | Low code |
| REST API + webhooks | Custom checkout, marketplaces, full control | Developer |
| Platform plugins | WooCommerce, WHMCS and other off-the-shelf stores | Install |
Plugins & platforms
Drop-in plugins let popular platforms accept crypto through Kaskade Pay without custom code. Packaged plugins are rolling out; in the meantime every platform below can be wired up in minutes with the Create a payment endpoint and a webhook.
WooCommerce Planned
For WordPress + WooCommerce stores. The official gateway plugin (Planned) adds "Pay with crypto" at checkout, redirects the shopper to a hosted invoice, and marks the order paid on the invoice.paid webhook. Until it ships, integrate with a few lines in your theme or a small custom gateway:
- Create an API key and set it in your server config (never in client JS).
- On order placement, call
POST /invoiceswith the order total asamountUsdand the WooCommerce order id asorderId. - Redirect the customer to the returned invoice
url. - On the
invoice.paidwebhook (verify the signature), mark the matching order complete.
WHMCS Planned
For hosting and SaaS billing on WHMCS. The official payment-gateway module (Planned) registers Kaskade Pay as a gateway so invoices can be paid in crypto and auto-reconciled. Manual integration mirrors WooCommerce: create a Kaskade Pay invoice from the WHMCS invoice, send the client to the hosted checkout, and apply the payment when invoice.paid arrives (map by orderId = WHMCS invoice id).
Team & multi-user access
Most teams need more than one person — or service — touching the gateway. Here's how access works today and what's coming.
API keys as machine identities Live
Create a separate API key for each app, environment or service that talks to Kaskade Pay. Keys are independent — name them ("production server", "staging", "billing worker"), rotate or revoke any one instantly without affecting the others, and enable request signing per key. This is the practical way to give each part of your stack its own credential and audit trail.
Team seats & roles Planned
Inviting teammates to the dashboard with roles — owner, admin, developer(keys & webhooks), and viewer (read-only reporting) — is on the roadmap. The committed model: one account owns the merchant, members are invited by email, and each role scopes what they can see and do. Until then, keep the account owner's login limited and use per-service API keys for automation.
Export transaction history
Pull your payments for bookkeeping, reconciliation or accounting in two ways.
From the dashboard (CSV) Live
Open Payment history and click Export CSV to download your full payment history as a spreadsheet-ready file. Columns:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | optional | Kaskade Pay payment id. |
created_at | string | optional | ISO-8601 creation time (UTC). |
status | string | optional | Final or current status. |
price_usd | number | optional | Amount charged in USD. |
pay_currency | string | optional | Coin paid. |
pay_amount | number | optional | Crypto amount due. |
actually_paid | number | optional | Crypto amount received. |
order_id | string | optional | Your order reference. |
deposit_tx_hash | string | optional | On-chain deposit TXID, if any. |
provider_payment_id | string | optional | Internal settlement reference. |
Via the API Live
For automated exports or syncing to your own ledger, page through List paymentsand persist what you need. Combine with webhooks to keep your records live instead of polling.
curl https://kaskade.com/api/v1/payments \
-H "Authorization: Bearer ks_live_xxx"Migrating & support
Already integrated with another crypto gateway? Kaskade Pay maps cleanly: a “create charge” becomes Create a payment, IPNs become webhooks, and your order reference rides along as orderId. Because the contract is provider-agnostic (see why), you integrate once and never re-migrate.
Stuck on something? Open a ticket from your dashboard or contact support.
FAQ
Do I need a separate key for signing?
No. Every API key can use Bearer auth, and you can additionally enable a signing secret on the same key.
What happens to my integration when you change crypto infrastructure?
Nothing. The contract on this page is stable across backend changes — see Infrastructure & stability.
How do I test without real money?
Create a small live payment (e.g. $5+) and pay it on-chain, or reach out for sandbox access.
Which status means “paid”?
finished. Fulfil orders on that webhook, idempotently.