
The Algorithm Models page.
GET /api/v1/algorithm-models
List all algorithm models. Supports cursor-based pagination.Response
POST /api/v1/algorithm-models
Create a new algorithm model.Request Body
outcomeWeights, interactionFeatures, and evolutionConfig are not accepted on create — the create schema silently drops them. Set them via PUT /api/v1/algorithm-models/{id} after the model exists.Defaults are intentionally conservative. A POST with no overrides creates a fully inert model:
status: "draft", registryStatus: "draft", autoLearn: false, learnMode: "none". It exists in the DB but doesn’t score traffic, isn’t a champion, and won’t retrain. To make it actually do something see the explicit 4-step path in Model lifecycle.Validation
All fields are validated via Zod schemas:key: 1-255 characters, must be unique per tenant.name: 1-255 characters.modelType: Must be one of the nine enum values listed above.status: Defaultdraft. One of:draft,active,paused,archived.config,metrics,modelState,learningConfig: JSON objects (max 100 keys each; keys named__proto__,constructor, orprototypeare rejected). These limits apply to every JSON-object field across the API.predictors,metricsHistory: JSON arrays (max 500 items each).
Example
Error codes
Response:
201 Created
GET /api/v1/algorithm-models/
Get model details including version history. Response:200 OK with the model object and versions array.
PUT /api/v1/algorithm-models/
Update a model’s configuration, status, metrics, or learning config.Request Body
All fields are optional. Only provided fields are updated.
Response:
200 OK
DELETE /api/v1/algorithm-models?id=
Hard-deletes a model permanently. Unlike decisioning gates and contact policies, algorithm models use hard delete (the record is physically removed from the database).Query parameters
Error codes
Response:
204 No Content
POST /api/v1/algorithm-models//score
Score a single customer against the model.Request Body
Response
The response shape depends on model type. The common field isscore:
There is no
contributions array in the response. Use explanations for per-predictor or per-offer breakdowns (available for scorecard, bayesian, logistic_regression, gradient_boosted, thompson_bandit, and epsilon_greedy model types).POST /api/v1/algorithm-models//score-offer-set
Score a set of offers for a customer. Returns per-offer propensity scores with optional interaction history features.Request Body
Response
Scores are returned sorted byscore descending — the array index itself is the rank (index 0 = highest score).
There is no
rank field in the response. The array order IS the ranking — index 0 is the highest-scored offer. If customerId is provided, interactionFeatures will be populated from the customer’s recorded interaction history (impressions, click rate, conversion rate per offer).POST /api/v1/algorithm-models//train
Train (or retrain) a model using the per-model training route. Creates a new version snapshot and updates metrics history. Requires at least 50 interaction records in the tenant.Response
200 OK — Returns the updated model with incrementedversion, refreshed metrics, and status set to "active".
422 Unprocessable Entity — Returned when the training request is well-formed but can’t proceed:
503 Service Unavailable —
error.code: "ML_WORKER_UNAVAILABLE", retryable: true. Returned when a gradient_boosted model is trained but the Python ML Worker (ML_WORKER_URL) is unreachable. The error message is surfaced verbatim (“Training requires the Python ml-worker service. Scoring remains available on the last trained model.”), so the model keeps scoring on its previously-trained state. All in-process model types (bayesian, scorecard, thompson_bandit, neural_cf, online_learner) train without the worker and are unaffected.
Training requires interaction data recorded via the Respond API. New tenants with no interaction history will receive a 422 until enough outcomes are recorded. Models can still be used for scoring without training — scorecard models use bin-based rules, and other model types use default priors.
POST /api/v1/algorithm-models/train
Bulk-train a model from real interaction outcomes. This is the recommended training endpoint — it replays the tenant’s recorded outcomes through the model’s training routine, updateslastTrainedAt, increments version, and creates a model version snapshot for rollback.
Supported model types
All built-in model types are supported:Request Body
Response
Error responses
Failures are classified rather than collapsed into a single status. The body carrieserror.code and (for transient conditions) error.retryable.
POST /api/v1/algorithm-models//upgrade
Upgrade a model to the next tier along the progressionscorecard → bayesian → logistic_regression → gradient_boosted. Optionally creates a champion/challenger experiment. Upgrading to gradient_boosted requires the ML Worker to be reachable.
Request Body
Response
201 Created
GET /api/v1/algorithm-models//evolution-history
View model evolution config, progress toward the next tier, and a timeline of version transitions.Response
POST /api/v1/algorithm-models//reset-offer
Reset or pause adaptive learning for a specific offer, category, channel, or globally.Request Body
Response
POST /api/v1/algorithm-models//reset-learning
Reset a model’s learned state back to fresh defaults. Creates a pre-reset version snapshot, clears metrics/metricsHistory, resets trainingSamples to 0, and sets status to"draft".
Response
200 OK — Returns the model with cleared state:GET /api/v1/algorithm-models//adaptations
List the model’s per-scopeModelAdaptation rows (the hierarchical offer → category → channel → global posteriors that drive adaptive learning). Useful for ops debugging and as the data source for the Model Health “Adaptations” panel.
Query parameters
Response
Rows are grouped underbyScope, keyed by scope name. Each row carries scope, scopeId, positives, negatives, evidence, positiveRate, paused, decayedAt, and updatedAt.
Error codes
GET /api/v1/algorithm-models//uplift
Per-offer Conditional Average Treatment Effect (CATE) estimates for one customer, using T-learner or X-learner metalearners over the model’s stored adaptations (marginal mode) or per-row-fitted base learners (fitted mode).Query parameters
Response
segment is one of persuadable, sure_thing, lost_cause, sleeping_dog, or uncertain. When no offers are in scope, offers is empty and a note explains why.
Error codes
GET /api/v1/models//registry
Read the model’s current registry metadata: status, family label, last promotion timestamp, and snapshot metrics. The lookup is filtered by tenant.This endpoint lives at
/api/v1/models/[id]/registry — note the models prefix (not algorithm-models). It is the model-registry promotion surface, separate from the model CRUD routes documented above.Path Parameters
Response
string
One of
draft, challenger, champion, archived.string
Family label that groups models for the “one champion per family” invariant. Defaults to the model name when not explicitly set.
Status codes
POST /api/v1/models//registry
Promote or demote a model. Enforces a legal-transition matrix and the “one champion per family” invariant — promoting a model tochampion demotes any existing champion in the same family inside the same database transaction. Every status change writes one audit-log entry (best-effort, after the core transaction commits).
Legal status transitions
Any other transition is rejected with
400 Bad Request and an error code of invalid_transition.
Request Body
string
required
Target status. One of
draft, challenger, champion, archived.string
Operator id or system label for the audit row. Defaults to
"system" when omitted.object
Map of
metric → number recorded alongside the promotion (e.g., { auc: 0.79, accuracy: 0.83 }). Used by the W6.2 auto-rollback guard to compare a candidate champion against the incumbent.Response
string
Present only when the promotion to
champion displaced an incumbent in the same family. The incumbent’s status is set to challenger in the same transaction.array
Present when the W6.2 rollback guard reported breached thresholds but the promotion was still permitted (e.g.,
bypassRollbackGuard: true). Each entry: { signal, value, threshold }.Status codes
Roles
POST: admin only. GET: admin, editor, viewer.Roles
See also: Algorithms & Models