Skip to main content
The Beacon Data API is how your own systems read Beacon’s figures — your warehouse, your BI tool, your scripts. It publishes a small, stable set of values about your accounts, your deals, your segments, your cohorts, your company as a whole, your chart of accounts and your posted ledger, and nothing else.
Nothing serves this API yet. There is no address to call, no key to hold, and no Beacon deployment that answers it. This page publishes the contract ahead of the build, so the names and shapes are fixed before anything is written against them.Read it to plan an integration. You cannot build one against it today.
Version PUB-2026.09.16-v0.7. This contract has its own version, separate from Beacon’s internal one. Beacon can change how it works inside without changing what you read here.

What you can read

Seven collections. All seven accept entity_scope, which narrows the read to one entity inside your grant and can only ever narrow it, and page, which is an opaque cursor from the previous response rather than an offset. Three collections are not about a customer: GET /periods, GET /chart-of-accounts and GET /ledger-entries. A key covers exactly one company, so the company half of the period object’s name is not in the address — a period is a period of yours, and a period is a month, a quarter, a year or the trailing twelve months.

The values on each

The values, their types and what each one holds are the account object, the deal object, the segment object, the cohort object, the company and period object, the chart of accounts object and the ledger entry object. This page does not restate them. Sixteen account values, seven deal values, six segment values, six cohort values, thirteen company-and-period values, fourteen chart-of-accounts values and eight ledger-entry values are published through this API, plus as_of and computed_at, which travel with every one of them. The chart of accounts and the posted ledger joined in v0.6, at the addresses their object pages have named since 2026-09-01. Neither is a customer record, so neither reaches your CRM. Nothing on either is produced yet. One authored segment value is not among them. Beacon holds seven at that level; one describes how the segment was cut, and it is held back on every read door while a question about how it is derived is still open. It is absent here rather than listed as unavailable. pipeline_velocity — how healthily a segment’s open pipeline is moving — joined in v0.4, and is the sixth segment value above. It was published on the segment object on 2026-08-29 and reached this API on 2026-09-14, as an addition; nothing already published changed. It is one figure read at more than one level, and the level is the object you read it on — the same measure is published for your company as a whole. The company-wide score is catalogued on the company and period object and is not yet in this contract: GET /periods reads thirteen values at this version, and the fourteenth arrives as an addition. A third level, by team, is deliberately not published anywhere: Beacon has no definition of a team to attach it to, so rather than return an empty one it declines the row outright. A value’s audience level says which reader may receive it under your grant. It is not a statement that the value can never leave Beacon. Each object page carries the level for every value it publishes; read it there rather than assuming a level from the grain.
Those counts are the values this API publishes, which is not the same as the values Beacon holds. Beacon authors seventeen values on an account and eight on a deal. One value at each level is written into the model but held back from publication until the work behind it is finished, so it is not readable here at any version.On the account that value is cost_to_serve_amount. On the deal it is a price-realization band, which the deal object does not list.A count of published values and a count of authored values are both correct and they are not the same number. Where you see a count, check which one it is.

What travels with every value

A value never arrives as a bare number. as_of and computed_at are both always present. They answer different questions and neither substitutes for the other: one tells you when something was true, the other tells you when Beacon last looked. For a figure built from several sources, the oldest source governs — a combined figure is only as current as its oldest ingredient, so Beacon never overstates how fresh something is. A value whose as_of cannot be established is not returned at all; you get a refusal instead of a number with a made-up timestamp. as_of_anchor carries basis, which says how the timestamp on a page of results was arrived at: stalest_row when the page returned rows and as_of is the oldest among them, or empty_collection when the page returned nothing, in which case as_of equals computed_at. That is stated rather than hidden, because a page with rows where the two are equal would be a defect, and you can only tell the two cases apart because the response says which one you have.

Refusals

When Beacon cannot serve a value it returns a named refusal and, where saying so would not disclose something beyond your access, what would make the value available. A refusal is a successful response carrying a reason — never a null, never a zero, and never a missing field. A null means something else: the value does not apply to that row. A top-level category has no parent; a category that is not a cost of service has no service layer. Only a value its object page marks “or null” can be null, and the page says when. A value that applies but is not available yet is always a refusal. Every refusal carries schema_version — the version of this contract it was issued under. It never carries Beacon’s internal version, which is what keeps the two independent. The five reasons are fixed. No sixth will be added without a published change.
The refusal model is published here as proposed. It is settled enough to build against and is not yet final.

What connects, and what it reads

A connecting system presents a key Beacon issued, over a bearer token. Beacon never holds your passwords to anything — the credentials you use with your own source tools stay in those tools and never pass through this API. That key resolves to one grant, which names a role and an entity scope. Everything served under it sits inside that access — never wider. What a grant states, and how to issue or revoke one, is on Access and grants. No such key can be issued today. The part of Beacon that issues them does not exist yet, and neither does the register of approved destinations that a key would be allowed to send data to.

What this API will not do

It does not write. This surface reads. Beacon writes back to your CRM through a separate path where every write is a draft a person approves, and nothing here can be turned into one. No open query. Every request names something Beacon already publishes, at a version. There is no query language and no expression field. Nothing worked out on request. Beacon serves what it has already computed. Ask twice, get the same answer twice. No raw billing lines. Individual invoice lines are never published by any Beacon interface. They are read when Beacon prepares your recurring-revenue figures and then discarded; there is no path to them here or anywhere else. No exact account or deal figure where Beacon publishes a band. On an account, recurring revenue arrives as mrr_band; on a deal, size arrives as deal_amount_band. Neither object publishes the exact amount today. Where Beacon does not already hold a band it refuses rather than working one out at the point of reading, and the boundaries of the bands it does hold are set from your own configuration rather than chosen by Beacon. The company total is different and is published exactly, on GET /periods. That is the one grain where an exact recurring-revenue figure is published today. Beacon’s own internal read surface is not published here, at any version. It is written in the column names of Beacon’s storage, so publishing it would turn every internal change into a change you would have to absorb. This contract exists to be the stable thing instead.

What this API does not cover

Beacon defines values beyond the seven above — target and plan figures, and further finance objects such as cash, runway and budget. Those are not on this API and are not declared here, and they are not yet published in any form. When a level becomes readable here, it will arrive as an addition rather than as a change to what is already published. Version v0.2 was the first instance of that — segments and cohorts joined on 2026-08-29 — v0.3 the second, company-level periods on 2026-09-14, v0.4 the third, pipeline_velocity joining the segment collection the same day, and v0.6 the fourth, the chart of accounts and the posted ledger on 2026-09-16. Nothing already published changed on any of the four.

Versioning

This contract’s version moves when this contract’s shape changes. It does not move when Beacon changes something inside, and Beacon’s internal version does not move when this one does. A new optional value, or a value becoming readable that was only declared, raises the version. A value never changes type, changes meaning, becomes required, or disappears inside a version. A published name is permanent; a rename ships as a redirect. Read the availability marker on each value before planning around it. Most values on all seven objects are declared and not yet produced — on GET /periods, GET /chart-of-accounts and GET /ledger-entries that is true of every value without exception — and reading one today would return not_computed rather than a number, if there were anything to read it from.