Browse the docs
How Trinium works

The Run API

Another system can start a pipeline or a Flow, wait for it to finish and stop it, through five calls and a token.

What it is for

Use the Run API when the schedule lives outside Trinium:

  • An orchestrator runs your jobs. An AWS Step Functions state machine, Airflow or an enterprise scheduler calls Trinium for each job that has moved, waits for it, and carries on. You can move one job at a time.
  • An event starts a run, such as a file landing in Amazon S3 (through EventBridge), a partner's webhook or a CI job.

When the schedule can live in Trinium, a schedule or a Flow is simpler. For files arriving in cloud storage, a file trigger already starts a run when something new lands.

The Run API starts what is deployed. It never accepts a pipeline, never runs a draft, and never reads or changes your data, settings or connections.

Set it up

  1. Create an integration in Settings → API. An integration stands for one calling system, for example step-functions-mdm. Nobody can sign in as it.
  2. Give it a workspace seat. In the workspace that holds the pipelines, open Members and add the integration with a View seat. View is the only seat an integration takes, and it is all it needs: it can run that workspace's pipelines and Flows, and never edit them.
  3. Check its connections. A connection shared with the workspace already reaches the integration through its seat, and the workspace's Production tick on that connection covers Production runs too. Only a connection shared with named people needs the integration added to its access list, with Production ticked if it will start Production runs: nobody reaches Production without the tick.
  4. Make a token. Under the integration, choose New token, name it after the place it will be used, and choose when it expires (at most a year). Copy it then: it is shown once.
  5. Store the token in the calling system, for example in an EventBridge connection, and send it with every call.

To rotate a token, make a second one, switch the caller to it, then revoke the first. Revoking a token, or switching its integration off, refuses it from the next request.

The five calls

CallWhat it does
POST /api/v1/pipelines/{id}/runsStart the version a pipeline's environment runs
GET /api/v1/runs/{id}How the run is going, and how it ended
POST /api/v1/runs/{id}/cancelStop it
POST /api/v1/flows/{id}/runsStart a Flow run
GET /api/v1/flow-runs/{id}How the Flow run is going, step by step

A pipeline's id is in its address in Trinium: /pipelines/{id}/edit. A Flow's is in /flows/{id}/edit.

Send the token in either header:

Authorization: Bearer trn_...
X-Trinium-Api-Key: trn_...

The API answers on the same address and port as Trinium itself. To reach the API from outside without exposing the app, forward only /api/v1/ to Trinium at your load balancer.

Start a run

POST /api/v1/pipelines/{id}/runs

{
  "environment": "Production",
  "parameters": { "region": "EMEA" },
  "idempotency_key": "evt-6a7e8f90"
}
  • environment is Staging or Production, and is required.
  • parameters gives values for the pipeline's parameters, by name. Anything left out takes its default. It may be left out entirely.
  • idempotency_key is required: your own name for this start, up to 255 characters. Send the same key when you retry, and you get the same run back instead of a second one. An EventBridge event's id or a Step Functions execution name is a good key.

A field the API does not know, such as a misspelled parameter, is refused rather than ignored.

The answer is 202 Accepted, with Location: /api/v1/runs/{id} and Retry-After: 30, and the run's status as the body.

Staging and Production

  • A start runs the version deployed to the environment it names, never the draft. If nothing is deployed there, the answer is 400, saying so. See versions and deploys.
  • Each connection is used through that environment's settings: its Staging settings for a Staging run, its Production settings for a Production run.
  • Production exists only for a pipeline in a workspace. It needs the Production tick on every shared connection the pipeline uses, and each of those connections needs its Production settings filled in.
  • An idempotency_key belongs to one environment. The same key sent for the other environment is refused with 422.
  • A Flow run's environment applies to every step: each step runs that environment's version of its pipeline.

Follow a run

GET /api/v1/runs/{id} answers 202 while the run is still going and 200 once it has ended:

{
  "id": "01a1...",
  "pipeline": "Load meters",
  "environment": "Production",
  "version": 7,
  "status": "Failed",
  "queued_at": "2026-10-28T02:00:04Z",
  "started_at": "2026-10-28T02:00:05Z",
  "completed_at": "2026-10-28T02:01:12Z",
  "duration_seconds": 67,
  "warnings": 0,
  "error": "Node 'Load meters' execution failed: ...",
  "runs": [ { "id": "01a1...", "file": null, "status": "Failed", "...": "..." } ]
}

status is one of Queued, Running, Cancelling, Succeeded, Failed or Cancelled. error names the node the way the canvas does.

One start can be several runs. A pipeline set to run each file separately runs once per file its input will read, and the runs take turns, one at a time, in the order the files were listed. With the input's Bookmark on, only files no successful run has read get a run, up to 500 a start; the rest are read by the next start. With nothing new to read, the start is one run that reads nothing. The id you get back stands for all of them: status is Succeeded only when every run succeeded, Failed when any failed, and still going while any is. runs lists each one with its file, the file's full path (inbound/eu/orders.csv).

Cancel a run

