Server API with scoped keys
Use the NervixPay v1 API from your backend: get a scoped bearer key, create payment links, read payments and handle errors.
The v1 API lets your backend or an AI agent read your account, manage payment links and read payments. It cannot move money, change receiving wallets or touch billing.
Get a key
Keys are issued through a browser-approved device flow, never typed into a form: your script asks for a key, you approve the displayed code while signed in at Integrations, and the script receives the key once. Keys are valid for 7 days and can be revoked at any time from Integrations. The full flow with commands is in AI agents and the device flow.
- Test mode keys create test drafts only: nothing a customer can pay. Use them while building.
- Live mode keys create real payment links and can manage the webhook. They need an explicit live approval in the browser.
- Store the key in a server-side secret store. Never ship it to a browser or commit it.
Scopes
| Scope | Allows |
|---|---|
merchant:read | GET /api/v1/merchant |
usage:read | GET /api/v1/usage |
payment_links:read | GET /api/v1/payment-links, optionally ?id=<uuid> |
payment_links:write | POST /api/v1/payment-links, PATCH /api/v1/payment-links/:id (includes read) |
payments:read | GET /api/v1/payments, GET /api/v1/payments/:id, POST /api/v1/payments/claim |
integrations:verify | GET /api/v1/verify: checks the key and lists what it can do |
webhooks:manage | GET, POST, DELETE /api/v1/webhook (writes need a live key) |
Ask only for the scopes you need. The full list: merchant:read, usage:read, payment_links:read, payment_links:write, payments:read, integrations:verify, webhooks:manage.
Step 1: Call the API with the bearer key
Terminal curl https://nervixpay.live/api/v1/merchant \ -H "Authorization: Bearer $NERVIXPAY_TOKEN"Response { "merchant": { "id": "8d0c6a1e-4f7b-4c1d-9a55-2f0e7c9b1a10", "name": "Example Shop", "walletAddress": "0x1111111111111111111111111111111111111111", "plan": "starter", "legacyPlan": null, "planExpiresAt": "2026-10-26T10:00:00.000Z", "onboardingCompleted": true, "blocked": false, "feeCredits": { "balanceUsd": 4.5, "feePerPaymentUsd": 0.5, "unpaidUsd": 0, "blocked": false } }, "credential": { "id": "5b7f2d0c-1e3a-4c8b-9d6e-0a1b2c3d4e5f", "clientName": "Shop backend", "mode": "live", "scopes": ["merchant:read", "payments:read"], "expiresAt": "2026-10-03T10:00:00.000Z" } }Step 2: Create a payment link
At most three prices, one per network (
polygon,ethereum,bnb).pricingMode: "usd"is allowed for the native coin only. The checkout URL ishttps://nervixpay.live/l/<id>.Terminal curl -X POST https://nervixpay.live/api/v1/payment-links \ -H "Authorization: Bearer $NERVIXPAY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "itemName": "Pro plan", "linkType": "share", "prices": [ { "network": "polygon", "currencyToken": "USDC", "amount": "25" }, { "network": "bnb", "currencyToken": "BNB", "amount": "25", "pricingMode": "usd" } ], "requiresCustomerLink": true }'Response (live key) { "paymentLink": { "id": "0f6d2c4e-8a1b-4e3f-9c7d-5b2a1e0f9d8c", "itemName": "Pro plan", "linkType": "share", "active": true, "createdAt": "2026-09-26T10:00:00.000Z", "redirectUrl": null, "requiresCustomerLink": true, "appearance": { "displayTitle": null, "description": null, "theme": "light", "displayMode": "card" }, "prices": [ { "network": "polygon", "currencyToken": "USDC", "amount": "25", "pricingMode": "fixed" }, { "network": "bnb", "currencyToken": "BNB", "amount": "25", "pricingMode": "usd" } ], "mode": "live" } }Step 3: Read payments
limitis 1 to 100 (default 20), newest first.amountReceivedis set once the order is paid.GET /api/v1/payments/:idreturns one payment with the same fields pluspriceUsdandusdRateSnapshot.Terminal curl "https://nervixpay.live/api/v1/payments?limit=20" \ -H "Authorization: Bearer $NERVIXPAY_TOKEN"Response { "items": [ { "id": "22222222-2222-4222-8222-222222222222", "itemName": "Pro plan", "network": "polygon", "amount": "25", "amountBaseUnits": "25000123", "amountReceived": "25.000123", "amountReceivedBaseUnits": "25000123", "currencyToken": "USDC", "status": "paid", "transactionHash": "0xabc0000000000000000000000000000000000000000000000000000000000001", "transactionId": "0xabc0000000000000000000000000000000000000000000000000000000000001", "transactionUrl": "https://polygonscan.com/tx/0xabc0000000000000000000000000000000000000000000000000000000000001", "recipientWallet": "0x1111111111111111111111111111111111111111", "paymentLinkId": "0f6d2c4e-8a1b-4e3f-9c7d-5b2a1e0f9d8c", "product": null, "customerReference": "user_42", "customerEmail": "buyer@example.com", "customerName": null, "originSite": "shop.example.com", "createdAt": "2026-09-26T10:01:00.000Z", "paidAt": "2026-09-26T10:02:10.000Z", "expiresAt": "2026-09-26T10:16:00.000Z" } ] }
Errors
Errors are JSON with a stable code:
{
"error": {
"code": "insufficient_scope",
"message": "This agent credential lacks the required scope."
}
}| Status | Codes | What to do |
|---|---|---|
| 400 | invalid_request, merchant_unavailable | Fix the request body or finish onboarding. |
| 401 | invalid_token, credential_not_found, token_expired, token_revoked | Get a new key through the device flow. Do not retry in a loop. |
| 403 | insufficient_scope, live_approval_required, merchant_blocked, merchant_not_verified | Request the missing scope or live approval, or complete verification. |
| 409 | invalid_request (product link) | Links that belong to a product can only be edited in Products. |
| 429 | rate_limited | Wait for the Retry-After seconds. |