Receivables

    Customers

    One customer per person or account you bill, addressed by your own ID.

    Create or update a customer

    Scope: customers:write. Send it the day the person is added in your system. Re-sending the same body returns result unchanged; a different body updates the customer.

    PUT
    curl -X PUT "https://api.helloledger.ai/v1/companies/{company_id}/customers/by-external-id/stu_1001" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "Jamie Rivera",
      "email": "jamie@example.com",
      "billing_email": "parent@example.com",
      "phone": "555-0100",
      "address_line1": "100 College Ave",
      "city": "Provo",
      "state": "UT",
      "zip": "84604",
      "metadata": {
        "unit": "4B",
        "lease_id": "L-2026-118"
      }
    }'
    Response (201 on create, 200 otherwise)
    {
      "customer_id": "66f2…",
      "external_id": "stu_1001",
      "name": "Jamie Rivera",
      "display_name": "Jamie Rivera",
      "email": "jamie@example.com",
      "billing_email": "parent@example.com",
      "phone": "555-0100",
      "status": "active",
      "metadata": { "unit": "4B", "lease_id": "L-2026-118" },
      "created_at": "2026-10-01T15:04:05+00:00",
      "updated_at": null,
      "result": "created"
    }

    Fields

    Unknown fields are rejected with 422, so typos don't go unnoticed.

    FieldTypeNotes
    namestring, requiredUp to 200 characters.
    email, billing_emailstringOptional. billing_email is used on invoices when set.
    phonestringOptional.
    address_line1, address_line2, city, state, zip, countrystringOptional.
    notesstringOptional, up to 2,000 characters.
    metadataobjectUp to 20 string key/value pairs, e.g. unit or lease ID.
    statusactive | inactiveOptional. Set inactive when the resident moves out. Omit it to leave the status unchanged.

    Moving out

    When a resident moves out, PUT the customer with status inactive. Their history stays, and you can still send final charges, credits, payments, and refunds for them. Send status active if they come back.

    PUT
    curl -X PUT "https://api.helloledger.ai/v1/companies/{company_id}/customers/by-external-id/stu_1001" \
      -H "Authorization: Bearer $HL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "Jamie Rivera",
      "email": "jamie@example.com",
      "metadata": {
        "unit": "4B"
      },
      "status": "inactive"
    }'

    Two customers with the same name

    Customer names are unique within a HelloLedger company. When a second person has the same name, HelloLedger stores it as "Name (external_id)", for example "Alex Kim (stu_2002)". The response's name is still the name you sent; display_name is how it appears in HelloLedger.

    Read a customer

    GET
    curl "https://api.helloledger.ai/v1/companies/{company_id}/customers/by-external-id/stu_1001" \
      -H "Authorization: Bearer $HL_API_KEY"