FinzBooksDevelopers

Credit & Debit Notes

GST-compliant reversal documents. Customer credit notes offset invoices (refund / write-off scenarios). Vendor credits offset bills (purchase return / vendor refund scenarios). Both live in the same credit_notes resource — direction is set by which parent id you pass.

Credit Notes — list / get

GET/credit_notesList credit notes (cursor-paginated)AIBooks.creditnotes.READ

Filter params:

  • ?status=DRAFT|ISSUED|APPLIED|CANCELLED
  • ?customer_id=<contact_id> — both customer + vendor
  • ?invoice_id=<id> — customer-side CNs linked to this invoice
  • ?bill_id=<id> — vendor-side CNs linked to this bill
  • ?type=customer|vendor — filter to one side
GET/credit_notes/{credit_note_id}Get one credit noteAIBooks.creditnotes.READ

Create / update

POST/credit_notesCreate (auto-posts journal)AIBooks.creditnotes.CREATE
PUT/credit_notes/{credit_note_id}Update (blocked once applied)AIBooks.creditnotes.UPDATE
POST/credit_notes/{credit_note_id}/voidCancel (status → CANCELLED)AIBooks.creditnotes.UPDATE

Customer-side (issued against an Invoice) and vendor-side (issued against a Bill — a purchase return) credit notes share this endpoint. The server decides stock direction (SALES_RETURN_IN vs PURCHASE_RETURN_OUT) based on the contact type and which parent id is supplied.

Create — customer-side

POST /credit_notes
{
  "customer_id": "ct_acme",
  "invoice_id":  "inv_abc",      // optional — links the CN to one invoice
  "date":        "2026-05-12",
  "line_items": [
    { "item_id": "it_widget", "quantity": 1, "rate": 1000, "restock": true }
  ],
  "notes": "Damaged in transit"
}

Create — vendor-side (purchase return / vendor credit)

POST /credit_notes
{
  "customer_id": "ct_vendor",    // the vendor's contact id (legacy name)
  "bill_id":     "bl_xyz",       // pass bill_id → vendor-side direction
  "date":        "2026-05-12",
  "line_items": [
    { "item_id": "it_widget", "quantity": 2, "rate": 500 }
  ]
}

Apply (knock off against the parent doc)

Creating a CN registers the credit but doesn't reduce any invoice/bill balance automatically. Use the apply endpoints to consume part or all of the credit against an open document.

POST/credit_notes/{credit_note_id}/apply-to-invoiceApply customer credit to an open invoiceAIBooks.creditnotes.UPDATE
POST /credit_notes/<cn_id>/apply-to-invoice
{
  "invoice_id": "inv_xyz",
  "amount":     5000
}

# Response — both records updated
{
  "code": 0,
  "message": "Credit note CN-001 applied to invoice INV-2026-0042.",
  "credit_note": {
    "credit_note_id":  "cn_…",
    "applied_amount":  5000.00,
    "balance_amount":  3000.00,   // remaining
    "status":          "ISSUED"   // → APPLIED when fully consumed
  },
  "invoice": {
    "invoice_id":    "inv_xyz",
    "balance":       0,
    "status":        "CREDIT_APPLIED",
    "paid_amount":   5000.00
  }
}
POST/credit_notes/{credit_note_id}/apply-to-billApply vendor credit to an open billAIBooks.creditnotes.UPDATE
POST /credit_notes/<cn_id>/apply-to-bill
{
  "bill_id": "bl_abc",
  "amount":  2000
}

# Response shape is symmetric — bill balance + status updated,
# bill.vendor_credits_applied is bumped.

Apply rules

  • Same contact: CN and target doc must belong to the same customer / vendor. Cross-contact → 400.
  • Amount caps: amount ≤ min(cn.balance, target.balance) — over either limit returns 400 with the actual limit in details.
  • Status guard:a CANCELLED CN can't be applied.
  • Side mirror:partial applications update both rows' balance / applied_amount / status in one transaction. If the target balance hits 0, the appropriate INVOICE_PAID / BILL_PAID webhook fires.

Debit Notes

GET/debit_notesList debit notesAIBooks.debitnotes.READ
GET/debit_notes/{debit_note_id}Get oneAIBooks.debitnotes.READ
POST/debit_notesCreateAIBooks.debitnotes.CREATE
PUT/debit_notes/{debit_note_id}UpdateAIBooks.debitnotes.UPDATE
POST/debit_notes/{debit_note_id}/voidCancelAIBooks.debitnotes.UPDATE

Status lifecycle (both CN + DN)

DRAFT  →  ISSUED  →  APPLIED        (when fully offset against AR / AP)
   ↓
CANCELLED

Common patterns

Inbox-style vendor credits view

# Outstanding vendor credits for a vendor
GET /credit_notes?type=vendor&customer_id=<vendor_id>&status=ISSUED

Find vendor credits available against a bill

# Same-vendor CNs with remaining balance
GET /credit_notes?type=vendor&customer_id=<vendor_id>&status=ISSUED

# Apply each up to its balance OR the bill's outstanding
POST /credit_notes/<cn_id>/apply-to-bill { "bill_id": ..., "amount": ... }

Refunding a customer in cash (instead of applying to a future invoice)

Use the internal POST /credit_notes/{id}/refund endpoint via the UI for now — public-API refunds are roadmap.