ZapAPI Docs
Get StartedConceptsAI GatewayGuidesPayment GatewaySDKAPI ReferenceResources

Quickstart

Accept your first Lightning payment in under 5 minutes. Create an account, get an API key, create an invoice and handle the paid webhook.

This guide walks you from zero to your first successful Lightning payment with the ZapAPI REST API. You will create an account, get an API key, create an invoice, and receive a webhook when it is paid.

Prefer TypeScript?

The official SDK wraps everything below with full types: npm install @zapapi/sdk. See the TypeScript SDK guide. This page uses curl so it works for any language.

1. Create an account

Sign up through the API. You'll receive an access token used to authenticate subsequent requests.

Register
curl -X POST https://api.zapapi.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@example.com",
    "password": "a-strong-password",
    "name": "Your Name"
  }'

2. Get an API key

For server-to-server integrations, create an API key from the dashboard or the API Keys endpoint, then send it as a bearer token. Keys are prefixed zap_live_ (production) or zap_test_ (test mode).

Authenticated request
curl https://api.zapapi.com/api/v1/users/me \
  -H "Authorization: Bearer zap_live_your_key_here"

Keep secret keys on your server

Never expose secret keys in client-side code, mobile apps, or version control. Use environment variables and a secrets manager in production.

Account security

Enable two-factor authentication (TOTP) from Dashboard → Settings → Security. With 2FA on, password logins return a short-lived challenge — complete them via POST /api/v1/auth/2fa/verify. API keys are unaffected (they're already scoped secrets).

3. Choose where payments settle

Every project has a settlement wallet — where its payments land. From Dashboard → your project → Settlement Wallet you can pick:

  • My default wallet — your main ZapAPI wallet (the default)
  • Dedicated project wallet — a separate wallet just for this project
  • One of my wallets — any wallet on your account
  • My own wallet (NWC) — your own external wallet (Alby Hub, coinos, Umbrel…) via Nostr Wallet Connect — fully non-custodial

Nothing to configure for a first test: the default wallet settles until you change it. Invoices never require a provider id.

4. Create your first invoice

Invoices are the core primitive for accepting a one-time Lightning payment. When your API key is created inside a project, it is project-scoped — the request needs nothing but an amount and a description:

Create an invoice
curl -X POST https://api.zapapi.com/api/v1/invoices \
  -H "Authorization: Bearer zap_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "sat",
    "description": "My first payment"
  }'

With an account-level key, pass the project explicitly: "projectId": "uuid-of-your-project" (visible under Dashboard → Projects → Project details).

Every response is wrapped in a standard envelope — the invoice object lives under data:

Response envelope
{
  "status": "success",
  "statusCode": 201,
  "message": "Request successful",
  "data": {
    "id": "inv_8f3…",
    "status": "pending",
    "paymentRequest": "lnbc10n1p…"
  },
  "timestamp": "2026-10-24T00:00:00.000Z",
  "path": "/api/v1/invoices"
}

data.paymentRequest is the BOLT-11 payment request you can render as a QR code or a lightning: link for the payer.

5. Handle the paid webhook

Subscribe to the invoice.paid event so your backend is notified the moment a payment settles. Deliveries are signed — always verify the signature before fulfilling an order.

Express webhook handler
import express from 'express';
import { ZapAPI } from '@zapapi/sdk';

const app = express();

app.post(
  '/webhooks/zapapi',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const ok = ZapAPI.webhooks.verify(
      req.body.toString(),
      req.headers['x-zapapi-signature'] as string,
      process.env.ZAPAPI_WEBHOOK_SECRET!,
    );
    if (!ok) return res.sendStatus(400);

    const event = JSON.parse(req.body.toString());
    if (event.type === 'invoice.paid') {
      // Fulfill the order — event.data.paymentHash, event.data.preimage
    }
    res.json({ received: true });
  },
);

See the Webhooks concept page for retries, replay and signature verification, and the Webhook endpoints reference for the API surface.

What's next

On this page