Skip to main content

Revenue recognition

Deferred revenue answers one finance question: how much of what customers already paid have you actually earned, and how much is still deferred. When your account carries a committed-use commitment (a negotiated prepaid minimum commit) or recurring subscription invoice lines, that money is received up front but earned over a service window. Until it is earned it sits on the books as deferred revenue, not recognized revenue. Orbit turns the contracts you already have into ratable straight-line recognition schedules — the per-month amounts a finance team books under ASC 606 — computed on demand from your committed-use commitment and your subscription invoices. Nothing has to be configured: no upload, no schedule construction, no mapping table. Two endpoints and one dashboard page cover the whole surface:
  • GET /api/v1/billing/revenue-recognition/schedule — the per-contract recognition schedule, one entry per calendar month.
  • GET /api/v1/billing/revenue-recognition/summary — the rollup: recognized-to-date vs. remaining-deferred as of a reporting date, plus the recognized amount in each period.
  • Dashboard → Billing → Revenue recognition — the same data, read-only.
Everything on this surface is read-only. It moves no money, issues no charge, and writes no record — each call recomputes the schedule from the live contract data at request time. Both endpoints require the owner, admin, or billing role.

1. What revenue recognition answers

Split every contract’s value into two buckets as of a reporting date:
  • Recognized to date — the share of the contract value earned up to the reporting date, prorated straight-line across the service window.
  • Deferred remaining — the share not yet earned. Still a liability; it converts to recognized revenue as the window elapses.
Recognized + deferred always equals the total contract value — the summary reconciles by construction, so it can tie straight into a deferred-revenue roll-forward. The by-period view then answers the second question — how much revenue lands in each calendar month — summed across all contracts.

2. The two endpoints

Both endpoints accept one optional query parameter:

2.1 Per-contract schedule

GET /api/v1/billing/revenue-recognition/schedule returns one recognition schedule per contract — your committed-use commitment plus each recognizable subscription invoice line.
Top-level fields: Per-schedule fields:

2.2 Recognized-vs-deferred summary

GET /api/v1/billing/revenue-recognition/summary rolls every contract up into org-level totals.

3. The straight-line model

The model is deliberately simple — the same ratable treatment the leading usage-billing platforms apply:
  • Committed-use commitment. The total contract value is the monthly commit × the number of whole months in the contract term, recognized straight-line over the term. When the commitment carries no term dates, the schedule falls back to the current billing period — one month recognizing the monthly commit — so a schedule always exists.
  • Subscription invoice lines. Each positive-amount line on a subscription invoice recognizes over the line’s own service window; when the line has none, the window falls back to the invoice’s billing period, then to the invoice-date month.
Recognition within a window is straight-line by day: each month recognizes a share proportional to the number of window days inside it, so February earns less than January in a flat-rate schedule. A cumulative rounding method keeps the period entries summing to the contract total exactly — the final period absorbs any residual cent, so the schedule never drifts off the invoice amount. Amounts are computed in integer cents, never floating point. Assumptions to be aware of:
  • The split is prorated to the exact reporting instant — a mid-month as_of recognizes the elapsed fraction of that month, not the whole month.
  • Credit and zero-amount invoice lines do not recognize and are excluded.
  • The rollup requires one currency; it reports the commitment’s currency, else the currency of the first subscription line, else USD.

4. Dashboard walkthrough

The same two reads render under Dashboard → Billing → Revenue recognition. The page is read-only — it reflects your contracts; it does not edit them — and it is gated to the owner, admin, and billing roles, matching the API.
  • Stat cards — total contract value, recognized to date, and deferred remaining across all contracts.
  • Recognized by period — the cross-contract table of revenue per calendar month.
  • Per-contract schedules — one card per contract with its source badge (Committed-use or Subscription), service dates, recognized/deferred split, and the month-by-month schedule table.
Report-date semantics match the API: the page reports as of the current time. For a historical reporting date, pass as_of on the API. An account with no committed-use commitment and no subscription invoices sees an empty state explaining when schedules appear — nothing is broken.

5. Finance-ops use

Month-end close. Pull the summary with a fixed as_of — e.g. as_of=2026-08-31 for the August close — so rerunning the report later reproduces the same figures instead of rolling with the clock. The recognized/deferred totals book as the period’s recognition entry; because they reconcile to contract value exactly, the deferred balance rolls forward without a plug. Export. The JSON responses are stable-schema and integer-exact; pipe them into your close tooling, or read the same tables in the dashboard and copy the per-period rows. Limits and edge cases:
  • Subscription history window. Subscription lines come from the most recent invoice page (up to 50 invoices). Long-lived accounts should treat the commitment as the primary multi-year source and the subscription lines as the recent-period complement.
  • Commitment without a term. A commitment with no term dates recognizes the monthly commit inside the current billing period — a useful default, not a multi-year schedule. Have your Devotel account team set the term for the full picture.
  • Subscription lines fail open. If the billing provider read is unavailable, the endpoints still return the committed-use schedule — the summary degrades rather than errors.
  • Not a revrec ledger. The schedule is computed on demand from live contract data; renegotiating a commitment restates the whole schedule. There is no stored history to drift — the contract is the record.