NuminaDevelopers
Dashboard
Book draft invoice

Book draft invoice

POST
/v1/invoices/{id}/book

Books a draft invoice to the ledger and assigns its number. Each call is your own approval of the invoice: Numina does not review it, so make sure a person at your company has checked it or has approved the rules your system books by. Booking is final and cannot be undone through this API. It does not send the invoice; use POST /v1/invoices/{id}/send.

Not available to Fuld Service customers (403 booking_not_available), whose books Numina's bookkeepers keep.

Returns 400 validation_error for a date in a closed accounting year or before the first accounting date, VAT on a company that is not VAT registered, an e-invoice that cannot be sent, or an invoice that is not complete. Returns 400 payment_details_required for an invoice with no payment details when the company has no default bank account to fill them from (see is_invoice_default on GET /v1/bank-accounts); create the invoice again with bank_account_id. A foreign-currency invoice uses the latest exchange rate Numina has on or before its issue date; see currency_rate on POST /v1/invoices.

Safe to retry: booking an invoice that is already booked returns it unchanged with 200. Credit notes and offers cannot be booked here and return 409.

Requires one ofinvoices:bookwrite:ledger

Path parameters

  • idstring (uuid)Required
    Invoice ID

Errors

  • 400Invalid input or validation failed
  • 401Invalid or missing authentication
  • 403Missing scope, the company is archived, or the company is on Fuld Service
  • 404The resource does not exist in this company
  • 409This is a credit note or offer, or the invoice is being updated
  • 429Rate limit exceeded
  • 500Internal Server Error

Every error has the same shape. See Errors.

cURL
curl -X POST https://api.numina.app/v1/invoices/550e8400-e29b-41d4-a716-446655440000/book \
  -H "Authorization: Bearer numi_YOUR_API_KEY"
JavaScript
const response = await fetch("https://api.numina.app/v1/invoices/550e8400-e29b-41d4-a716-446655440000/book", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.NUMINA_API_KEY}`,
  },
});

const data = await response.json();
Python
import os

import requests

response = requests.post(
    "https://api.numina.app/v1/invoices/550e8400-e29b-41d4-a716-446655440000/book",
    headers={
        "Authorization": f"Bearer {os.environ['NUMINA_API_KEY']}",
    },
)
data = response.json()
Response
200
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "invoice_number": 1001,
  "type": "invoice",
  "credited_invoice_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "sent",
  "issue_date": "2026-01-15",
  "due_date": "2026-02-15",
  "contact_id": "550e8400-e29b-41d4-a716-446655440001",
  "contact_name": "Acme ApS",
  "currency": "DKK",
  "subtotal": 10000,
  "vat": 2500,
  "vat_rate": 25,
  "total": 12500,
  "has_mixed_vat": false,
  "outstanding_balance": 12500,
  "outstanding_balance_currency": "DKK",
  "currency_rate": 0,
  "delivery_status": "sent",
  "email_delivery_status": "string",
  "email_sent_at": "string",
  "e_invoice_sent_at": "string",
  "is_overdue": false,
  "payment_state": "open",
  "unmatched_payments_note": "string",
  "items": [
    {
      "unit": "string",
      "vat_account_id": "string",
      "vat_code": "string",
      "sales_account_number": 0,
      "vat_rate": 0,
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "description": "Consulting services",
      "quantity": 10,
      "unit_price": 1000
    }
  ],
  "memo": "Project Q1 delivery",
  "payment_details": {
    "bank_name": "Danske Bank",
    "scheme": "dk-registration-number",
    "clearing_code": "3409",
    "account_number": "0012345678",
    "iban": "DK5030000012345678",
    "swift_bic": "DABADKKK"
  },
  "created_at": "2026-01-15T10:30:00Z"
}