Skip to main content
An invoice in Kibble is a formal billing document with line items, a due date, and a unique invoice number. When you create one, Kibble generates a PDF, emails it to your vendor, and provisions a deposit address to receive payment. Once your vendor sends USDC on Base, Kibble updates the invoice status and sends you a payment confirmation email. If you configure a webhook URL, Kibble also POSTs a signed payload to your server.

Invoice number format

Invoice numbers follow the format INV-XXXX where XXXX is a zero-padded counter that increments per merchant. Your first invoice is INV-0001, the second is INV-0002, and so on. The counter is tied to your merchant email, so it persists across CLI sessions and API calls.

Creating an invoice

Run npx create-kibble and select kibble invoice when prompted. The CLI walks you through each field in sequence.
◆  What do you want to do?
○  kibble charge   accept payments, generate links, track receivables
●  kibble invoice  create, send, and track invoices
You will be asked for your business address, the vendor’s name and email, line items, a due date, and where payments should land.

Invoice fields

Merchant fields

These fields identify you as the billing party and appear on the PDF.
FieldTypeRequiredDescription
merchant_emailstringYesYour email. Used to look up or create your merchant record.
merchant_namestringYesYour business name as it appears on the invoice.
merchant_addressstringYesYour business address.

Vendor fields

These fields identify the party being billed.
FieldTypeRequiredDescription
vendor_emailstringYesWhere the invoice email is sent.
vendor_namestringYesVendor or customer name on the PDF.
vendor_addressstringNoVendor address. Optional.

Line items

Each line item has three fields. You can include between 1 and 30 line items per invoice.
FieldTypeRequiredDescription
descriptionstringYesWhat the line item is for.
quantitynumberYesPositive number (e.g. 10 for 10 hours).
unit_pricestringYesUSDC amount per unit (e.g. "150.00").
The total for each line is quantity × unit_price. Kibble sums all line totals to produce the total_amount.

Dates and metadata

FieldTypeRequiredDescription
due_datestringYesISO date YYYY-MM-DD.
issue_datestringNoISO date YYYY-MM-DD. Defaults to today.
notesstringNoFree-text note printed at the bottom of the PDF.

Payment and automation

FieldTypeRequiredDescription
wallet_typestringYesprivy or byo.
wallet_addressstringIf byoYour USDC wallet address on Base.
webhook_urlstringNoURL to receive a signed POST when the invoice is paid.
send_nowbooleanNoSend the invoice email immediately. Defaults to true.

Downloading the PDF

The PDF is available at:
GET https://pay.kibble.sh/api/invoices/{invoice_id}/pdf
The invoice_id is returned when you create the invoice. The PDF is also attached to the email sent to your vendor.

Invoice statuses

Invoices move through a separate status lifecycle from payment links.
StatusMeaning
draftInvoice created but not yet emailed to the vendor.
sentInvoice emailed to the vendor. Awaiting payment.
paidReceived amount exactly matches the invoice total.
partialReceived amount is less than the invoice total.
excessReceived amount exceeds the invoice total.
An invoice moves from draft to sent automatically when you create it with send_now: true (the default). If you create with send_now: false, the invoice sits in draft until you trigger sending via the API.

Immutable fields

Invoice records are append-only for audit purposes. The following fields never change after creation, even if you update your merchant profile:
  • merchant_name_snapshot
  • merchant_address_snapshot
  • invoice_number
This ensures that a printed or downloaded PDF always matches the database record.

Webhooks

If you pass a webhook_url, Kibble POSTs a signed JSON payload to that URL when the invoice status changes to paid, partial, or excess.
{
  "invoice_id": "a1b2c3d4-...",
  "invoice_number": "INV-0001",
  "status": "paid",
  "tx_hash": "0x...",
  "paid_amount": "1550.00",
  "paid_at": "2026-05-15T10:23:45.000Z"
}
The request includes an X-Kibble-Signature header formatted as sha256={hex}. Verify it using the webhook_secret returned when you created the invoice. See Webhooks for verification details.