Authentication
API keys, bearer tokens, scopes, test vs live mode, and security best practices for authenticating with the ZapAPI REST API.
The ZapAPI API uses bearer-token authentication. Every request must
include an API key in the Authorization header:
Authorization: Bearer zap_live_your_key_hereKeys are scoped (per-project) and prefixed so you can tell at a glance what environment they belong to:
| Prefix | Environment | Behavior |
|---|---|---|
zap_live_ | Production | Creates real invoices, moves real sats. |
zap_test_ | Test mode | Creates test invoices, webhook events carry livemode: false. |
Creating an API key
Create keys from the dashboard (Settings → API Keys) or programmatically via the API Keys endpoints. Keys are shown once at creation time — store them immediately in a secrets manager.
curl -X POST https://api.zapapi.com/api/v1/api-keys \
-H "Authorization: Bearer <dashboard-jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "Production backend",
"projectId": "proj_…",
"scopes": ["invoices:write", "webhooks:write"]
}'The response contains the plaintext key exactly once:
{
"data": {
"id": "key_…",
"name": "Production backend",
"prefix": "zap_live_",
"key": "zap_live_51H7…" // ← shown ONCE, store immediately
}
}Scopes
Scopes limit what a key can do. Always grant the minimum scopes your integration needs:
| Scope | Allows |
|---|---|
invoices:read / invoices:write | Read / create / cancel invoices |
payment-links:read / payment-links:write | Read / manage payment links |
webhooks:read / webhooks:write | Read / manage webhook endpoints |
refunds:read / refunds:write | Read / create refunds |
customers:read / customers:write | Read / manage customers (CRM) |
wallet:read / wallet:write | Read balance / initiate withdrawals |
When a request is missing a scope, the API returns 403 Forbidden with a
machine-readable code you can branch on.
Test mode
Test keys behave identically to live keys, but nothing settles on mainnet:
- Invoice
paymentRequests are valid BOLT-11 strings on a regtest/signet-style network. - Webhook events carry
livemode: falseso your handler can distinguish them. - The TypeScript SDK exposes
zap.isTestModeas a convenience flag.
const zap = new ZapAPI('zap_test_…');
zap.isTestMode; // trueUse test mode for CI, local development and end-to-end tests — it is a fully functional sandbox, not a mock.
Rotating and revoking keys
Rotate keys on a schedule (e.g., quarterly) and immediately on any suspicion of leakage:
- Create a new key with the same scopes.
- Deploy the new key to your service.
- Revoke the old key from the dashboard or via
DELETE /api-keys/:id.
Revoking is immediate — in-flight requests with the old key will return
401 Unauthorized.
Security best practices
Never embed secret keys in client-side code
Secret keys must live on your server. For browser/mobile flows, use a backend proxy or short-lived, scoped tokens.
- Store keys in a secrets manager (AWS Secrets Manager, Doppler, 1Password Connect, Vercel env vars). Never commit them to git.
- Restrict by IP (optional) from the dashboard for server-to-server integrations.
- Use one key per service so you can rotate and audit independently.
- Enable 2FA on the dashboard account that owns the keys.
- Audit key usage regularly — every authenticated request is logged with the key id and IP.
Other authentication surfaces
The API also uses these for specific flows — you will not normally use them for server integrations:
- Dashboard JWT — short-lived session token for the web dashboard; used to call the API Keys, Team and Billing endpoints.
- LNURL-auth — passwordless sign-in for public pages (e.g., bio-link dashboards) using a Lightning wallet.
- NWC connection strings — delegated wallet access for NIP-47 clients.