FinzBooksDevelopers

Bulk operations

POST up to 50 invoices or bills in one HTTP call. Each item is created independently — one bad row doesn't roll back the rest.

POST/bulk/invoicesCreate up to 50 invoicesAIBooks.invoices.CREATE
POST/bulk/billsCreate up to 50 billsAIBooks.bills.CREATE

Request shape

POST /bulk/invoices
Authorization: Bearer aibk_pat_…
Content-Type: application/json
Idempotency-Key: …

{
  "invoices": [
    {
      "customer_id": "ct_acme",
      "date": "2026-05-12T00:00:00",
      "place_of_supply": "IN-MH",
      "line_items": [{ "item_id": "it_widget", "quantity": 1 }]
    },
    {
      "customer_id": "ct_beta",
      "date": "2026-05-12T00:00:00",
      "place_of_supply": "IN-KA",
      "line_items": [{ "item_id": "it_widget", "quantity": 3 }],
      "auto_approve": true
    }
  ]
}

Each entry uses the same shape as POST /invoices — same required fields, same line-item auto-fill, same auto_approve behaviour.

Response shape

Always HTTP 200 with a per-item results array. Partial failures are not request-level errors — check results[].ok for each row.

{
  "code": 0,
  "message": "2 of 3 invoices created.",
  "summary": { "total": 3, "succeeded": 2, "failed": 1 },
  "results": [
    {
      "ok": true,
      "invoice": { /* full InvoicePublic */ }
    },
    {
      "ok": false,
      "error": {
        "code":   "not_found.resource",
        "message": "Item 'it_missing' not found in this org.",
        "field":  "line_items[0].item_id"
      }
    },
    {
      "ok": true,
      "invoice": { /* full InvoicePublic */ }
    }
  ]
}

Limits + rules

  • Maximum 50 items per request (HTTP 422 if exceeded).
  • Empty invoices: [] / bills: [] rejected with HTTP 422.
  • Each item is created in its own try/except. A failure rolls back only that row — earlier successful rows are durable.
  • Webhooks fire per-item exactly as if you'd called the single-resource endpoints. Plus an aggregate INVOICE_BULK_CREATED / BILL_BULK_CREATED event at the end with { count, failed, batch_size }.