Skip to main content
Call POST /api/invoices to create a USDC invoice. Kibble generates a line-item breakdown, calculates the total, renders a PDF, provisions a unique deposit address on Base, and — by default — emails the vendor a link to the hosted invoice page at https://pay.kibble.sh/i/{slug}. Optionally, you can suppress the email with send_now: false and trigger it later using POST /api/invoices/{id}/send.

Request

POST https://pay.kibble.sh/api/invoices
Content-Type: application/json

Body parameters

Merchant

merchant_email
string
required
Your email address as the billing merchant. Kibble uses this to identify your account and provision your managed wallet when wallet_type is "privy".
merchant_name
string
required
Your business name as it appears on the invoice.
merchant_address
string
required
Your business address as it appears on the invoice. This value is captured at creation time and cannot be changed after the invoice is created.

Vendor

vendor_email
string
required
The vendor’s email address. Kibble sends the invoice to this address (unless send_now is false).
vendor_name
string
required
The vendor’s name as it appears on the invoice.
vendor_address
string
The vendor’s address. Optional — displayed on the invoice if provided.

Line items

line_items
object[]
required
An array of between 1 and 30 line items. Each item contributes to the invoice total.

Dates

issue_date
string
The invoice issue date in YYYY-MM-DD format. Defaults to today if omitted.
due_date
string
required
The payment due date in YYYY-MM-DD format. Kibble uses this to compute the overdue field.

Wallet

wallet_type
string
required
How Kibble resolves your receiving wallet. Use "privy" for a Kibble-managed wallet or "byo" to supply your own address.
wallet_address
string
Required when wallet_type is "byo". Must be a valid EVM address in checksum format.

Options

notes
string
Optional free-text notes displayed at the bottom of the invoice (e.g. "Net 30").
webhook_url
string
A publicly reachable URL that Kibble will POST to when the invoice reaches paid, partial, or excess status. The request is signed with an HMAC secret — see Webhooks for verification details.
send_now
boolean
default:"true"
Set to false to create the invoice without emailing the vendor. Use POST /api/invoices/{id}/send to send the email when you are ready.

Example request

curl --request POST \
  --url https://pay.kibble.sh/api/invoices \
  --header 'Content-Type: application/json' \
  --data '{
    "merchant_email": "you@acme.com",
    "merchant_name": "Acme SaaS",
    "merchant_address": "123 Main St, San Francisco, CA 94105",
    "vendor_email": "vendor@example.com",
    "vendor_name": "Vendor Co",
    "vendor_address": "456 Market Ave, New York, NY 10001",
    "line_items": [
      {
        "description": "Consulting — April",
        "quantity": 10,
        "unit_price": "150.00"
      }
    ],
    "due_date": "2026-05-28",
    "notes": "Net 30",
    "wallet_type": "privy",
    "webhook_url": "https://your-app.com/webhooks/kibble",
    "send_now": true
  }'

Response

A successful request returns 201 Created with the following fields.
invoice_id
string
required
The UUID for this invoice. Use it in all subsequent API calls that reference this invoice.
invoice_number
string
required
A human-readable invoice identifier (e.g. "INV-0001"). Increments automatically for each new invoice.
slug
string
required
The short identifier used in the hosted invoice URL.
invoice_url
string
required
The hosted invoice page URL. Send this to your vendor so they can review the invoice and pay.
pdf_url
string
required
The URL to download the invoice as a PDF. See Download invoice PDF.
deposit_address
string
required
The on-chain USDC deposit address on Base where the vendor should send payment.
total_amount
string
required
The sum of all line item totals, in USDC (e.g. "1500.00").
sent_at
string
ISO 8601 timestamp of when the vendor email was sent. null if send_now was false.
webhook_secret
string
The HMAC secret used to sign webhook requests. Only present when you provided a webhook_url. Store this securely — you need it to verify incoming webhook signatures.

Example response

201
{
  "invoice_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "invoice_number": "INV-0001",
  "slug": "abc12345",
  "invoice_url": "https://pay.kibble.sh/i/abc12345",
  "pdf_url": "https://pay.kibble.sh/api/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/pdf",
  "deposit_address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
  "total_amount": "1500.00",
  "sent_at": "2026-04-28T12:00:00Z",
  "webhook_secret": "whs_abc123..."
}
webhook_secret is returned only once, at creation time. If you lose it, you will need to create a new invoice with a fresh webhook_url to get a new secret.

Errors

StatusCause
400One or more fields failed validation. The response body contains field-level error details.
500Kibble could not provision your wallet or save the invoice to the database.