POST /api/v1/runs/{id}/cancel stops every run the start made. A run still waiting is cancelled at once; a running one stops at its next check. Cancelling a run that has already ended is not an error: the answer is how it ended.

Start a Flow

POST /api/v1/flows/{id}/runs takes the same body. parameters are the Flow's own inputs. GET /api/v1/flow-runs/{id} answers with the Flow run's status and each step, named as on the Flow canvas, with the pipeline runs it started.

Retries and bursts

  • A retry is never a second run. The same idempotency_key returns the same run, for as long as the run exists. The same key with a different environment or different parameters is refused with 422.
  • A burst becomes one run. When a start asks for exactly what a run already waiting in the queue will do (the same pipeline, environment, deployed version and parameter values, queued the same day, by the same integration), it joins that run instead of queuing another. Thirty files landing at once start one run, which reads all of them when it starts. A run that has already started is never joined, and a pipeline that runs each file separately always queues its own runs.
  • One run of a pipeline at a time, for each set of text parameter values. While a run of the pipeline with the same text values is waiting or running in that environment, including any one file's run of a start that runs each file separately, any other start of it is refused with 429 and Retry-After: 30, and the message names that run. Nothing is queued and the key is not used up, so the caller's retry starts a run once that one has ended. Amazon EventBridge and Azure Logic Apps retry a 429 by themselves; a Step Functions state machine needs the Retry shown below. A run with a different text value is not in the way, and neither is a run in the other environment.

Answers

StatusMeansRetry?
202Started, or still going
200Ended (see status)
400The request is wrong, or nothing is deployed in that environment; the message says whichNo
401The token is missing, wrong, revoked or expired, or its integration is switched offNo
402This instance's license has lapsed, so no run may startNo
403The integration may not use a connection the pipeline needs, or may not reach ProductionNo
404No such pipeline, Flow or run, or one this integration cannot seeNo
422The idempotency key was already used for a different startNo
429A run of this pipeline in that environment is still waiting or running; the message names itYes, after Retry-After
503Trinium could not reach its databaseYes

The API never answers 409, so a caller that retries 409 never repeats a refusal for a day.

From AWS Step Functions

Use an HTTP Task with an EventBridge connection of the API key kind: header name X-Trinium-Api-Key, value the token. An HTTP Task gives up after 60 seconds, so start the run, then wait and ask in a loop:

"Start load": {
  "Type": "Task",
  "Resource": "arn:aws:states:::http:invoke",
  "Parameters": {
    "ApiEndpoint": "https://trinium.example.com/api/v1/pipelines/PIPELINE_ID/runs",
    "Method": "POST",
    "Authentication": { "ConnectionArn": "CONNECTION_ARN" },
    "RequestBody": { "environment": "Production", "idempotency_key.$": "$$.Execution.Name" }
  },
  "Retry": [
    { "ErrorEquals": ["States.Http.StatusCode.429"], "IntervalSeconds": 30, "BackoffRate": 1.5, "MaxAttempts": 20 }
  ],
  "ResultSelector": { "id.$": "$.ResponseBody.id" },
  "Next": "Wait"
},
"Wait": { "Type": "Wait", "Seconds": 30, "Next": "Check" },
"Check": {
  "Type": "Task",
  "Resource": "arn:aws:states:::http:invoke",
  "Parameters": {
    "ApiEndpoint.$": "States.Format('https://trinium.example.com/api/v1/runs/{}', $.id)",
    "Method": "GET",
    "Authentication": { "ConnectionArn": "CONNECTION_ARN" }
  },
  "ResultSelector": { "id.$": "$.ResponseBody.id", "status.$": "$.ResponseBody.status" },
  "Next": "Done?"
},
"Done?": {
  "Type": "Choice",
  "Choices": [
    { "Variable": "$.status", "StringEquals": "Succeeded", "Next": "NEXT_STATE" },
    { "Variable": "$.status", "StringEquals": "Failed", "Next": "Load failed" },
    { "Variable": "$.status", "StringEquals": "Cancelled", "Next": "Load failed" }
  ],
  "Default": "Wait"
}

From Amazon EventBridge

Make the API destination's target POST /api/v1/pipelines/{id}/runs with the same connection, and shape the body with an input transformer so each event's own id is the key. EventBridge retries for up to a day; the key makes every retry the same run:

Input path:     { "id": "$.id" }
Input template: { "environment": "Production", "idempotency_key": "<id>" }

From Azure Logic Apps

Use an HTTP action to start the run with the token in a header, then an Until loop: a Delay of 30 seconds and an HTTP action calling GET /api/v1/runs/{id}, until status is Succeeded, Failed or Cancelled.

Keep the token safe

  • Call Trinium over HTTPS. AWS Step Functions and EventBridge only call a public DNS name with a publicly trusted certificate, even inside a private network; see Turning on HTTPS.
  • Trinium keeps only a fingerprint of each token, never the token, and shows it once.
  • Each integration runs only what its workspace seats and connection access allow, and the audit trail records every run it starts or stops, with the token's name.
  • Limit which addresses may call the API at your load balancer or firewall.
  • After restoring a backup, review Settings → API: tokens return to how they were when the backup was taken.