Bookkeeping

    Bills

    Bills from vendors. Posting puts the expense on the books and the amount owed in Accounts Payable.

    Create a bill

    Scope: bills:write. Each line names an expense (or asset) account from GET /coa and an amount. The vendor is matched by name or created, so you can send bills before setting up vendors.

    With "post": true the bill is posted right away (status entered): each line's account is debited and Accounts Payable is credited. Without it the bill is saved as a draft.

    POST
    curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/bills" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Idempotency-Key: bill_5531" \
      -H "Content-Type: application/json" \
      -d '{
      "vendor": {
        "name": "Staples"
      },
      "bill_number": "INV-77",
      "date": "2026-10-01",
      "due_date": "2026-10-31",
      "memo": "October office supplies",
      "external_id": "bill_5531",
      "post": true,
      "lines": [
        {
          "account_id": "66f1a2b3c4d5e6f708091d01",
          "description": "Paper and toner",
          "amount": "120.00"
        },
        {
          "account_id": "66f1a2b3c4d5e6f708091d02",
          "description": "Storage unit",
          "amount": "80.00"
        }
      ]
    }'
    Response (201)
    {
      "bill_id": "66f1a2b3c4d5e6f708093b01",
      "external_id": "bill_5531",
      "vendor_id": "66f1a2b3c4d5e6f708092a01",
      "vendor_name": "Staples",
      "vendor_created": false,
      "bill_number": "INV-77",
      "date": "2026-10-01",
      "due_date": "2026-10-31",
      "status": "entered",
      "posted": true,
      "total_amount": "200.00",
      "amount_paid": "0.00",
      "amount_credited": "0.00",
      "balance_due": "200.00",
      "currency": "USD",
      "ap_account_id": "66f1a2b3c4d5e6f708091d09",
      "lines": [
        { "account_id": "66f1a2b3c4d5e6f708091d01", "account_name": "Office Supplies", "description": "Paper and toner", "amount": "120.00" },
        { "account_id": "66f1a2b3c4d5e6f708091d02", "account_name": "Rent Expense", "description": "Storage unit", "amount": "80.00" }
      ],
      "posted_at": "2026-10-01T15:04:05Z",
      "result": "posted"
    }

    Fields

    FieldNotes
    vendor_id or vendorRequired on create, one or the other. vendor takes the same fields as POST /vendors.
    dateDate the bill was received (YYYY-MM-DD). Required on create.
    lines1–100 lines of account_id and amount, with optional description, quantity, and unit_price.
    due_date, bill_number, memoOptional.
    ap_account_idAccounts Payable account. Defaults to the company's A/P account.
    external_idYour ID for the bill, stored for reference.
    posttrue posts now. Default false saves a draft.

    List and read bills

    Scope: bills:read or bills:write. Filter by status (draft, entered, partial, paid, overdue, voided), vendor_id, external_id, and a from/to date range. Unpaid bills past their due date show as overdue.

    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/bills?status=overdue&limit=50" \
      -H "Authorization: Bearer $HL_API_KEY"
    One bill · GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/bills/66f1a2b3c4d5e6f708093b01" \
      -H "Authorization: Bearer $HL_API_KEY"

    Edit, post, or delete

    PATCH changes a draft or an unpaid posted bill. Sending lines replaces all lines. A posted bill is re-posted with the new amounts. Bills with payments or vendor credits return 409 bill_has_payments.

    PATCH
    curl -X PATCH "https://api.helloledger.ai/v1/companies/{company_id}/bills/66f1a2b3c4d5e6f708093b01" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "due_date": "2026-11-15",
      "lines": [
        {
          "account_id": "66f1a2b3c4d5e6f708091d01",
          "amount": "135.00"
        }
      ]
    }'
    Post a draft · POST
    curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/bills/66f1a2b3c4d5e6f708093b01/post" \
      -H "Authorization: Bearer $HL_API_KEY"
    Delete a draft · DELETE
    curl -X DELETE "https://api.helloledger.ai/v1/companies/{company_id}/bills/66f1a2b3c4d5e6f708093b01" \
      -H "Authorization: Bearer $HL_API_KEY"

    Void a bill

    Voiding reverses the bill's ledger entries and sets status voided. Bills with payments or credits can't be voided until those are removed in HelloLedger.

    POST
    curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/bills/66f1a2b3c4d5e6f708093b01/void" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "reason": "Duplicate of INV-76"
    }'