> ## Documentation Index
> Fetch the complete documentation index at: https://docs.horizonpay.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Retrieve Invoice Details — Invoice AI API Reference

> Fetch a single invoice by its public ID or UUID, including the complete list of line items with per-line amounts and tax breakdowns.

Retrieves the full detail of a single invoice, identified by its `in_…` public ID or UUID. Unlike the [list endpoint](/api-reference/invoices/list), the retrieve response always includes the `lines.data` array with every line item and its computed amounts.

```http theme={null}
GET /api/v1/invoices/:id
```

**Base URL:** `https://invoice.horizonpay.co`

***

## Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token in the form `Bearer inv_live_…`. The token must carry the `invoices:read` scope.
</ParamField>

***

## Path Parameters

<ParamField path="id" type="string" required>
  The invoice's public ID (`in_…`) or its UUID. Both forms are accepted.
</ParamField>

***

## Request Example

```bash theme={null}
curl https://invoice.horizonpay.co/api/v1/invoices/in_01JABCDEFGHIJKLMNOPQRSTU01 \
  -H "Authorization: Bearer inv_live_sk_1234abcd5678efgh"
```

***

## Response Example

```json theme={null}
{
  "data": {
    "id": "in_01JABCDEFGHIJKLMNOPQRSTU01",
    "object": "invoice",
    "number": "INV/25-26/0042",
    "status": "open",
    "customer": "cus_01J9ZXMQR7P4KBN2VWTF3D6H8A",
    "currency": "USD",
    "collection_method": "send_invoice",
    "issue_date": "2025-06-01",
    "due_date": "2025-07-01",
    "description": "Website redesign — Phase 2",
    "footer": "Payment due within 30 days. Bank transfer preferred.",
    "subtotal": 700000,
    "discount": 50000,
    "taxable": 650000,
    "tax": 108000,
    "total": 758000,
    "amount_due": 758000,
    "amount_in_words": "Seven thousand five hundred and eighty dollars",
    "public_url_token": "tok_share_a1b2c3d4e5f6",
    "finalized_at": "2025-06-01T09:00:00.000Z",
    "paid_at": null,
    "voided_at": null,
    "void_reason": null,
    "created": "2025-06-01T08:00:00.000Z",
    "updated": "2025-06-01T09:00:00.000Z",
    "lines": {
      "data": [
        {
          "id": "ii_01JABCDEFGHIJKLMNOPQRSTU02",
          "object": "invoiceitem",
          "price": null,
          "product": null,
          "description": "UI/UX Design",
          "quantity": 40,
          "unit": "HRS",
          "unit_amount": 15000,
          "amount": 600000,
          "discount_percent": 0,
          "tax_rate": 18,
          "tax_amount": 108000
        },
        {
          "id": "ii_01JABCDEFGHIJKLMNOPQRSTU03",
          "object": "invoiceitem",
          "price": "price_01J9ZXMQR7P4KBN2VWTF3D6HXX",
          "product": "prod_01J9ZXMQR7P4KBN2VWTF3D6HYY",
          "description": "Domain Registration (1 year)",
          "quantity": 1,
          "unit": "NOS",
          "unit_amount": 10000,
          "amount": 10000,
          "discount_percent": 10,
          "tax_rate": 0,
          "tax_amount": 0
        }
      ]
    }
  }
}
```

<Note>
  The `status` field is computed at read time. An invoice will be returned as `overdue` once its `due_date` has passed, without any explicit state transition. Always trust the value returned in the API response rather than a locally cached status.
</Note>

***

## Response Fields

<ResponseField name="data.id" type="string">
  Unique public identifier for the invoice, prefixed `in_`.
</ResponseField>

<ResponseField name="data.object" type="string">
  Always `"invoice"`.
</ResponseField>

<ResponseField name="data.number" type="string | null">
  Human-readable invoice number (e.g. `"INV/25-26/0042"`). `null` while the invoice is a draft; permanently assigned on finalization.
</ResponseField>

<ResponseField name="data.status" type="string">
  Current status, computed at read time. One of `draft`, `open`, `paid`, `overdue`, or `void`.
</ResponseField>

<ResponseField name="data.customer" type="string">
  The `cus_…` public ID of the customer attached to this invoice.
</ResponseField>

<ResponseField name="data.currency" type="string">
  Three-letter ISO 4217 currency code.
</ResponseField>

<ResponseField name="data.collection_method" type="string">
  `"send_invoice"` or `"charge_automatically"`.
</ResponseField>

<ResponseField name="data.issue_date" type="string">
  ISO 8601 date the invoice was issued (`YYYY-MM-DD`).
