Deployment
A deployment takes a pipeline you have been editing and puts it into production. It is one action, and it does four things: it publishes your draft, freezes the version that will run, packages it, and creates the schedule that executes it — on the platform, on an edge device, or on both at once.
It also leaves a record. A deployment is not a button that fires and forgets: it is an object you can read, poll, pause, resume and retry, and it remembers exactly which commit it runs and how it got there.
If you are looking for TriggersA trigger is the schedule a pipeline runs on. From 12.1 you no longer create one by hand — deploying a pipeline creates it, and pausing or deleting the deployment removes it. Everything you used to configure on a trigger is now configured on the deployment, and the sections below describe each one.
What a deployment does
Every deployment moves through the same four steps, in order. Each records its own outcome, so when something goes wrong you learn which stage failed rather than only that the deployment did.
| Step | What happens | When it is skipped |
|---|---|---|
| Merge | Your draft is published — the feature branch is merged into the default branch and deleted. | You are deploying a pipeline with no draft open, or the draft was already published. |
| Release | A release branch is cut, labelling the exact commit this deployment runs. | You are deploying an existing release. The commit is still resolved and recorded. |
| Image | The pipeline and its trained model are packaged into an image, so every run executes identical code. | packaging="release" — there is nothing to build. |
| Trigger | The schedule is created: on the platform for cloud twins, on the device for edge twins. | Never. |
Because the steps are recorded, a deployment that stopped half way can continue from where it stopped rather than starting again — see Retrying.
Where the branches come fromMerge and release are the git operations described in Working with branches. You do not manage those branches yourself; deploying creates and removes them for you.
Why a release is frozen
A release branch is a fixed label on an already-published commit. The default branch can move on as much as it likes afterwards — the release keeps pointing at the same commit, so a deployment made today still runs the same code in six months.
That is also why a release branch cannot be deleted while a deployment references it.
Cloud and edge
A deployment targets twins, and each twin runs either in the cloud or on an edge device. One deployment can do both: the same pipeline can run on platform infrastructure for most of your assets and on a device for the ones that need it.
Cloud
The default. The schedule lives on the platform, and executions run on Wizata's pipeline runners. Nothing needs to be installed anywhere, and a deployment reaching deployed means the schedule is live.
Edge
The schedule is written into the device's own configuration, and the device runs the pipeline locally — so it keeps working when the link to the cloud does not, and data that should not leave the site does not have to.
Three things follow from that, and they are worth knowing before you deploy:
- An edge deployment is delivered, not started. Reaching
deployedmeans the schedule has been written to the device's configuration. The device picks it up on its next configuration sync, within about a minute. If the device is offline, it collects the change when it reconnects. - Edge runs images only. A device cannot build a pipeline from a branch, so
packaging="release"is refused for an edge target. - The device must be able to run pipelines. The twin — or one of its ancestors — needs an edge device registered with both connectivity and pipeline support. If you name a device explicitly, it has to be one of the devices that twin could legitimately use.
Deploying to an edge device merges your entry into that device's configuration and leaves everything else in it untouched, so several deployments can target the same device without disturbing one another.
Choosing the target
In Python, a bare twin means cloud:
twins=["mef_plant_A_motor1_bearings"]and an edge target names the device:
twins=[{"twin": "mef_plant_A_motor1_bearings",
"target": "edge",
"deviceId": "plant-a-edge-01"}]Both forms can appear in the same list. Twins can be given as hardware ids or as UUIDs.
Plot and train are cloud-onlyA scheduled run can produce plots and retrain models, but neither is available on an edge target. Both are refused rather than silently ignored.
Deploying from the interface
Deploy is an action on the pipeline itself, in the AI Lab. It opens a short wizard, and nothing at all happens until you press Deploy on the last step — you can open it to see what a deploy would do and close it again.
Version — what goes live
Pick the code this schedule will run: the published version, or a branch. A release is cut from it and named for you, and the dialog shows the git ref that will be created, for example release/demo_wizata_AI_Lab/202609141424.
A new release is cut so that what runs is fixed and traceable.

Package
An image, or the release branch. See Packaging for which to choose.
Targets — where should it run?
Each twin is set to Cloud, Edge or Off, and everything starts Off — a deployment covers the twins you choose, not all of them.
A twin's Edge option is unavailable when nothing can run a pipeline for it: that twin, or one of its ancestors, needs an edge device registered with pipeline support. The dialog greys it out rather than accepting a target that could never run.

Schedule — when should it run?
Run every takes a duration such as 15m or 1d, and First run after is an optional delay before the first run.
The same step sets what each run does — Train, Plot, Write — and disables the ones that do not apply. Training is unavailable on an image, and the dialog says so.

Review
A summary of all of it, and the button that performs the deployment.
Watching it happen
Deployments are listed under AI Lab ▸ Deployments, with the pipeline, release, image, status, environment, twins and frequency. From there a deployment can be paused, resumed and edited.

