Concepts
External IDs and idempotency
Address records by your own IDs. Retrying a request never creates a duplicate.
External IDs
Customers, invoices, and payments are addressed by your ID in the URL: /customers/by-external-id/{external_id}. Use the ID your system already has, such as a student, charge, or payment intent ID.
Bills, expenses, vendors, journal entries, and invoices created with POST are addressed by their HelloLedger ID instead. Retry those creates with an Idempotency-Key header; see How bookkeeping records work.
External IDs are 1–128 characters: letters, numbers, and . _ : -, starting with a letter or number. They are unique per company and integration, and case-sensitive.
PUT is safe to retry
Every write is a PUT to the record's external ID. HelloLedger hashes the request body and compares it with what it stored:
- Amounts compare by value: "850", "850.0", and "850.00" are the same.
- Two identical requests sent at the same moment still produce one record.
- Because retries are safe, a nightly job that re-sends the last few days is a good way to make sure nothing is missed.
- One exception: a Connect HelloLedger code works only once. If the exchange fails after the code was accepted, send the user through Connect again.
| Situation | Result | HTTP |
|---|---|---|
| New external ID | created | 201 |
| Same body as before | unchanged (nothing is written) | 200 |
| Customer with a different body | updated | 200 |
| Unpaid invoice with a different body | replaced (old version voided, new version posted) | 200 |
| Payment, credit, refund, or payout with a different body | 409 payment_immutable (credit_, refund_, payout_) | 409 |
| Any record that was voided | 409 invoice_voided (payment_, credit_, refund_, payout_) | 409 |
The result field
Write responses include result: created, updated, replaced, unchanged, or voided. Log it; it tells you what HelloLedger did without a second request.
Reading records back
curl "https://api.helloledger.ai/v1/companies/{company_id}/customers/by-external-id/stu_1001" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/invoices/by-external-id/chg_2026_10_rent_1001" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/customer-payments/by-external-id/pay_pi_3Q8x" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/customer-credits/by-external-id/cr_2026_10_special_1001" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/customer-refunds/by-external-id/rf_deposit_1001" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/payouts/by-external-id/po_1QxYz" \
-H "Authorization: Bearer $HL_API_KEY"