Deployments
Deploy a trained model
Create a deployment — put a completed training into live serving with one call.
Deploy a specific training of a pipeline. pipeline_id and
training_id are required; find training IDs in
Trainings.
curl -X POST "$API_BASE/v1/deployments" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Workspace-Id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"pipeline_id": "'$PIPELINE_ID'",
"training_id": "'$TRAINING_ID'",
"reason": "Beats current champion by 4 points"
}'from predictai import PredictAI
client = PredictAI(token="pa_live_…", workspace_id="ws_…")
data = client.deployments.post_deployments(json={
"pipeline_id": PIPELINE_ID,
"training_id": TRAINING_ID,
"reason": "Beats current champion by 4 points",
})
import { PredictAI } from "@predictai/sdk";
const client = new PredictAI({ token: "pa_live_…", workspaceId: "ws_…" });
const data = await client.deployments.postDeployments({
json: {
pipeline_id: PIPELINE_ID,
training_id: TRAINING_ID,
reason: "Beats current champion by 4 points",
},
});
{
"success": true,
"promotion_id": "7d3f92a1-…",
"pipeline_id": "9f2c41d8-…",
"training_id": "b81e57c3-…",
"deployment_type": "shared",
"status": "deploying",
"endpoint": "…/v1/models/model-b81e57c3",
"created_at": "2026-07-15T12:04:31Z",
"message": "Model promoted successfully - deployment in progress"
}A 200 means the deployment record exists and serving is coming up in
the background — status starts at deploying and moves through the
lifecycle. Poll
the pipeline's status,
or subscribe to deployment.updated on the workspace's
realtime channel.
Request body
| Field | Meaning |
|---|---|
pipeline_id required | The pipeline whose training you're deploying. |
training_id required | The specific training to serve. |
deployment_type optional | "shared", "dedicated", or "foundation". Auto-detected from the model's kind when omitted — and overridden for foundation models even when set. |
dedicated_config optional | Capacity configuration for Dedicated deployments: { "replicas": 2, "cpu": "500m", "memory": "1Gi" }. Ignored for Shared deployments. |
reason optional | Free-text note stored on the deployment for your audit trail. |
Response fields
| Field | Meaning |
|---|---|
promotion_id | The new deployment's ID — use it to inspect, retry, or delete. |
deployment_type | The resolved serving mode (after auto-detection). |
status | Starts at deploying; flips to deployed when serving is up. |
endpoint | Where the model will answer once ready — but prefer the stable inference routes, which survive redeployments. |
All deployments are treated the same — capacity is governed by your plan's deployment caps, and every deployment gets the standard serving resources.
Errors
| Status | Code | Why |
|---|---|---|
400 | VALIDATION_ERROR | Missing body, missing pipeline_id or training_id, or deployment_type isn't one of the accepted values. |
403 | FORBIDDEN | No access to the pipeline, or your organization role can't deploy models. |
403 | PLAN_FEATURE_REQUIRED | You requested a Dedicated deployment but your plan doesn't include dedicated hosting. |
403 | QUOTA_EXCEEDED | This workspace's deployment cap is reached. Caps are per workspace, and Shared and Dedicated have separate caps — see Billing. |
409 | ALREADY_PROMOTED | This training is already live with the same deployment_type; the details include the existing promotion_id. |
400 | PROMOTION_FAILED | The promotion couldn't start; the message says why. |
A quota rejection tells you exactly where you stand:
{
"error": {
"code": "QUOTA_EXCEEDED",
"message": "You have reached the maximum number of shared deployments for this workspace (3)",
"details": {
"deployment_type": "shared",
"current": 3,
"limit": 3
}
}
}Free a slot by unpromoting a deployment you no longer need, or upgrade your plan.

