Predict.aiDocs
Pipelines

Create & manage

Create, list, inspect, edit, and delete pipelines.

Create a pipeline

POST /v1/pipelines binds one or more models to a segment with a schedule and a promotion policy. A 201 means the pipeline exists — and if you didn't set a recurring schedule, one training run is queued immediately.

curl -X POST "$API_BASE/v1/pipelines" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Daily sales forecaster",
    "segment": "SEGMENT_ID",
    "workspace_id": "'$WORKSPACE_ID'",
    "models": [
      { "model": "MY_CUSTOM_MODEL_ID" },
      { "family": "predictfm", "slug": "predictfm-f-v0.1" }
    ],
    "forecast_horizon": 14,
    "training_schedule": {
      "start_time": "02:00:00",
      "end_time": "05:00:00",
      "days": ["monday", "thursday"],
      "frequency": "86400",
      "timezone": "UTC"
    },
    "promotion_policy": { "mode": "auto" }
  }'
{
  "data": {
    "uid": "9f2c41d8-…",
    "message": "Pipeline created successfully"
  }
}

Request body

FieldMeaning
name requiredDisplay name for the pipeline.
segment requiredThe segment this pipeline trains on.
workspace_id requiredMust match your X-Workspace-Id header — a mismatch is rejected with 400.
models requiredThe model pool — an array of entries, one per model that trains each run. See the entry shape below.
forecast_horizon optionalHow many steps ahead every model predicts. Pipeline-level and shared by all entries so cycle scores stay comparable. Defaults to 5.
training_schedule optionalWhen recurring runs fire. See the schedule shape below. Defaults to run once: no recurring runs, one immediate training at creation.
promotion_policy optionalWhat happens when a run finishes: { "mode": "manual" | "auto" | "off", "demote_previous": true }. Defaults to manual (winner waits for your decision); auto deploys the winner when it beats the serving version; off never proposes. demote_previous (default true) retires the previous deployment when a new one goes live.
retrain_triggers optionalRetrain when fresh data lands: { "on_new_data": { "enabled": false, "min_rows": …, "quiet_seconds": …, "max_wait_seconds": …, "cooldown_seconds": … } }. Disabled unless you turn it on.
budget optionalSpending guardrail: { "monthly_credit_cap": 500 }. When a month's training spend reaches the cap, scheduled runs stop until the month rolls over. null or 0 means no cap.
active optionalSet false to create the pipeline paused. Defaults to true.

The models array

Each entry references one model by its catalog ID — a custom model, a BYOM upload, or a foundation model, in any mix. The entries form a pool of equals: every run trains all of them, and the best score becomes the promotion candidate (see The model pool). You never say what kind a model is — the platform resolves that from the ID.

FieldMeaning
model requiredA catalog model ID — from your models or the foundation catalog. Omit it only when using the family + slug shorthand.
family optionalFoundation shorthand: the model family (e.g. predictfm, chronos_bolt). Use together with slug instead of model.
slug optionalFoundation shorthand: the model version within the family.
lookback optionalFoundation entries only. How much history the model consumes per sample. Defaults to 2048.
intensity optionalFoundation entries only. Fine-tuning effort: light, adapt (default), or deep. Deeper costs more and adapts more.

There's no cap on the number of entries — but every entry is one full paid training per run, governed by your credit balance, the pipeline's monthly budget, and your plan's training quotas.

One rule: a BYOM model must be the only entry. BYOM arrives pre-trained and can't race in a training cycle, so a BYOM pipeline references exactly one model and goes straight to deployment.

The training_schedule object

FieldMeaning
days optionalWeekdays the schedule fires, lowercase: ["monday", "thursday"]. An empty array means "run once" — no recurring runs; one training is queued immediately at creation.
start_time optionalStart of the daily window, HH:MM:SS. Defaults to 00:00:00.
end_time optionalEnd of the daily window, HH:MM:SS. Defaults to 23:59:59.
frequency optionalSeconds between runs inside the window, as a string. "86400" (the default) = once per day.
timezone optionalIANA timezone for the window, e.g. "UTC".

Validation before anything trains

Every entry is contract-checked at create time against the shared segment and forecast_horizon: data-sufficiency window math, label arity, and each foundation family's horizon cap. A model that can't train on this segment is rejected with a concrete message — nothing is charged.

Errors

StatusWhyExample message
400Missing field, workspace mismatch, a bad models entry, or the segment is too small for the requested horizon"Missing required field: segment"
400A BYOM model listed with other entries"BYOM models arrive pre-trained and can't race in a training cycle — a BYOM pipeline must reference exactly one model"
403No workspace access, no access to a referenced model, or plan quota reached"Pipeline limit exceeded. Your plan allows 5 pipelines per workspace."
404A referenced model or the segment doesn't exist"Segment with ID … not found in this workspace"

