Skip to content

Assignments

Assignments are the recommended way for business workflows to run models. An assignment has a stable key, such as default or forecast, and points to one active model version in a domain or service scope.

Without assignments, consumers would need to know the exact model_id and model_version for each workflow. Assignments let the platform change the model version behind a stable key while callers keep using the same route.

ScopeRoute shapeUse when
Domain/v2/clients/{client_id}/domains/{domain_id}/assignments/{assignment_key}The capability belongs to the domain as a whole.
Service/v2/clients/{client_id}/domains/{domain_id}/service/{service_id}/assignments/{assignment_key}The capability belongs to one initialized service.

Each assignment key has one active revision. Creating a new revision archives the previous active revision for the same key. Historical jobs remain linked to the revision that launched them.

flowchart LR
    Key[assignment key forecast] --> Active[active revision]
    Active --> ModelVersion[model version]
    NewRevision[new revision] --> Active
    Active --> Archived[previous revision archived]

Run inference through the assignment job route. The response returns a job_id. Poll GET /v2/jobs/{job_id} to read status, output, and errors.

Assignments keep the caller insulated from model-version changes, but they do not hide async behavior. Always treat assignment execution as a job lifecycle.

When you create or update a domain assignment (POST or PUT on the domain assignments collection or keyed route), the API checks every non-departed service in the domain. If any service’s provided_features cannot be resolved against the target model version’s frozen feature schema, the request fails with HTTP 422 and a structured body (not the usual { success, message } envelope). Other semantic failures on those routes — for example, an invalid model reference — still use the standard error envelope.

{
"error": "cannot assign model version 3: 2 service(s) have incompatible provided_features",
"blocking_services": [
{ "service_id": "svc-a", "feature": "cabin_category", "value": "unknown" }
]
}
FieldMeaning
errorHuman-readable summary of why assignment was blocked. Do not parse for control flow.
blocking_servicesServices to fix before retrying — each entry names the service, the feature that failed validation, and the stored value.

Remediation:

Retry the domain default assignment (POST or PUT) with optional service_updates to patch provided_features for specific services in the same request. Each entry uses static_features (same field name as service init/PUT); keys are shallow-merged into the stored object and validated only against the target model version’s frozen feature schema:

{
"model_id": "example-model",
"model_version": "2.0.0",
"service_updates": [
{ "service_id": "svc-001", "static_features": { "route": "route-a" } }
]
}

The API validates all service_updates, then pre-checks every other non-departed service. If any still block, you get the same 422 with blocking_services. When none block, it applies the patches, upserts the assignment, and re-resolves resolved_features for all non-departed services in one transaction.

service_updates is only allowed on domain default assignment upserts (not service-scoped routes or other assignment keys).

Depart services whose departure_datetime is in the past when they should no longer participate in the domain freeze check.

For general maintenance under the current default freeze (not assign-time remediation), PUT .../service/{service_id} can update stored provided_features on individual services.

Changing features on services does not change an already-frozen model version. If you need a different feature contract on the model itself, register a new model version.

Service-scoped assignment routes do not perform this domain-wide freeze check; only domain assignment upserts can return blocking_services.

Live domain_features is the next-train draft — the contract the next model version will be trained against. It is not the contract that currently-deployed services are running under; that one is the frozen schema on the active default assignment’s model version.

PUT /v2/clients/{client_id}/domains/{domain_id}/features is persist-only. It writes the new feature definitions and returns { features: [...] }. It does not re-resolve, re-validate, or re-fire inference for any existing service. Live edits cannot silently change the meaning of stored provided_features or resolved_features for a deployed model.

To propagate new feature shapes onto deployed services, use one of:

WhenRoute
Roll a new model version’s contract onto the whole domainDomain default assignment swap (POST or PUT) — optionally with service_updates to patch incompatible services in the same call.
Adjust one service’s static_features under the current freezePUT /v2/.../service/{service_id}.
Re-fire inference per service without changing their stored featuresPOST /v2/.../services/init — dispatches a fresh assignment-linked inference job per non-departed service using the stored resolved_features, then returns { dispatched_services: [...] }.

Ferry-style domains may sell several capacity types on one sailing (seats, cabins, lane metres). Use one service per departure and service-scoped keys named {primary}_{capability} (e.g. cabin_recommendation). Keys are a tenant naming convention, not a separate platform type — see Multiple primary products.