https://api.nozle.app/engine/api/v1/margin/*. They are GET requests, except POST /margin/simulate. The examples below use Node unless they show curl. Secret key required; with API key permissions, the key needs analytic:read.
When the analytics store cannot be reached or a query fails, these reads answer 503 with code: analytics_unavailable (before Engine 1.4.0, 500 internal_error). Retry later. A missing analytics schema answers 503 with code: analytics_schema_missing.
Overview revenue. GET /analytics/overview (the dashboard Overview) returns two kinds of revenue. The estimated usage revenue fields (total_revenue_cents, total_cost_cents, total_margin_cents, blended_margin_percent, previous_month_revenue_cents, revenue_mom_percent) come from usage events on standard charges, in USD cents, and are not invoiced revenue; label them “Estimated usage revenue”. The invoiced revenue fields are the fees, excluding tax, of finalized invoices issued in the month to date (UTC), not self-billed and without a lost payment dispute: invoiced_revenue_cents, previous_period_invoiced_revenue_cents and invoiced_revenue_mom_percent in currency, and invoiced_revenue_by_currency (currency, revenue_cents, previous_period_revenue_cents, mom_percent) per invoice currency. Subscription fees and graduated, package, volume and percentage charges count. period_start, period_end, previous_period_start and previous_period_end (end exclusive) state the two windows. Month over month compares equal windows: on October 2, October 1-2 against September 1-2, ending at the previous month’s last day when it is shorter. Before Engine 1.10.0 it compared the month to date with the whole previous month (-96.7% on October 2 with flat revenue). A failed read answers 503 analytics_unavailable.
In the dashboard, the MRR, ARR, Outstanding and Overdue tiles show the total in your default currency. An info icon beside the figure shows the per-currency split (“By currency: ₹143,994.00 · $153.00”), and appears only when more than one currency is involved.
Summary — overall margin overview:
new_price_dollars is the new price per unit, in dollars; cost stays as recorded. See Simulate Margin:
points, starting on the first UTC day the history does not reach: with a plain to date such as 2026-10-15 (which includes that day, so the range ends at 2026-10-16T00:00:00Z) the first point is 2026-10-16; an RFC3339 to at midnight starts on that day; a to with a time of day, such as the default range’s end (now), starts on the next day, so the default forecast starts tomorrow. projected_revenue, projected_cost and projected_margin are integer cents, although their names have no _cents suffix. confidence is low, medium or high, depending on how many days of the range have events. With fewer than 2 such days, points is an empty array and confidence is low.
Every endpoint accepts optional from and to parameters. Use a YYYY-MM-DD date or an RFC3339 timestamp (2026-07-01T09:30:00Z). A plain date to includes that whole day, while an RFC3339 to is an exclusive instant. The Python and Go SDKs send the same values as from_date and to_date, which the API accepts as aliases. These four names, and granularity on the trend, are the only query parameters the endpoints read. Other query parameters are ignored without an error.
If you send only one end, the API derives the other: only to covers the month before it, and only from runs until now (one month after from if it is not in the past). With neither, the range is the last month.
An unparseable value, or an end that is not after the start, returns 400 with {"code": "invalid_date_range", "error": "..."}. In the Node SDK the call throws a NozleApiError whose code is invalid_date_range:
- Node
- REST
{"models": []}, {"customers": []}, and so on).