List pipelines

GET /v1/pipelines returns every pipeline in the workspace, newest first.

curl "$API_BASE/v1/pipelines?page=0&per_page=25" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "pipelines": [
      {
        "uid": "9f2c41d8-…",
        "name": "Daily sales forecaster",
        "segment_id": "SEGMENT_ID",
        "models": [
          { "model": "MY_CUSTOM_MODEL_ID", "kind": "custom" },
          { "model": "pfm__predictfm-f-v0.1", "kind": "foundation",
            "family": "predictfm", "slug": "predictfm-f-v0.1" }
        ],
        "active": true,
        "in_training": false,
        "accuracy_score": 0.94,
        "top_model": { "uid": "TRAINING_ID", "score": 0.94 },
        "latest_training_status": "completed",
        "promotion_policy": { "mode": "auto", "demote_previous": true },
        "has_pending_promotion": false,
        "schedule": { "days": ["monday", "thursday"], "frequency": "86400" },
        "created_at": "2026-07-15T08:30:00+00:00"
      }
    ],
    "total_count": 1,
    "page": 0,
    "per_page": 25,
    "total_pages": 1
  }
}

Query parameters

ParameterMeaning
page optionalZero-based page number. Defaults to the first page.
per_page optionalRows per page. Defaults to 100.
sort_column optionalField to sort by. Defaults to created_at.
sort_direction optionalasc or desc (default).

Response fields

FieldMeaning
modelsThe pool, with each entry's resolved kind (custom, byom, foundation) and — for foundation entries — family + slug.
activeWhether scheduled and triggered runs fire. Paused pipelines also refuse manual training.
in_trainingtrue while a run is in flight.
accuracy_score / top_modelThe best score so far, and which training produced it.
latest_training_statusStatus of the most recent run: queued, running, completed, failed.
has_pending_promotiontrue when a winner is waiting for your promotion decision (manual mode).
scheduleThe recurring schedule, echoed back.

Inspect one pipeline

GET /v1/pipelines/{id} returns the full pipeline document — the same fields as a list row, plus the automation state (budget, budget_state, retrain_triggers) and aggregate training cost. For the run-by-run history, use Trainings.

curl "$API_BASE/v1/pipelines/$PIPELINE_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"

Errors

StatusWhyExample message
404The pipeline doesn't exist in this workspace, or you can't access it"Pipeline with ID … not found"

Edit a pipeline

PUT /v1/pipelines/{id} — send only the fields you're changing.

curl -X PUT "$API_BASE/v1/pipelines/$PIPELINE_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'
{ "data": { "message": "Pipeline updated successfully" } }

Request body

All fields optional — anything omitted keeps its current value.

FieldMeaning
name optionalRename the pipeline.
active optionalfalse pauses the pipeline: scheduled runs stop firing and train refuses until re-enabled.
models optionalReplace the model pool — same shape as create. Re-validated against the segment and horizon before saving.
segment optionalMove the pipeline to a different segment. Every pool entry is re-validated against it.
forecast_horizon optionalChange the prediction horizon. Re-validated against segment size and each foundation entry's cap.
training_schedule optionalReplace the recurring schedule — same shape as create.
promotion_policy optionalChange the automation mode or demote_previous.
retrain_triggers optionalEnable/disable or retune the new-data trigger.
budget optionalChange or clear the monthly credit cap.

BYOM pipelines are bound to their uploaded model at creation — the models list can't be changed afterwards, and a BYOM model can't be swapped into an existing pipeline. Create a new pipeline instead.

Errors

StatusWhyExample message
400A bad models entry, the post-edit contract fails, or a BYOM swap was attempted"Model '…': segment has too few rows for the requested horizon"
404The pipeline or the new segment doesn't exist in this workspace"Pipeline with ID … not found or you don't have permission to edit it"

Delete a pipeline

DELETE /v1/pipelines/{id} removes the pipeline and its schedule.

curl -X DELETE "$API_BASE/v1/pipelines/$PIPELINE_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{ "data": { "message": "Pipeline deleted successfully" } }

Deleting a pipeline doesn't tear down its live deployment — unpromote first if one is serving.

Errors

StatusWhyExample message
400The pipeline is mid-training — wait for the run to finish"Cannot delete a pipeline while it is training"
404The pipeline doesn't exist in this workspace"Pipeline with ID … not found"

On this page