Building an image takes minutes, so a deployment fills in as it goes; you do not have to wait on the page. If a step fails, it says which one and why, and the deployment can be retried once you have fixed the cause.
Deploying with Python
The same thing, as one call:
deployment = wizata_dsapi.api().deploy(
"demo_wizata_AI_Lab",
twins=["mef_plant_A_motor1_bearings"],
interval=600000, # every 10 minutes
delay=300000 # 5 minutes after each interval boundary
)It returns immediately with a deployment to poll. It does not wait, because building an image takes longer than a request is allowed to — the record carries the progress instead of the response.
Checking before you commit to it
deploy_preview() answers what a deploy would do — what would be merged, which release would be cut, which image built — without doing any of it. Worth running the first time you deploy a pipeline, or whenever you are unsure which version you are about to promote.
plan = wizata_dsapi.api().deploy_preview("demo_wizata_AI_Lab")Following it
deployment = wizata_dsapi.api().await_deployment(deployment, timeout=900)
print(deployment.status) # deployed
print(deployment.release) # release/demo_wizata_AI_Lab/2026.09.14
print(deployment.sha) # the commit that actually runsA deployment is pending, then deploying, then deployed — or failed. To poll it yourself rather than waiting:
deployment = wizata_dsapi.api().get(id=deployment.deployment_id,
entity=wizata_dsapi.Deployment)
for step in deployment.steps:
print(step)Configuring the schedule
Interval and delay
Executions are aligned to 0d 0h 0m 0s 0ms. An interval of 10 minutes runs at 0h10, 0h20, 0h30 and so on, whatever time you deployed.
A delay offsets each run from that boundary: 300000 ms (5 minutes) with a 10-minute interval runs at 0h05, 0h15, 0h25.
interval=600000, # 10 minutes, in milliseconds
delay=300000 # 5 minutes, in milliseconds
The interface uses durations, the SDK uses millisecondsThe deploy dialog reads
15mor1d;deploy()takesintervalanddelayin
milliseconds. They describe the same schedule —15misinterval=900000.
Timestamps stay aligned regardless of when the deployment was created.
Twin units
A templated pipeline runs once per twin at each interval:
twins=["mef_plant_A_motor1_bearings", "mef_plant_A_motor2_bearings"]A pipeline that is not templated has no twins, and runs once per interval.
Properties
Fixed properties are passed to every execution, using the same @var_name notation as experiments:
properties={
"from": "now-30d",
"to": "now"
}What each run does
| Argument | Default | Effect |
|---|---|---|
write | on | Write results back to the platform. |
plot | off | Produce plots on each run. Cloud only. |
train | off | Train models on each run. Cloud only, and not on an image deployment. |
train is refused on an image deployment for a reason worth knowing: the image carries a frozen model, and that frozen model is what predict uses. Training on each run would train a model and then discard it in silence.
Packaging: image or release
packaging="image" (the default) freezes the pipeline and its model into an artifact, so every run executes exactly the same code — months later included. packaging="release" runs from the release branch instead, so a fix pushed to that branch takes effect without redeploying.
Choose an image when reproducibility matters, and a release when you want to be able to patch in place. Edge deployments are always images.
Now: queued vs started
Within the pipeline Context, now is the reference datetime for relative expressions such as now-10m in query steps:
queued(default) — the moment the execution was pushed to the queue. Use this when timestamps must be sharp and aligned to the interval.started— the moment it actually began running.
If your pipeline writes data back to the platform, it uses the timestamps resulting from the query by default, not the
nowvalue.
Managing a deployment
Pausing and resuming
Pausing removes the schedule and keeps everything else — the record, the release, the image:
wizata_dsapi.api().pause_deployment(deployment)
wizata_dsapi.api().resume_deployment(deployment)Resuming recreates the schedule from the stored manifest, so it returns exactly as it was. Pause when a pipeline should stop running for a while; delete when it should be gone.
Retrying a failed deployment
A deployment that failed part way continues from where it stopped:
wizata_dsapi.api().retry_deployment(deployment)Steps already completed are not repeated — a retry after a failed image build does not merge and cut a release again. The steps list shows where it will resume, and error explains why it stopped.
Deleting
Deleting a deployment removes the schedule it owns, so the pipeline stops running. The release branch it used remains, and can then be deleted if nothing else references it.
wizata_dsapi.api().delete(deployment)Seeing what is deployed
The interface lists deployments with their pipeline, status and release. From Python:
paged = wizata_dsapi.api().search_deployments()
for deployment in paged.results:
print(deployment.pipeline_key, deployment.status, deployment.release)Search returns a PagedQueryResult, so a large estate needs filtering or more than one page. To simply take all of them:
deployments = wizata_dsapi.api().lists(wizata_dsapi.Deployment)The underlying endpoint is POST /deployments/search — see the API reference.
A worked example
demo_wizata_AI_Lab is a templated pipeline, so it runs once per twin. Deploying it to two motors in the cloud, every ten minutes:
import wizata_dsapi
api = wizata_dsapi.api()
deployment = api.deploy(
"demo_wizata_AI_Lab",
twins=["mef_plant_A_motor1_bearings", "mef_plant_A_motor2_bearings"],
interval=600000,
delay=300000,
properties={"from": "now-30d", "to": "now"},
plot=True
)
deployment = api.await_deployment(deployment)
if deployment.status == wizata_dsapi.DeploymentStatus.DEPLOYED:
print(f"running {deployment.release} at {deployment.sha}")
else:
print(f"stopped at: {deployment.error}")
for step in deployment.steps:
print(f" {step}")The same pipeline, with one motor kept on a device and the other in the cloud:
deployment = api.deploy(
"demo_wizata_AI_Lab",
twins=[
{"twin": "mef_plant_A_motor1_bearings",
"target": "edge",
"deviceId": "plant-a-edge-01"},
"mef_plant_A_motor2_bearings"
],
interval=600000
)Note the absence of plot=True here: the deployment has an edge target, and plots are cloud-only.
Updated 23 days ago