curl -X PATCH https://invoice.horizonpay.co/api/v1/customers/cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6 \
-H "Authorization: Bearer $INVOICE_AI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "phone": "+1 512 555 0100" }'import InvoiceAI from '@horizonpay/invoice-ai'
const invoiceai = new InvoiceAI() // reads INVOICE_AI_API_KEY
const customer = await invoiceai.customers.update('cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6', {
phone: '+1 512 555 0100',
})
console.log(customer.phone)from invoice_ai import InvoiceAI
client = InvoiceAI() # reads INVOICE_AI_API_KEY
customer = client.customers.update(
"cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6",
phone="+1 512 555 0100",
)
print(customer.phone){
"data": {
"id": "cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6",
"object": "customer",
"name": "Acme Industries",
"email": "[email protected]",
"phone": "+1 512 555 0100",
"tax_id": "US-EIN 12-3456789",
"address": {
"line1": "4th Floor, Market Tower",
"line2": null,
"city": "Austin",
"state": "TX",
"postal_code": "73301",
"country": "US"
},
"deleted": false,
"created": "2026-09-22T09:30:00.000Z"
}
}{
"type": "https://invoice.horizonpay.co/problems/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Send your API key as `Authorization: Bearer inv_live_…`.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "unauthorized"
}{
"type": "https://invoice.horizonpay.co/problems/forbidden",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential is missing the invoices:write scope.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "forbidden"
}{
"type": "https://invoice.horizonpay.co/problems/not-found",
"title": "Not found",
"status": 404,
"detail": "Client not found.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "not_found"
}{
"type": "https://invoice.horizonpay.co/problems/validation",
"title": "Validation failed",
"status": 422,
"detail": "Some fields need attention.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "validation",
"errors": [
{
"path": "name",
"message": "Enter your customer's name"
}
]
}{
"type": "https://invoice.horizonpay.co/problems/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "Rate limit of 120 per 60s exceeded.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "rate_limited"
}Update a customer
Updates the fields you send and leaves the rest unchanged. Issued invoices keep the customer details they were billed with. No Idempotency-Key needed — repeating the call is harmless.
Scope: clients:write
curl -X PATCH https://invoice.horizonpay.co/api/v1/customers/cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6 \
-H "Authorization: Bearer $INVOICE_AI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "phone": "+1 512 555 0100" }'import InvoiceAI from '@horizonpay/invoice-ai'
const invoiceai = new InvoiceAI() // reads INVOICE_AI_API_KEY
const customer = await invoiceai.customers.update('cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6', {
phone: '+1 512 555 0100',
})
console.log(customer.phone)from invoice_ai import InvoiceAI
client = InvoiceAI() # reads INVOICE_AI_API_KEY
customer = client.customers.update(
"cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6",
phone="+1 512 555 0100",
)
print(customer.phone){
"data": {
"id": "cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6",
"object": "customer",
"name": "Acme Industries",
"email": "[email protected]",
"phone": "+1 512 555 0100",
"tax_id": "US-EIN 12-3456789",
"address": {
"line1": "4th Floor, Market Tower",
"line2": null,
"city": "Austin",
"state": "TX",
"postal_code": "73301",
"country": "US"
},
"deleted": false,
"created": "2026-09-22T09:30:00.000Z"
}
}{
"type": "https://invoice.horizonpay.co/problems/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Send your API key as `Authorization: Bearer inv_live_…`.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "unauthorized"
}{
"type": "https://invoice.horizonpay.co/problems/forbidden",
"title": "Insufficient scope",
"status": 403,
"detail": "This credential is missing the invoices:write scope.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "forbidden"
}{
"type": "https://invoice.horizonpay.co/problems/not-found",
"title": "Not found",
"status": 404,
"detail": "Client not found.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "not_found"
}{
"type": "https://invoice.horizonpay.co/problems/validation",
"title": "Validation failed",
"status": 422,
"detail": "Some fields need attention.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "validation",
"errors": [
{
"path": "name",
"message": "Enter your customer's name"
}
]
}{
"type": "https://invoice.horizonpay.co/problems/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "Rate limit of 120 per 60s exceeded.",
"instance": "req_7f3c9a1e2b4d4e8a9c6f2d1b0a3e5f71",
"code": "rate_limited"
}Authorizations
An Invoice-AI API key sent as Authorization: Bearer inv_live_….
Create keys in Settings → API keys; the secret is shown once. Each key carries scopes, and every operation lists the scope it needs (x-required-scope):
business:read— Read your business profile, tax ID and bank detailsclients:read— List and read your clientsclients:write— Create, update and archive clientsproducts:read— List and read products and pricesproducts:write— Create, update and archive products and pricesinvoices:read— List and read invoices, including PDFsinvoices:write— Create, edit and delete draftsinvoices:finalize— Finalize invoices and void theminvoices:send— Email invoices to your clientspayments:write— Mark invoices as paidwebhooks:manage— Manage webhook endpoints
Keys cannot be created or revoked through the API, so a leaked key cannot mint more keys.
Path Parameters
The customer, cus_… or UUID.
"cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6"
Body
Any subset of the create fields. Omitted fields are left unchanged.
Full name or legal business name.
1"Acme Industries"
Billing email. POST /invoices/{id}/send delivers here unless you pass to. "" clears it.
^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$Phone number, free text.
Tax registration number (VAT, EIN, GSTIN…), free text — no format check.
Billing address. Every field is optional.
Show child attributes
Show child attributes
Response
The updated customer.
The updated customer.
Show child attributes
Show child attributes