Receivables

    Customer credits

    Specials, write-offs, and kept deposits, applied to the charges they cover.

    Record a credit

    Scope: invoices:write. A credit lowers what a customer owes without money changing hands. HelloLedger debits each line's account, credits A/R, and applies the credit to the invoices you list.

    Move-in special · PUT
    curl -X PUT "https://api.helloledger.ai/v1/companies/{company_id}/customer-credits/by-external-id/cr_2026_10_special_1001" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "customer_external_id": "stu_1001",
      "date": "2026-10-01",
      "reason": "concession",
      "memo": "First month $100 off",
      "lines": [
        {
          "account_id": "66f1a2b3c4d5e6f708091f60",
          "description": "Move-in special",
          "amount": "100.00"
        }
      ],
      "applications": [
        {
          "invoice_external_id": "chg_2026_10_rent_1001",
          "amount": "100.00"
        }
      ]
    }'
    Response
    {
      "credit_id": "66f6…",
      "external_id": "cr_2026_10_special_1001",
      "customer_id": "66f2…",
      "customer_external_id": "stu_1001",
      "date": "2026-10-01",
      "reason": "concession",
      "credit_number": null,
      "memo": "First month $100 off",
      "total_amount": "100.00",
      "amount_applied": "100.00",
      "refunded_amount": "0.00",
      "unapplied_amount": "0.00",
      "status": "applied",
      "lines": [
        { "account_id": "66f1a2b3c4d5e6f708091f60", "description": "Move-in special", "amount": "100.00" }
      ],
      "applications": [
        { "invoice_id": "66f3…", "invoice_external_id": "chg_2026_10_rent_1001", "amount": "100.00" }
      ],
      "result": "created"
    }

    Which account to use

    Lines can't point at bank, A/R, asset, or equity accounts. Ask the bookkeeper which accounts to use and keep their IDs in your app's settings.

    SituationreasonLine account
    Rent special, move-in discount, goodwill creditconcessionAn income account such as Rent Concessions
    Balance you won't collectwrite_offAn expense account such as Bad Debt
    Security deposit kept for damage or unpaid rentdeposit_appliedThe deposit liability, such as Tenant Security Deposits (required)
    Anything elseotherAny income, expense, or liability account

    Keeping a security deposit

    Post the damage or unpaid rent as a normal charge, then apply the deposit to it with a deposit_applied credit. The deposit liability goes down and the charge is paid. Return whatever is left with a refund (source deposit).

    PUT
    curl -X PUT "https://api.helloledger.ai/v1/companies/{company_id}/customer-credits/by-external-id/cr_deposit_kept_1001" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "customer_external_id": "stu_1001",
      "date": "2027-05-20",
      "reason": "deposit_applied",
      "memo": "Carpet cleaning kept from deposit",
      "lines": [
        {
          "account_id": "66f1a2b3c4d5e6f708091d4e",
          "description": "Deposit applied",
          "amount": "150.00"
        }
      ],
      "applications": [
        {
          "invoice_external_id": "chg_2027_05_cleaning_1001",
          "amount": "150.00"
        }
      ]
    }'

    Fields

    FieldTypeNotes
    customer_external_idstring, requiredWhose balance is credited.
    dateYYYY-MM-DD, requiredPosting date.
    reasonconcession | write_off | deposit_applied | otherRequired.
    linesarray, 1–50, requiredaccount_id, description, amount. The credit total is the sum of the lines.
    applicationsarrayInvoices the credit pays down. Can be empty; the amount stays unapplied on the customer's account.
    credit_number, memostringOptional.

    Rules

    • Applications must be the same customer's open invoices and can't exceed each invoice's balance or the credit total.
    • Credits can't be edited. Void one and send the corrected credit under a new external ID.
    • Voiding a credit reverses its ledger entry and reopens the invoices it paid. A credit with a refund can't be voided until the refund is voided.
    • An invoice with a credit applied can't be changed (409 invoice_has_payments) until the credit is voided.
    POST
    curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/customer-credits/by-external-id/cr_2026_10_special_1001/void" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "reason": "Special entered twice"
    }'
    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"