Get an invoice for its hosted page
The invoices.hosted.get operation: GET /api/v1/public/invoices/{invoiceId} in the REST API and the invoices_hosted_get tool in the MCP server.
/api/v1/public/invoices/{invoiceId}Returns an issued invoice as its hosted page shows it to the customer: amounts, due date, the bank transfer details with the invoice number as the payment reference, the PDF link, and whether it can be paid by card now (open with something due, and the brand has a processor).
Public: the page calls it with the token of the invoice link (the invoice email and reminders carry it);
API keys with invoices:read read their brand's invoices without one.
At a glance
- REST:
GET /api/v1/public/invoices/{invoiceId} - MCP tool:
invoices_hosted_get - Operation ID:
invoices.hosted.get - Scope: Brand
- Permission:
invoices:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Authentication: None (a public endpoint, rate-limited per IP address)
- Since: M5
Request
Path parameters
| Field | Type | Description |
|---|---|---|
invoiceId | inv_… ID |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
token | string | No | The invoice link's token (needed without an API key). |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
object | "hosted_invoice" | |
id | inv_… ID | |
number | string | |
livemode | boolean | |
status | string | |
language | one of en, de, fr, hr, it, es | The invoice's language (spec §18.5): the page shows it in this language unless the visitor picks another. |
brand | object | |
brand.name | string | |
brand.slug | string | |
brand.logoUrl | string or null | |
brand.primaryColor | string or null | |
brand.supportEmail | string or null | |
sellerName | string | |
buyerName | string or null | |
currency | string | |
total | money | |
creditApplied | money or null | |
amountDue | money | |
issueDate | string | |
dueDate | string or null | |
paidAt | date-time or null | |
bankTransfer | object or null | Where to transfer the amount due, with the invoice number as the payment reference. |
card | object | |
card.available | boolean | |
card.unavailableReason | one of not_open, nothing_due, no_processor or null | |
card.component | one of fake, stripe_payment_element, redirect or null | |
card.publishableKey | string or null | |
pdfPath | string |
Examples
An open invoice with its bank transfer details
GET /api/v1/public/invoices/inv_01m4tx5nj8emwbyf7y9vcf47zn?token=WyJvcmdfMDEiLCJlbnRfMDEiLCJicmRfMDEiLDBd.c2lnbmF0dXJl
Response (200):
{
"object": "hosted_invoice",
"id": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"number": "GEN-2026-000131",
"livemode": false,
"status": "open",
"language": "en",
"brand": {
"name": "Acme App",
"slug": "acme-app",
"logoUrl": null,
"primaryColor": null,
"supportEmail": "billing@acme.example"
},
"sellerName": "Acme Digital d.o.o.",
"buyerName": "Alpen Apps GmbH",
"currency": "EUR",
"total": {
"amount": "1200000000",
"currency": "EUR"
},
"creditApplied": null,
"amountDue": {
"amount": "1200000000",
"currency": "EUR"
},
"issueDate": "2026-10-20",
"dueDate": "2026-11-03",
"paidAt": null,
"bankTransfer": {
"accountHolder": "Acme Digital d.o.o.",
"iban": "HR1210010051863000160",
"bic": "PBZGHR2X",
"bankName": "Privredna banka Zagreb",
"reference": "GEN-2026-000131"
},
"card": {
"available": true,
"unavailableReason": null,
"component": "fake",
"publishableKey": null
},
"pdfPath": "/api/v1/invoices/inv_01m4tx5nj8emwbyf7y9vcf47zn/pdf?token=WyJvcmdfMDEiLCJlbnRfMDEiLCJicmRfMDEiLDBd.c2lnbmF0dXJl"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A field is malformed or out of range. | Fix the fields listed in details.issues and send the request again. |
resource_not_found | 404 | No issued invoice has this ID in the brand, or the link's token doesn't belong to it. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
It can also return these common errors: api_version_unsupported, scope_required, dry_run_not_supported, rate_limited, internal_error.