Integrate Kaspa payments into your application with our simple REST API. Accept payments, create payment links, and receive webhook notifications.
Base URL
https://kaspay.vercel.appProtected endpoints require a JWT token in the Authorization header:
Authorization: Bearer your-jwt-token
Get your token by calling POST /api/auth/login or POST /api/auth/register.
/api/auth/registerCreate a new merchant account
Request Body
{
"email": "merchant@example.com",
"password": "securepassword",
"name": "My Store",
"kaspaAddress": "kaspa:qr..."
}Response
{
"user": { "id": "uuid", "email": "...", "name": "..." },
"token": "jwt-token"
}/api/auth/loginAuthenticate and get JWT token
Request Body
{
"email": "merchant@example.com",
"password": "securepassword"
}Response
{
"user": { "id": "uuid", "email": "...", "name": "..." },
"token": "jwt-token"
}/api/auth/meAuth RequiredGet your account details and API key
Response
{
"id": "uuid",
"email": "merchant@example.com",
"name": "My Store",
"kaspaAddress": "kaspa:qr...",
"apiKey": "your-api-key-uuid",
"paymentExpiry": 30
}/api/linksAuth RequiredCreate a new payment link. Supports KAS or USD currency (USD auto-converts at payment time).
Request Body
{
"title": "Premium Plan",
"description": "Monthly subscription",
"amount": 100,
"currency": "KAS",
"expiryMinutes": 30,
"status": "active",
"successMessage": "Thank you!",
"redirectUrl": "https://yoursite.com/thanks",
"linkExpiresIn": 10080
}Response
{
"id": "uuid",
"title": "Premium Plan",
"amount": "100.00000000",
"slug": "premium-plan-abc123",
"url": "https://kaspay.vercel.app/pay/premium-plan-abc123",
"status": "active",
"expiresAt": "2026-02-15T12:00:00.000Z"
}/api/linksAuth RequiredList all your payment links
Response
{
"data": [
{
"id": "uuid",
"title": "Premium Plan",
"amount": "100.00000000",
"currency": "KAS",
"slug": "premium-plan-abc123",
"status": "active",
"expiresAt": null,
"expiryMinutes": 30,
"createdAt": "2026-02-08T12:00:00.000Z"
}
]
}/api/links/:idAuth RequiredUpdate a payment link (e.g., publish a draft or deactivate a link)
Request Body
{
"status": "active"
}Response
{
"id": "uuid",
"status": "active"
}/api/paymentsCreate a payment session from a link. Public endpoint for customers.
Request Body
{
"paymentLinkSlug": "premium-plan-abc123",
"customerEmail": "customer@example.com",
"customerName": "John Doe",
"metadata": { "orderId": "12345" }
}Response
{
"id": "payment-uuid",
"kaspaAddress": "kaspa:qr...",
"amountExpected": "100.00000000",
"status": "pending",
"expiresAt": "2026-02-08T13:00:00.000Z"
}/api/payments/:id/statusPoll payment status. Checks Kaspa blockchain for balance and UTXOs in real-time.
Response
{
"id": "payment-uuid",
"status": "confirmed",
"amountReceived": 100,
"senderAddress": "kaspatest:qr...",
"txId": "kaspa-transaction-hash",
"confirmations": 1,
"confirmedAt": "2026-02-08T12:01:00.000Z"
}/api/paymentsAuth RequiredList all payments for your account with status and transaction details
Response
{
"data": [
{
"id": "uuid",
"amountExpected": "100.00000000",
"amountReceived": "100.00000000",
"status": "confirmed",
"txId": "kaspa-tx-hash...",
"senderAddress": "kaspatest:qr...",
"customerName": "John Doe",
"customerEmail": "customer@example.com",
"createdAt": "2026-02-08T12:00:00.000Z",
"confirmedAt": "2026-02-08T12:01:00.000Z"
}
]
}/api/webhooksAuth RequiredRegister a webhook endpoint for payment notifications
Request Body
{
"url": "https://your-server.com/webhook",
"events": ["payment.confirmed", "payment.expired"]
}Response
{
"id": "uuid",
"url": "https://your-server.com/webhook",
"events": ["payment.confirmed", "payment.expired"],
"secret": "webhook-signing-secret",
"isActive": true
}/api/webhooksAuth RequiredList all your registered webhooks
Response
{
"data": [
{
"id": "uuid",
"url": "https://your-server.com/webhook",
"events": ["payment.confirmed"],
"isActive": true,
"createdAt": "2026-02-08T12:00:00.000Z"
}
]
}/api/settingsAuth RequiredUpdate your account settings (payment timeout, wallet address)
Request Body
{
"paymentExpiry": 60,
"kaspaAddress": "kaspatest:qr..."
}Response
{
"paymentExpiry": 60,
"kaspaAddress": "kaspatest:qr..."
}/api/priceGet live KAS/USD price from CoinGecko (60-second cache)
Response
{
"price": 0.10,
"currency": "USD"
}/api/networkGet live Kaspa network statistics
Response
{
"blockCount": 12345678,
"headerCount": 12345678,
"difficulty": 1234567890123,
"virtualDaaScore": 87654321,
"networkName": "testnet-10"
}All endpoints return errors in a consistent format with appropriate HTTP status codes.
// 400 Bad Request - Invalid input
{ "error": "Invalid email format" }
// 401 Unauthorized - Missing or invalid token
{ "error": "Unauthorized" }
// 404 Not Found - Resource doesn't exist
{ "error": "Payment link not found" }
// 409 Conflict - Duplicate resource
{ "error": "Email already registered" }| Event | Description |
|---|---|
payment.confirmed | Fired when a payment is verified on the Kaspa blockchain |
payment.expired | Fired when a payment session times out without receiving funds |
* | Subscribe to all events |
Each webhook delivery includes an X-KasPay-Signature header containing an HMAC-SHA256 signature of the payload using your webhook secret.
// Verify webhook signature (Node.js)
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return signature === expected;
}Merchant creates a payment link
POST /api/links with amount and title
Customer opens the payment page
POST /api/payments creates a payment session with the merchant's Kaspa address
Customer sends KAS to the address
QR code and address displayed. Customer pays from any Kaspa wallet.
KasPay verifies on-chain
GET /api/payments/:id/status polls the Kaspa blockchain REST API for balance + UTXOs
Payment confirmed, webhook sent
Status updated to "confirmed", webhook delivered to merchant's endpoint with HMAC signature