Schedules
Schedules and recurring forecasts
Create recurring forecast jobs that fetch source data on a cron schedule and deliver outputs to a webhook.
Why schedules exist
Schedules are for recurring forecast jobs where TSFM.ai should fetch the data source, run the model on a fixed cadence, and deliver the result without another orchestrator building each request by hand. Each account can have up to 20 active schedules.
- Daily or hourly forecasts that should run without a separate orchestrator invoking `/v1/forecast` manually.
- Pipelines where the source data already lives behind a stable URL and the result should be pushed to a webhook or internal service.
- Operator workflows that need run history, failure counts, and next-run visibility as part of normal monitoring.
Create a schedule
Use the same forecast contract, then add cadence and delivery
A schedule wraps the normal forecast parameters with data-source and delivery settings. The forecasting portion should already be known-good from direct API testing before you automate it.
Core schedule fields
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Human-readable schedule name. Keep it stable enough to show up cleanly in dashboards, alerts, and webhook consumers. |
| model | string | Yes | Hosted model id to invoke on each run. Reuse the same ids you would send directly to /v1/forecast. |
| source_url | https URL | Yes | Remote file or service endpoint that the schedule fetches at run time before normalizing into a forecast payload. |
| cron_expression | string | Yes | UTC cron schedule that controls when runs start. Choose a cadence that matches the upstream data refresh cycle. |
| parameters | object | Yes | The same forecast parameters object you use with /v1/forecast, including prediction_length, freq, and optional quantiles. |
| callback_url | https URL | Conditional | Webhook destination for completed forecasts. Use when results need to land in an application or automation pipeline immediately. |
| callback_secret | string | Conditional | Shared secret for verifying delivery signatures or authenticating webhook receivers. |
curl -X POST https://api.tsfm.ai/v1/schedules \
-H "Authorization: Bearer $TSFM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "daily-store-017",
"model": "amazon/chronos-bolt-small",
"source_url": "https://static.tsfm.ai/examples/store-017.csv",
"cron_expression": "0 6 * * *",
"parameters": {
"prediction_length": 7,
"freq": "D",
"quantiles": [0.1, 0.5, 0.9]
},
"callback_url": "https://ops.acme.com/webhooks/forecast",
"callback_secret": "whsec_example"
}'{
"schedule": {
"id": "40f78e2d-5d4c-4ff6-84c0-5514d1ce5ed1",
"user_id": "44d1e8a7-8b33-4dcf-a65a-b8a8e02ca9aa",
"name": "daily-store-017",
"status": "active",
"model": "amazon/chronos-bolt-small",
"source_url": "https://static.tsfm.ai/examples/store-017.csv",
"cron_expression": "0 6 * * *",
"parameters": {
"prediction_length": 7,
"freq": "D",
"quantiles": [0.1, 0.5, 0.9]
},
"callback_url": "https://ops.acme.com/webhooks/forecast",
"next_run_at": "2026-03-18T06:00:00+00:00",
"last_run_at": null,
"run_count": 0,
"error_count": 0,
"created_at": "2026-03-17T09:00:00+00:00",
"updated_at": "2026-03-17T09:00:00+00:00"
}
}tsfm call createSchedule \
--base-url https://api.tsfm.ai \
--api-key "$TSFM_API_KEY" \
--body '{
"name": "daily-store-017",
"model": "amazon/chronos-bolt-small",
"source_url": "https://static.tsfm.ai/examples/store-017.csv",
"cron_expression": "0 6 * * *",
"parameters": {
"prediction_length": 7,
"freq": "D",
"quantiles": [0.1, 0.5, 0.9]
},
"callback_url": "https://ops.acme.com/webhooks/forecast",
"callback_secret": "whsec_example"
}' \
--jsonManage schedules
Full lifecycle management
Beyond creation, the API exposes endpoints for listing, updating, pausing, resuming, deleting schedules, and inspecting run history.
Schedule endpoints
POST/v1/schedulesCreate a new scheduleGET/v1/schedulesList schedules (filter by status, limit, offset)GET/v1/schedules/{schedule_id}Get schedule detailsPATCH/v1/schedules/{schedule_id}Update schedule fieldsDELETE/v1/schedules/{schedule_id}Delete a schedulePOST/v1/schedules/{schedule_id}/pausePause a running schedulePOST/v1/schedules/{schedule_id}/resumeResume a paused scheduleGET/v1/schedules/{schedule_id}/runsList run history for a scheduleManage runs
Inspect execution history like an operator
A healthy schedule is more than “it exists.” Watch the run history, data volume, latency, and webhook outcomes so you can tell whether failures are happening at ingestion, inference, or delivery.
Run signals to monitor
| Field | Type | Required | Description |
|---|---|---|---|
| status | queued | running | succeeded | failed | No | Primary run outcome. Alert on repeated failed states instead of a single isolated transient error. |
| source_point_count | integer | No | Quick signal that the upstream data payload still contains the volume of history you expect. |
| latency_ms | number | No | End-to-end runtime for the schedule invocation. Track it over time to catch slow model or source regressions. |
| webhook_status / webhook_attempts | string / integer | No | Delivery health for downstream callbacks. Useful when the forecast succeeded but the consumer did not accept the result. |
{
"runs": [{
"id": "30d8d6ee-bae9-4f36-95f8-922587f9728c",
"schedule_id": "40f78e2d-5d4c-4ff6-84c0-5514d1ce5ed1",
"user_id": "44d1e8a7-8b33-4dcf-a65a-b8a8e02ca9aa",
"status": "succeeded",
"started_at": "2026-03-18T06:00:00+00:00",
"completed_at": "2026-03-18T06:00:03+00:00",
"source_url": "https://static.tsfm.ai/examples/store-017.csv",
"source_point_count": 365,
"model": "amazon/chronos-bolt-small",
"parameters": {
"prediction_length": 7,
"freq": "D",
"quantiles": [0.1, 0.5, 0.9]
},
"webhook_status": "200",
"webhook_attempts": 1,
"latency_ms": 942,
"created_at": "2026-03-18T06:00:03+00:00"
}]
}Operating tips
Make recurring jobs boring
- Validate the model and payload shape with direct `/v1/forecast` calls before you schedule anything recurring.
- Keep `source_url` outputs stable. Most schedule incidents come from upstream schema drift or empty files, not the forecast model itself.
- Log both run status and webhook delivery status so you can separate forecast failures from downstream ingestion failures.
- Rotate callback secrets on the same cadence as API keys and rehearse what happens when a consumer returns non-200 statuses.