Rolling-forecast
Rolling forecast: the forecast of profit and loss every company has for the next 12 periods, made by the system and rolled after each close from actuals and the run rate, never below what is already scheduled. Its versions are plans (plans).
| Operation | Summary | Scope | Idempotency-Key |
|---|---|---|---|
GET /v1/entities/{entity}/rolling-forecast |
Read the rolling forecast | read |
GET /v1/entities/{entity}/rolling-forecast
Read the rolling forecast
The company's rolling forecast as its latest roll made it: each period's revenue, expenses
and net income (closed periods as posted, open ones from the run rate, never below what is
scheduled), and the totals of the periods not closed yet. The system makes the forecast and
rolls it after each close; each roll is a draft a person approves (/v1/plans). 404
no_rolling_forecast before the first scheduled run made it. Nothing is posted.
| Required scope | read (admin implies every scope) |
| Operation id | get_rolling_forecast_v1_entities__entity__rolling_forecast_get |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | entity |
string | yes | Entity code, e.g. CH01 (GET /v1/entities). |
Example request
curl "$ERP_URL/v1/entities/CH01/rolling-forecast" \
-H "Authorization: Bearer $ERP_KEY"
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | RollingForecastOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"actuals_through": "2026-09",
"ahead": {
"expenses": "198000.00",
"net": "42000.00",
"revenue": "240000.00"
},
"currency": "CHF",
"entity": "CH01",
"link": "/plans/6f1c2a10-4b5e-4d7a-9a3b-2c1d0e9f8a7b",
"made_at": "2026-10-02T06:00:00Z",
"made_by_system": true,
"periods": [],
"periods_ahead": 12,
"plan_id": "6f1c2a10-4b5e-4d7a-9a3b-2c1d0e9f8a7b",
"status": "draft",
"version": 3,
"version_id": "7d2e3f40-5162-4c73-8d84-9ea5fb6c7d18"
}
Schemas
ForecastPeriod
| Field | Type | Required | Description |
|---|---|---|---|
revenue |
string | yes | Revenue, in the company's currency. |
expenses |
string | yes | Expenses, in the company's currency. |
net |
string | yes | Revenue less expenses: the net income. |
period |
string | yes | The fiscal period, YYYY-MM (fiscal year and number). |
start |
string (date) | yes | Its first day. |
end |
string (date) | yes | Its last day. |
actual |
boolean | yes | Closed: its figures are what was posted. |
scheduled |
boolean | yes | Some of its figures are what is already scheduled (recurring invoices, subscriptions, recurring journals, depreciation) rather than the run rate. |
ForecastTotals
| Field | Type | Required | Description |
|---|---|---|---|
revenue |
string | yes | Revenue, in the company's currency. |
expenses |
string | yes | Expenses, in the company's currency. |
net |
string | yes | Revenue less expenses: the net income. |
RollingForecastOut
| Field | Type | Required | Description |
|---|---|---|---|
entity |
string | yes | Code of the company. |
currency |
string | yes | Its functional currency: every amount is in it. |
plan_id |
string (uuid) | yes | The plan named Rolling forecast. |
version_id |
string (uuid) | yes | Its latest version, the last roll. |
version |
integer | yes | That version's number. |
status |
string | yes | That version's status (draft, submitted, approved, superseded): a roll is a draft until a person approves it. |
made_at |
string (date-time) | yes | When that version was made. |
made_by_system |
boolean | yes | The system rolled it (not a person). |
actuals_through |
string or null | yes | The last closed period whose actuals it holds; none before the first close. |
periods |
array of ForecastPeriod |
yes | Each period of the version, in order: the year's actuals, then the forecast. |
ahead |
ForecastTotals |
yes | The totals of the periods not closed yet. |
periods_ahead |
integer | yes | How many periods ahead covers. |
link |
string | yes | Where the app shows the plan. |