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

# Invoice line item object

> The seven values Beacon publishes about each invoice line — the amount, the period it covers, and what it was for. This is where recurring revenue comes from.

The invoice line item object carries seven values about each line on an invoice, at one row per line, and two timestamps that accompany every one of them on every door: `as_of` and `computed_at`.

**This is the object recurring revenue is actually built from.** Not the subscription — the line. A subscription says an agreement exists; the line says what was charged, for what, and for which period. When those two disagree, the line is what happened.

<Note>
  The names, types and availability below are fixed. No read interface or MCP tool serves them yet — this page publishes the shape ahead of the doors.
</Note>

On the read interface this object is `invoice_line_item`. **The collection name is not published yet** — it lands with the [API reference](/api-reference) rather than being fixed here.

## Example payload

```json theme={null}
{
  "object": "invoice_line_item",
  "id": "il_2026_0412_1",
  "as_of": "2026-08-05T06:00:00Z",
  "computed_at": "2026-08-05T06:11:48Z",
  "line_amount": 18000.00,
  "period_start": "2026-07-01",
  "period_end": "2027-06-30",
  "subscription_id": "sub_10442",
  "product_id": "prod_pro_annual",
  "quantity": 1,
  "discount_amount": 0.00,
  "is_direct_income": null
}
```

## Attributes

| Value | Type | Method | What it holds |
| - | - | - | - |
| `as_of` | Timestamp, UTC | System | The moment the value describes. Present on every response and every property. |
| `computed_at` | Timestamp, UTC | System | When Beacon last read or worked the value out. Present on every response and every property. |
| `line_amount` | Number, in the invoice's currency | Measured | The amount of the line, **after discounts and before tax** — see below. |
| `period_start` | Date, or null | Measured | The first day of the period the line covers. **Not always delivered** — see below. |
| `period_end` | Date, or null | Measured | The last day of the period the line covers. **Not always delivered** — see below. |
| `subscription_id` | String, or null | Measured | The [subscription](/data-model/subscription) the line belongs to. |
| `product_id` | String, or null | Measured | The [product](/data-model/product) the line was for. |
| `quantity` | Number | Measured | How many units the line charges for. |
| `discount_amount` | Number, in the invoice's currency | Measured | The discount applied to the line, including its share of any discount applied to the invoice as a whole. Already reflected in `line_amount`; published so the gross figure can be reconstructed. |
| `is_direct_income` | Boolean, or null | Measured | Whether the line is direct income. **Delivered by some accounting systems only**; null where your source does not publish it. |

## One amount, three conventions, one published basis

**Every billing and accounting system reports a line amount slightly differently**, and the differences are the kind that produce a wrong figure which still balances.

* Some publish the amount in minor units — cents rather than euros.
* Some publish a figure that includes tax, with the tax broken out beside it.
* Some publish a figure that excludes tax already, and a sibling field on the same line that includes it — **with the same name another system uses for the opposite thing.**

Beacon publishes one basis on this object: **after discounts, before tax**, in the invoice's currency, in major units. The conversion happens once, on the way in, in a declared and version-pinned step, per source system. **It is not left to be handled at the point of use**, because the failure it prevents is a revenue figure that is wrong by exactly your tax rate and looks entirely plausible.

## The period is the value that varies most by source, and it is stated rather than smoothed over

**How much Beacon knows about which months a line covers depends on where the line came from.**

**Both dates delivered.** Subscription platforms typically publish a start and an end on each line. The period is read directly and the amount is spread across exactly the months it covers. Two lines on one invoice covering different periods — an annual subscription and a quarterly true-up — are handled correctly, because each line carries its own window.

**One date delivered.** Some accounting systems publish a single service date per line. That says when the period starts but not how long it runs, so the length comes from the [product's declared billing cycle](/data-model/product). Accurate where the product is billed the way it is declared; not where the same product is sold on two different billing cycles.

**No date delivered.** Some accounting systems publish nothing at line level at all. Every line on the invoice inherits the invoice's own date, and the length again comes from the declared billing cycle. **On this path, two lines covering genuinely different periods cannot be told apart from what the source sends** — and Beacon says so rather than presenting a figure with a confidence the data does not carry.

**Where the period cannot be established, the figure is marked provisional.** Storing the line makes the ambiguity visible and checkable. It does not make it resolvable, and the two are not the same thing.

## How a line becomes monthly revenue

The amount is spread across the calendar months the period covers, rather than landed whole in the month of the invoice. **The parts always sum back to the line** — spreading redistributes a figure, it never changes its total.

A one-off charge does not spread. It is not recurring revenue, and it is not treated as a short subscription.

## Availability

**Nothing on this object is served on any door today**, and which values will be available on the read interface, in MCP tools, on events and as CRM properties **has not been settled for this object yet.** It is left unstated here rather than guessed at, and it lands with the same act that publishes the collection.

**What is settled is the audience ceiling: every value on this object sits at `operational`**, derived the same way as on the [invoice](/data-model/invoice).

## Freshness

| Value | Recomputed | Sealed |
| - | - | - |
| All values | On each sync from your billing or accounting system | Inside the locked record of every period the line's amount was spread across |

**A line can be spread across several periods, and it is sealed into each of them.** That is deliberate: a locked month has to be reproducible from the lines that produced it, and a line covering twelve months contributed to twelve locks.

**Retaining the lines behind a sealed period — so that re-running a locked month reproduces it rather than re-querying a source that may have been restated since — is a commitment Beacon is building to, not one it meets today.** It is stated here because it is the reason the lines are kept at all, and because a reproducibility promise that is not yet met should be visible rather than assumed.

## Versioning

The published object is versioned separately from Beacon's internal model. A value is never removed from a published version — it is deprecated, and the removal lands in the next version. A published name is permanent; a rename ships as a redirect.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.