</ResponseField>

<ResponseField name="data.due_date" type="string | null">
  ISO 8601 date payment is due, or `null` if not set.
</ResponseField>

<ResponseField name="data.description" type="string | null">
  Notes shown on the invoice body. `null` if not set.
</ResponseField>

<ResponseField name="data.footer" type="string | null">
  Footer text shown at the bottom of the invoice. `null` if not set.
</ResponseField>

<ResponseField name="data.subtotal" type="integer">
  Sum of all line totals before discounts and tax, in minor units.
</ResponseField>

<ResponseField name="data.discount" type="integer">
  Total discount applied across all line items, in minor units.
</ResponseField>

<ResponseField name="data.taxable" type="integer">
  Taxable base amount (subtotal minus discount), in minor units.
</ResponseField>

<ResponseField name="data.tax" type="integer">
  Total tax charged, in minor units.
</ResponseField>

<ResponseField name="data.total" type="integer">
  Grand total (taxable + tax), in minor units.
</ResponseField>

<ResponseField name="data.amount_due" type="integer">
  Amount currently owed, in minor units. `0` for `draft`, `paid`, and `void` invoices. Equals `total` for `open` and `overdue` invoices.
</ResponseField>

<ResponseField name="data.amount_in_words" type="string | null">
  The total expressed as words. `null` if not generated.
</ResponseField>

<ResponseField name="data.public_url_token" type="string | null">
  Token component of the shareable public invoice URL. `null` until finalized.
</ResponseField>

<ResponseField name="data.finalized_at" type="string | null">
  ISO 8601 datetime of finalization, or `null` for drafts.
</ResponseField>

<ResponseField name="data.paid_at" type="string | null">
  ISO 8601 datetime payment was recorded, or `null`.
</ResponseField>

<ResponseField name="data.voided_at" type="string | null">
  ISO 8601 datetime the invoice was voided, or `null`.
</ResponseField>

<ResponseField name="data.void_reason" type="string | null">
  Reason provided when voiding, or `null`.
</ResponseField>

<ResponseField name="data.created" type="string">
  ISO 8601 datetime the invoice record was created.
</ResponseField>

<ResponseField name="data.updated" type="string">
  ISO 8601 datetime of the last modification to the invoice record.
</ResponseField>

<ResponseField name="data.lines" type="object">
  Always present on retrieve. Contains a `data` array of line item objects.
</ResponseField>

<ResponseField name="data.lines.data[].id" type="string">
  Unique identifier for the line item, prefixed `ii_`.
</ResponseField>

<ResponseField name="data.lines.data[].object" type="string">
  Always `"invoiceitem"`.
</ResponseField>

<ResponseField name="data.lines.data[].price" type="string | null">
  The `price_…` public ID of the catalog price, or `null` for ad-hoc lines.
</ResponseField>

<ResponseField name="data.lines.data[].product" type="string | null">
  The `prod_…` public ID of the parent product, or `null` for ad-hoc lines.
</ResponseField>

<ResponseField name="data.lines.data[].description" type="string">
  The description of this line item.
</ResponseField>

<ResponseField name="data.lines.data[].quantity" type="number">
  Number of units billed.
</ResponseField>

<ResponseField name="data.lines.data[].unit" type="string">
  Unit of measure code (e.g. `"HRS"`, `"NOS"`, `"KGS"`).
</ResponseField>

<ResponseField name="data.lines.data[].unit_amount" type="integer">
  Price per unit in minor units.
</ResponseField>

<ResponseField name="data.lines.data[].amount" type="integer">
  Line total after applying `discount_percent`, in minor units.
</ResponseField>

<ResponseField name="data.lines.data[].discount_percent" type="number">
  Percentage discount applied to this line (0–100).
</ResponseField>

<ResponseField name="data.lines.data[].tax_rate" type="number">
  Tax rate applied to this line as a percentage (0–100).
</ResponseField>

<ResponseField name="data.lines.data[].tax_amount" type="integer">
  Tax amount charged on this line, in minor units.
</ResponseField>

***

## Error Codes

| HTTP Status | `code`         | Meaning                                                                      |
| ----------- | -------------- | ---------------------------------------------------------------------------- |
| `401`       | `unauthorized` | Missing or invalid `Authorization` header.                                   |
| `403`       | `forbidden`    | Token does not carry the `invoices:read` scope.                              |
| `404`       | `not_found`    | No invoice with that ID exists, or it belongs to a different account.        |
| `429`       | `rate_limited` | Per-credential rate limit exceeded. Check the `Retry-After` response header. |
