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.
    SituationResultHTTP
    New external IDcreated201
    Same body as beforeunchanged (nothing is written)200
    Customer with a different bodyupdated200
    Unpaid invoice with a different bodyreplaced (old version voided, new version posted)200
    Payment, credit, refund, or payout with a different body409 payment_immutable (credit_, refund_, payout_)409
    Any record that was voided409 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

    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/customers/by-external-id/stu_1001" \
      -H "Authorization: Bearer $HL_API_KEY"
    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/invoices/by-external-id/chg_2026_10_rent_1001" \
      -H "Authorization: Bearer $HL_API_KEY"
    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/customer-payments/by-external-id/pay_pi_3Q8x" \
      -H "Authorization: Bearer $HL_API_KEY"
    GET
    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"
    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/customer-refunds/by-external-id/rf_deposit_1001" \
      -H "Authorization: Bearer $HL_API_KEY"
    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/payouts/by-external-id/po_1QxYz" \
      -H "Authorization: Bearer $HL_API_KEY"