Developers

Build billing in minutes, not weeks.

One REST API for GST-compliant invoices, customers, payments and webhooks. Native SDKs for Node and Python. Built for speed.

Quickstart

Live in 3 steps.

From sign-up to your first invoice in under five minutes.

1

Get your API key

Sign in to your dashboard and create a new secret key under Settings → API.

// Store your key in an environment variable
process.env.BILL21_API_KEY = "sk_live_••••••••";
2

Install the SDK

Pick your language. Or skip and call the REST API directly with cURL.

npm install @21bill/node
# or
yarn add @21bill/node
3

Send your first invoice

Create a GST-compliant invoice and email it to a customer in one call.

import Bill21 from "@21bill/node";
const bill = new Bill21(process.env.BILL21_API_KEY);

const invoice = await bill.invoices.create({
  customer_id: "cus_8h2k",
  items: [{ name: "Consulting", qty: 1, rate: 50000, gst: 18 }],
  send_email: true,
});

console.log(invoice.id, invoice.pdf_url);

API Reference

Endpoints, in plain English.

Every resource is a REST endpoint that returns predictable JSON. Authenticate with a bearer token. That's it.

Invoices

POST /v1/invoices

Create a GST-compliant invoice. Returns a signed PDF URL and IRN.

await bill.invoices.create({
  customer_id: "cus_8h2k",
  items: [{ name: "Design sprint", qty: 1, rate: 120000, gst: 18 }],
  due_date: "2025-05-01",
});
GET /v1/invoices/:id

Retrieve a single invoice by its ID.

const invoice = await bill.invoices.retrieve("inv_2k9f");
GET /v1/invoices

List invoices with filters: status, customer, date range.

const { data } = await bill.invoices.list({ status: "unpaid", limit: 50 });

Customers

POST /v1/customers

Create a customer with billing address and GSTIN.

await bill.customers.create({
  name: "Acme Pvt Ltd",
  email: "ap@acme.in",
  gstin: "29AAACB1234F1Z5",
});
GET /v1/customers/:id

Retrieve a customer with their full ledger summary.

const customer = await bill.customers.retrieve("cus_8h2k");

Payments

POST /v1/payments

Record a payment received against one or many invoices.

await bill.payments.create({
  invoice_id: "inv_2k9f",
  amount: 50000,
  method: "upi",
  reference: "UPI/REF/00123",
});
GET /v1/payments

List all payments, filterable by date or invoice.

const { data } = await bill.payments.list({ from: "2025-01-01" });

Webhooks

React to billing events in real time.

We sign every payload with HMAC-SHA256 so you can trust what hits your server. Subscribe to one or many event types.

invoice.createdinvoice.sentinvoice.paidinvoice.overduecustomer.createdpayment.receivedpayment.failed
// Express endpoint that verifies a 21bill signature
import crypto from "crypto";

app.post("/webhooks/21bill", (req, res) => {
  const sig = req.headers["x-21bill-signature"] as string;
  const expected = crypto
    .createHmac("sha256", process.env.BILL21_WEBHOOK_SECRET!)
    .update(JSON.stringify(req.body))
    .digest("hex");

  if (sig !== expected) return res.status(400).end();

  const event = req.body;
  if (event.type === "invoice.paid") {
    // mark order as paid
  }
  res.json({ received: true });
});

Ready to ship?

Grab a key and send your first invoice in under five minutes. Need help integrating? Our team replies within an hour.