Concepts

    Errors

    Every error has a stable code, a message, an optional hint, and a request ID.

    Error format

    Errors return a non-2xx status with this body. Branch on code, not on message. Quote request_id when you contact support; it is also in the X-Request-Id response header.

    You can send your own X-Request-Id header to correlate logs. HelloLedger echoes it on the response, in errors, and in the key's activity. It must be 1–128 characters of letters, digits, and . _ : / + = @ - starting with a letter or digit; anything else is replaced with a generated ID.

    json
    {
      "detail": {
        "error": {
          "code": "customer_not_found",
          "message": "No customer with external_id 'stu_1001'",
          "hint": "Create it with PUT /v1/companies/{company_id}/customers/by-external-id/stu_1001, or include a customer block on the invoice.",
          "request_id": "req_4f1c2a9b8e7d6c5b4a39"
        }
      }
    }

    Validation errors

    A body that doesn't match the schema (missing field, wrong type, unknown field) returns 422 with a list of problems:

    json
    {
      "detail": [
        { "type": "extra_forbidden", "loc": ["body", "favorite_color"], "msg": "Extra inputs are not permitted" }
      ]
    }

    Error codes

    CodeHTTPWhat to do
    unauthorized401Send Authorization: Bearer <secret>. Check the key wasn't revoked.
    bearer_required401This endpoint doesn't accept HTTP Basic. Send Authorization: Bearer <secret>.
    ip_not_allowed403The key has an IP allowlist. Call from an allowed address or update the list.
    forbidden_company403The key doesn't cover this company_id.
    insufficient_scope403Create a key with the scope the route needs.
    not_found404No record with that external ID for your integration.
    customer_not_found422PUT the customer first, or include a customer block on the invoice.
    unknown_item422Use an item_id from GET /items.
    item_inactive422The product or service was deactivated in HelloLedger.
    unknown_account422Use an account_id from GET /coa for this company.
    account_closed422The account isn't open on that date.
    invalid_deposit_account422Deposit to a bank or current-asset (clearing) account.
    invoice_not_found422A payment application names an invoice that doesn't exist.
    invoice_customer_mismatch422A payment can only pay its own customer's invoices.
    duplicate_application422List each invoice once per payment.
    applications_exceed_amount422Applications add up to more than the payment or credit.
    invalid_application422An application is more than the invoice's or bill's open balance, or the bill belongs to another vendor or isn't open.
    exceeds_unapplied422Vendor credits: apply or refund at most the credit's unapplied_amount.
    invalid_card_account422Card credits: card_account_id must be a credit card or bank account.
    unknown_expense422Card credits: expense_id isn't an expense in this company.
    invalid_date_range, date_range_too_large400'to' must be on or after 'from', and the range must fit the endpoint's limit.
    report_not_available400Hotel reports and room statistics are only for Hospitality companies.
    invalid_credit_account422Credit lines use income, expense, or liability accounts; deposit_applied needs the deposit liability.
    invalid_paid_from_account422Refunds: use a bank or current-asset (clearing) account. Expenses: use a bank, credit card, or cash account.
    unknown_vendor, unknown_customer422The vendor_id or customer_id isn't in this company. Read it from GET /vendors, or send a vendor or customer block instead.
    ap_account_required422The company has no default Accounts Payable account. Send ap_account_id, or set the default in HelloLedger.
    payment_not_found422The refund or payout names a payment that doesn't exist.
    credit_not_found422The refund names a credit that doesn't exist.
    payment_customer_mismatch422Refund a payment under the customer who made it (same for credit_customer_mismatch).
    refund_exceeds_unapplied422/409Refund at most the payment's or credit's unapplied_amount. Read it back to see the current amount.
    invalid_clearing_account422Use the bank or current-asset clearing account the payments went to.
    invalid_fee_account422Send fee_account_id as an expense account whenever fee is above 0.
    invalid_bank_account422bank_account_id must be a bank or current-asset account.
    duplicate_payment422List each payment once per payout.
    invoice_number_taken409Pick another invoice_number or omit it.
    invoice_has_payments409Void the payment, then change or void the invoice.
    invoice_voided409Voided invoices stay voided. Use a new external ID.
    payment_immutable409Payments can't be edited. Void it and send a new external ID.
    payment_voided409Use a new external ID for the corrected payment.
    payment_has_refunds409Void the refund before voiding the payment.
    credit_has_refunds409Void the refund before voiding the credit. For vendor credits, reverse the refund in HelloLedger.
    credit_immutable, refund_immutable, payout_immutable409These can't be edited. Void and send a new external ID.
    credit_voided, refund_voided, payout_voided409Use a new external ID for the corrected record. A voided vendor or card credit can't be applied, refunded, or edited.
    customer_name_taken409Rare: both the name and "Name (external_id)" are taken.
    vendor_exists409A vendor with that name exists. Use its vendor_id from the message, or pick another name.
    idempotency_key_reused409The Idempotency-Key was already used with a different body. Send a new key for a new record.
    not_draft409Only drafts can be deleted. Void the record instead.
    bill_has_payments409Remove the bill's payments or vendor credits in HelloLedger, then edit or void it.
    bill_voided, expense_voided, journal_voided409Voided records stay voided. Create a new one.
    expense_matched409The expense is matched to a bank transaction. Unmatch it in HelloLedger first.
    unsupported_expense_type409Employee reimbursement claims are managed in HelloLedger, not through the API.
    managed_by_integration409Another integration created this journal entry. Change it there.
    period_reconciled409An account is reconciled through that date. Use a later date, or undo the reconciliation in HelloLedger.
    invalid_client401Partner endpoints only: check your client ID and secret.
    invalid_grant400Connect only: the code expired or was already used. A code works once, for 10 minutes.
    invalid_redirect_uri400Connect only: use the redirect URI exactly as registered.
    partner_paused403Connect for this partner app is paused. Contact HelloLedger.
    company_not_linked404Partner endpoints only: the company isn't connected to your app.
    access_deniedredirectConnect only: the user cancelled on the approval screen.
    posting_failed4xx/5xxThe record is saved as a draft. Retry the same request, or call /post on it.
    internal_error500Retry the same request. Contact support with the request_id if it persists.
    db_unavailable503Retry with backoff.