Using the Forecasting Endpoint
![]()
Forecaster · v0.1
The POST /api/v1/forecasts endpoint produces probabilistic forecasts from a univariate time series. There are two models:
inertialai-forecast: a low-latency router over forecasting experts that returns calibrated quantiles. Use it for dashboards, automation, alerting, capacity planning, and high-volume jobs where signal history is enough.inertialai-forecast (reasoning)(inertialai-forecasting-reasoning): starts from the same forecast and applies audited adjustments — scale, shift, clip, or widen intervals — returning the adjusted forecast plus a rationale and adjustment trace. It reasons two ways: from the series itself (computing properties such as non-negativity and material recent volatility to fix calibration) and from any text or image context you supply.
Automatic routing: if you send
contexttext orimage_urlswith aninertialai-forecastrequest, it is automatically upgraded to the reasoning version (and billed as such).
The two modes at a glance
You control the mode entirely by what you send — you never have to change the model name:
| You send | Mode | What runs |
|---|---|---|
series + horizon only | Forecast-only | The probabilistic forecaster (time-series in → calibrated quantiles out). No LLM. |
…plus context text | Reasoning | Forecast + an audited, tool-constrained adjustment from your text (via OpenRouter). |
…plus image_urls (and/or context) | Multimodal reasoning | Same, but the model also reads the chart/screenshot images you attach. |
In other words: send just the time series for a pure forecast; add context and/or image_urls to switch on reasoning/multimodal. Sending either field auto-upgrades the request to the reasoning version.
Does reasoning improve a plain forecast?
Yes — modestly but measurably, even with no text context. By computing features of the series, the reasoning version fixes calibration errors the base forecaster leaves behind: it clips impossible sub-zero quantiles on non-negative series, rounds the forecast to integers for count series, and widens intervals when recent volatility rises materially. On GIFT-Eval (1624 windows, 16 datasets) this lowers normalised CRPS 1.49% and improves 80% interval coverage (0.737 → 0.774), with MASE roughly unchanged (integer rounding nudges it slightly better on counts). The response rationale also explains the forecast in plain language — its trend, volatility, and any adjustments.
Request Structure
Required Parameters
series: Univariate historical values, ordered oldest to newest. Minimum 4 points.horizon: Number of future steps to forecast (1–365).
Optional Parameters
model:inertialai-forecast(default) orinertialai-forecasting-reasoning.freq: Series frequency —"H","D"(default),"W", or"M".quantiles: Quantile levels to return. Must be sorted, between 0 and 1, and include0.5. Default[0.1, 0.5, 0.9].context: Operational text context (e.g."Promotion starts tomorrow; expect ~20% demand lift."). Supplying it routes the request to the reasoning version.image_urls: Optional chart or screenshot URLs for multimodal reasoning context (also routes to the reasoning version).reasoning_provider: Which backend resolves the contextual adjustment —"auto"(default),"openrouter", or"openai".autouses the provider InertialAI has configured (OpenRouter). There is no fallback — if the selected provider is unavailable or misconfigured, the request fails with a clear error rather than degrading to another provider.reasoning_model: The reasoning LLM ID, e.g."openai/gpt-5.5"(see the catalog below). Optional — leave unset to use the configured default. The exact model you pass is the model that runs.
Choosing the Reasoning Model
The forecaster is InertialAI's own model. The contextual reasoning step runs on a third-party LLM that you choose — so it is always clear what is the InertialAI model and what LLM is doing the reasoning. The model you select is the model that runs: there is no silent fallback.
Set reasoning_model to one of the curated, cost-laddered options below (routed via OpenRouter):
| LLM | Provider | Tier | Cost (output) |
|---|---|---|---|
mistralai/mistral-small-3.2-24b-instruct | Mistral | Small | ~$0.20 / 1M tok |
mistralai/mistral-medium-3.1 | Mistral | Medium | ~$2.00 / 1M tok |
openai/gpt-5.4-mini | OpenAI | Medium | ~$4.50 / 1M tok |
openai/gpt-5.5 | OpenAI | Large | ~$30 / 1M tok |
google/gemini-2.5-flash | Medium | ~$2.50 / 1M tok | |
google/gemini-3-flash-preview | Medium | ~$3.00 / 1M tok | |
anthropic/claude-sonnet-4.6 | Anthropic | Large | ~$15 / 1M tok |
anthropic/claude-opus-4.8 | Anthropic | Large | ~$25 / 1M tok |
Prices are the provider's output-token rate (indicative) — pick a smaller model from this catalog to keep the reasoning charge on your request smaller (see Billing).
- Pin a provider (
"openrouter"/"openai") withreasoning_modelwhen you need a specific model's capabilities or reproducibility.
Response
The response includes:
base_forecast: the forecast quantiles before any reasoning adjustment.final_forecast: the forecast after reasoning adjustments. For a plain forecast-only request this equalsbase_forecast.adjustments: the audited tool(s) applied, with parameters and a reason (empty when none).rationaleandinterval_explanation: short natural-language explanations. Quantiles are monotonically repaired after every adjustment.usage:prompt_tokens,completion_tokens,total_tokens, andcredits.
These usage headers are also set on the response:
x-api-total-request-token-countx-api-total-request-credits-used
Examples
1. Forecast-only
import requests
response = requests.post(
"https://api.inertialai.com/api/v1/forecasts",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"series": [18, 19, 21, 20, 22, 23, 24, 25],
"horizon": 7,
"freq": "D",
"model": "inertialai-forecast",
"quantiles": [0.1, 0.5, 0.9],
},
)
forecast = response.json()["final_forecast"]
2. Forecasting with reasoning
import requests
response = requests.post(
"https://api.inertialai.com/api/v1/forecasts",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"series": [18, 19, 21, 20, 22, 23, 24, 25],
"horizon": 7,
"freq": "D",
"model": "inertialai-forecasting-reasoning",
"context": "Promotion starts tomorrow; expected demand lift is about 20%.",
"reasoning_provider": "auto",
"reasoning_model": "openai/gpt-5.5",
},
)
body = response.json()
print(body["rationale"])
print(body["adjustments"]) # e.g. [{"tool": "scale", "parameters": {"factor": 1.2}, ...}]
print(body["final_forecast"]) # reasoning-adjusted quantiles
3. Multimodal reasoning (attach a chart)
Attach one or more image URLs (chart screenshots, dashboards) to give the reasoning
layer visual context. Images route the request to the reasoning version just like
text context does, and can be combined with context.
import requests
response = requests.post(
"https://api.inertialai.com/api/v1/forecasts",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"series": [18, 19, 21, 20, 22, 23, 24, 25],
"horizon": 7,
"freq": "D",
"context": "The attached chart shows a holiday spike we expect to repeat.",
"image_urls": ["https://example.com/demand-chart.png"],
},
)
body = response.json()
print(body["rationale"]) # explains how the chart/text influenced the forecast
print(body["final_forecast"]) # reasoning-adjusted quantiles
4. curl (forecast-only)
curl -X POST https://api.inertialai.com/api/v1/forecasts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"series": [18, 19, 21, 20, 22, 23, 24, 25],
"horizon": 7,
"model": "inertialai-forecast"
}'
Billing
Forecasts are charged in prepaid InertialAI credits — one billing surface across both stages:
inertialai-forecast: a small flat per-request fee plus a deterministic price per forecast point, where points =horizon × number of quantiles. The flat fee covers fixed compute overhead so even tiny forecasts are priced fairly.inertialai-forecasting-reasoning: the same request fee and per-point price as above, plus one additional usage-based charge — but only for calls that actually invoke an LLM. Self-reasoning from the series alone (nocontext/image_urls) costs the same as forecast-only.
Each response reports exact usage.credits and usage.total_tokens, and the same values are returned in the x-api-total-request-credits-used and x-api-total-request-token-count headers so you can track spend per request.