curl --request POST \
--url https://pria.praxislxp.com/api/user/agents/workflows/{id}/run \
--header 'x-access-token: <api-key>'import requests
url = "https://pria.praxislxp.com/api/user/agents/workflows/{id}/run"
headers = {"x-access-token": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'x-access-token': '<api-key>'}};
fetch('https://pria.praxislxp.com/api/user/agents/workflows/{id}/run', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://pria.praxislxp.com/api/user/agents/workflows/{id}/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"x-access-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://pria.praxislxp.com/api/user/agents/workflows/{id}/run"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-access-token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://pria.praxislxp.com/api/user/agents/workflows/{id}/run")
.header("x-access-token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://pria.praxislxp.com/api/user/agents/workflows/{id}/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-access-token"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"outcome": "started",
"workflowId": "<string>",
"runId": "<string>",
"sessionId": "<string>",
"workspaceId": "<string>",
"status": "<string>",
"agent": {
"key": "<string>",
"name": "<string>"
},
"reused": true,
"instruction": "<string>",
"instructionDelivered": true,
"deliveryState": "n/a",
"deliveryCode": "<string>",
"deliveryMessage": "<string>",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"outcome": "rejected",
"workflowId": "<string>",
"runId": "<string>",
"code": "run_limit",
"message": "<string>",
"retryable": true,
"details": {}
}Run one of the caller's workflows now.
Starts the workflow’s agent through the same deploy chain a catalogue deploy uses. Manual trigger only — there is no scheduling and nothing runs unattended. The agent is resolved from the SAVED workflow; the request body is ignored entirely. If a session for that agent is already running, the existing session is returned with outcome reused — it is never presented as a fresh start.
When the outcome is started and the workflow has a non-empty instruction, the instruction is delivered to the new session on a BEST-EFFORT basis (bounded in-request retry). Delivery failure NEVER fails the run: the session did start. The result reports it separately via instructionDelivered / deliveryState / deliveryCode.
The instruction is NEVER delivered on a reused outcome. This system has no observable turn state, so an injected prompt could land mid-turn; the caller is told to open the session instead.
Workflows made by the Digital Twin (madeBy: twin) run in their own read-only session that closes after the turn, and never reuse a live one: a run while another is live answers 409 workflow_busy. They need automatic session cleanup (409 auto_close_unavailable), share a limit of 48 started runs per owner per 24 hours across chat, page and schedule (429 run_limit, recorded as a rejected run), and can be refused 409 tool_group_unavailable or model_unavailable. They are paid like any other agent use (owner ruling 10): the model follows the institution’s credential mode (user_oauth the owner’s own connection, institution_oauth the institution’s connection, api_key the institution’s key), refused 409 credential_unavailable when that route has no credential and 409 model_route_changed when it now serves a different model than the saved one. Delegated tokens get 403 TWIN_MANAGED. (A scheduled Twin run whose workflow agent is gone is released as failed with WORKFLOW_AGENT_MISSING; that code is internal to the scheduler.)
curl --request POST \
--url https://pria.praxislxp.com/api/user/agents/workflows/{id}/run \
--header 'x-access-token: <api-key>'import requests
url = "https://pria.praxislxp.com/api/user/agents/workflows/{id}/run"
headers = {"x-access-token": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'x-access-token': '<api-key>'}};
fetch('https://pria.praxislxp.com/api/user/agents/workflows/{id}/run', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://pria.praxislxp.com/api/user/agents/workflows/{id}/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"x-access-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://pria.praxislxp.com/api/user/agents/workflows/{id}/run"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-access-token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://pria.praxislxp.com/api/user/agents/workflows/{id}/run")
.header("x-access-token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://pria.praxislxp.com/api/user/agents/workflows/{id}/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-access-token"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"outcome": "started",
"workflowId": "<string>",
"runId": "<string>",
"sessionId": "<string>",
"workspaceId": "<string>",
"status": "<string>",
"agent": {
"key": "<string>",
"name": "<string>"
},
"reused": true,
"instruction": "<string>",
"instructionDelivered": true,
"deliveryState": "n/a",
"deliveryCode": "<string>",
"deliveryMessage": "<string>",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"code": "INVALID_NAME",
"message": "<string>"
}{
"success": false,
"outcome": "rejected",
"workflowId": "<string>",
"runId": "<string>",
"code": "run_limit",
"message": "<string>",
"retryable": true,
"details": {}
}Authorizations
JWT token passed in x-access-token header
Path Parameters
Response
Started, or an already-running session was returned.
started, reused The bound agent. On a workflow made by the Digital Twin both fields are empty strings (its binding is internal), and message names the workflow.
Show child attributes
Show child attributes
True when an existing session for this agent was returned instead of a new one. Never presented as a fresh start.
The saved instruction. Also delivered to the session when outcome is started; see instructionDelivered.
True only when the saved instruction was actually accepted by the agent session. Independent of outcome.
n/a — nothing to deliver, or delivery deliberately not attempted (empty instruction, or outcome reused). delivered — the prompt frame was accepted. not_ready — the session was not promptable within the bounded in-request retry budget. failed — the guest agent rejected or errored on the send.
n/a, delivered, not_ready, failed Machine-readable reason when not delivered, e.g. REUSED_SESSION, SESSION_INCOMPLETE, NO_CONTROL_KEY, SEND_FAILED.
User-safe reason when not delivered.
Was this page helpful?