curl https://invoice.horizonpay.co/api/v1/invoices/in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8/send \
-H "Authorization: Bearer $INVOICE_AI_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "to": "[email protected]" }'import InvoiceAI from '@horizonpay/invoice-ai'
const invoiceai = new InvoiceAI() // reads INVOICE_AI_API_KEY
// Retries reuse one Idempotency-Key; pass { idempotencyKey } to set your own.
const sent = await invoiceai.invoices.send('in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8', {
to: '[email protected]',
})
console.log(sent.data.number, sent.emailed_to)from invoice_ai import InvoiceAI
client = InvoiceAI() # reads INVOICE_AI_API_KEY
# Retries reuse one Idempotency-Key; pass idempotency_key=... to set your own.
sent = client.invoices.send(
"in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8",
to="[email protected]",
)
print(sent.data.number, sent.emailed_to){
"data": {
"id": "in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8",
"object": "invoice",
"number": "INV-0042",
"status": "open",
"customer": "cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6",
"currency": "USD",
"collection_method": "send_invoice",
"issue_date": "2026-09-22",
"due_date": "2026-10-22",
"description": "Consulting retainer.",
"footer": null,
"subtotal": 2550000,
"discount": 0,
"taxable": 2550000,
"tax": 0,
"total": 2550000,
"amount_due": 2550000,
"amount_in_words": "Twenty Five Thousand Five Hundred USD Only",
"public_url_token": "2b7e4c1a-9f3d-4e68-8a5b-0d1c7f3e9a46",
"finalized_at": "2026-09-22T10:00:00.000Z",
"paid_at": null,
"voided_at": null,
"void_reason": null,
"created": "2026-09-22T09:30:00.000Z",
"updated": "2026-09-22T10:00:00.000Z",
"lines": {
"data": [
{
"id": "ii_Da4Vq9Ns2Kx7Bm3Yt8Rc1Lp6",
"object": "invoiceitem",
"price": "price_Jc5Tn8Wq1Ze6Ra3Ym9Ub2Gs7",
"product": "prod_Hy7Rq2Lm9Xc4Vb8Nt3Kd6Pw1",
"description": "Consulting retainer",
"quantity": 1,
"unit": "NOS",
"unit_amount": 2500000,
"amount": 2500000,
"discount_percent": 0,
"tax_rate": 0,
"tax_amount": 0
},
{
"id": "ii_Ew8Hz3Jc6Tq1Ms5Nv9Kb2Xr4",
"object": "invoiceitem",
"price": null,
"product": null,
"description": "Onboarding workshop",
"quantity": 1,
"unit": "NOS",
"unit_amount": 50000,
"amount": 50000,
"discount_percent": 0,
"tax_rate": 0,
"tax_amount": 0
}
]
}
},
"emailed_to": "[email protected]"
}Send an invoice
Emails the invoice PDF and a link to its public page to to, or else the customer email on the invoice. A draft is finalized first (no invoices:finalize scope needed). Open and paid invoices can be re-sent; void ones cannot.
Requires a verified account email — until then this returns 409 invalid_state.
Rate limits: 10 sends per hour per API key, and 50 per hour per account across every key and the dashboard (429 rate_limited, with Retry-After).
If the email fails after finalizing, the response is 502 upstream_failed and the number stays spent; retry the send. Emits invoice.emailed (or invoice.email_failed), plus invoice.finalized when it finalized.
Scope: invoices:send
Idempotency: Idempotency-Key required (428 without it). A retry with the same key and body replays the first response (Idempotent-Replayed: true); the same key with a different body is a 422 idempotency_mismatch.
curl https://invoice.horizonpay.co/api/v1/invoices/in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8/send \
-H "Authorization: Bearer $INVOICE_AI_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "to": "[email protected]" }'import InvoiceAI from '@horizonpay/invoice-ai'
const invoiceai = new InvoiceAI() // reads INVOICE_AI_API_KEY
// Retries reuse one Idempotency-Key; pass { idempotencyKey } to set your own.
const sent = await invoiceai.invoices.send('in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8', {
to: '[email protected]',
})
console.log(sent.data.number, sent.emailed_to)from invoice_ai import InvoiceAI
client = InvoiceAI() # reads INVOICE_AI_API_KEY
# Retries reuse one Idempotency-Key; pass idempotency_key=... to set your own.
sent = client.invoices.send(
"in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8",
to="[email protected]",
)
print(sent.data.number, sent.emailed_to){
"data": {
"id": "in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8",
"object": "invoice",
"number": "INV-0042",
"status": "open",
"customer": "cus_Nf3kQ8pR2mX7vB1cT9wL4sZ6",
"currency": "USD",
"collection_method": "send_invoice",
"issue_date": "2026-09-22",
"due_date": "2026-10-22",
"description": "Consulting retainer.",
"footer": null,
"subtotal": 2550000,
"discount": 0,
"taxable": 2550000,
"tax": 0,
"total": 2550000,
"amount_due": 2550000,
"amount_in_words": "Twenty Five Thousand Five Hundred USD Only",
"public_url_token": "2b7e4c1a-9f3d-4e68-8a5b-0d1c7f3e9a46",
"finalized_at": "2026-09-22T10:00:00.000Z",
"paid_at": null,
"voided_at": null,
"void_reason": null,
"created": "2026-09-22T09:30:00.000Z",
"updated": "2026-09-22T10:00:00.000Z",
"lines": {
"data": [
{
"id": "ii_Da4Vq9Ns2Kx7Bm3Yt8Rc1Lp6",
"object": "invoiceitem",
"price": "price_Jc5Tn8Wq1Ze6Ra3Ym9Ub2Gs7",
"product": "prod_Hy7Rq2Lm9Xc4Vb8Nt3Kd6Pw1",
"description": "Consulting retainer",
"quantity": 1,
"unit": "NOS",
"unit_amount": 2500000,
"amount": 2500000,
"discount_percent": 0,
"tax_rate": 0,
"tax_amount": 0
},
{
"id": "ii_Ew8Hz3Jc6Tq1Ms5Nv9Kb2Xr4",
"object": "invoiceitem",
"price": null,
"product": null,
"description": "Onboarding workshop",
"quantity": 1,
"unit": "NOS",
"unit_amount": 50000,
"amount": 50000,
"discount_percent": 0,
"tax_rate": 0,
"tax_amount": 0
}
]
}
},
"emailed_to": "[email protected]"
}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.
Headers
A unique key per distinct operation (a UUID works), reused only when retrying that same request. Up to 255 characters; stored for 24 hours.
255"6f1c2d9e-8a4b-4c3f-9e7d-2b5a1c8f4e30"
Path Parameters
The invoice, in_… or UUID.
"in_Pb2Xk7Mv4Qs9Lr1Wd6Tn3Fh8"
Body
Recipient email. Defaults to the customer email recorded on the invoice; one of the two is required.
Response
Sent. The invoice (finalized if it was a draft, with lines) plus the address it went to.
The invoice, finalized if it was a draft, with lines.
Show child attributes
Show child attributes
The address the email was sent to: to, or the customer email.