Replace variables
PUT/
Sets a workflow’s variables. What you send is the whole set: any you leave out is deleted.
Needs an API token with the Write permission for workflows (workflow:write).
Parameters
Path
idRequired · UUIDThe workflow’s ID.
Body
variablesRequired · array of objectsEvery variable the workflow should have. Required:
[]deletes them all.variables.nameRequired · stringLetters, digits and underscores, not starting with a digit, up to 128 characters. Each name once.
variables.valueOptional · stringIts value. A sensitive one needs 6 bytes or more, up to 8 KB, unless it has
keep. A plain one without it is empty.variables.isSecretOptional · booleantruefor sensitive.variables.keepOptional · booleanWith
isSecret: keep the stored value, which you can’t read back. Send novalue.expectedRevOptional · integerThe
definitionRevyou read. If the workflow changed since, nothing changes and you get 409.
Keep a secret you can’t read
Read the variables, change the list, and send it all back. For a sensitive variable you aren’t changing, send {"name": …, "isSecret": true, "keep": true} with no value.
A sensitive value is masked in run data wherever it appears. That’s why a short one is refused: it would blank out unrelated text.
Plain variables live in the draft, so they reach live runs when you publish. Sensitive ones apply at once, so a leaked key can be replaced without publishing.
Responses
- 200OK
The variables as GET answers them, without sensitive values, and the new
definitionRev. idisn’t a UUID, the body isn’t JSON, it has novariableslist (details.fieldsays so, and nothing changes), orexpectedRevisn’t a whole number.- 403
FORBIDDENThe token lacks the Write permission for workflows.
- 404
NOT_FOUNDNo workflow with this ID in the token’s workspace.
- 409
CONFLICTThe workflow changed since your
expectedRev, or another write took too long. Read it again first. A name isn’t allowed or is listed twice; a sensitive value is missing, under 6 bytes or over 8 KB;
keephas nothing stored to keep; over 100 sensitive variables; or no encryption key on the server. Nothing changed.Nothing was changed. Try again.
Any call can also answer: 401 UNAUTHORIZED · 401 TOKEN_ENDED · 403 TOKEN_SURFACE_OFF · 403 FEATURE_OFF · 403 EMBED_NOT_ALLOWED · 403 EMBED_NOT_AVAILABLE · 403 ACCOUNT_SUSPENDED · 413 PAYLOAD_TOO_LARGE · 415 INVALID_CONTENT_TYPE · 429 RATE_LIMITED · 503 BUSY · 503 PAUSED · 503 SERVICE_UNAVAILABLE. See Errors.
Request
GORUNNER="https://api.gorunner.io"
GORUNNER_TOKEN="grt_…" # needs Write for workflows
WORKFLOW_ID="your-workflow-id"
URL="$GORUNNER/api/workflows/$WORKFLOW_ID/variables"
curl -X PUT "$URL" \
-H "Authorization: Bearer $GORUNNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"variables": [
{
"name": "SLACK_CHANNEL",
"value": "#alerts",
"isSecret": false
},
{
"name": "STRIPE_KEY",
"isSecret": true,
"keep": true
}
],
"expectedRev": 7
}'const GORUNNER = "https://api.gorunner.io";
const TOKEN = process.env.GORUNNER_TOKEN;
const WORKFLOW_ID = process.env.WORKFLOW_ID;
const res = await fetch(
`${GORUNNER}/api/workflows/${WORKFLOW_ID}/` +
`variables`,
{
method: "PUT",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
variables: [
{
name: "SLACK_CHANNEL",
value: "#alerts",
isSecret: false,
},
{
name: "STRIPE_KEY",
isSecret: true,
keep: true,
},
],
expectedRev: 7,
}),
},
);
const { data } = await res.json();import os, requests
GORUNNER = "https://api.gorunner.io"
TOKEN = os.environ["GORUNNER_TOKEN"]
WORKFLOW_ID = os.environ["WORKFLOW_ID"]
res = requests.put(
f"{GORUNNER}/api/workflows/{WORKFLOW_ID}/"
f"variables",
headers={"Authorization": f"Bearer {TOKEN}"},
json={
"variables": [
{
"name": "SLACK_CHANNEL",
"value": "#alerts",
"isSecret": False,
},
{
"name": "STRIPE_KEY",
"isSecret": True,
"keep": True,
},
],
"expectedRev": 7,
},
)
data = res.json()["data"]Response · 200 OK
{
"data": {
"variables": [
{
"name": "STRIPE_KEY",
"value": "",
"isSecret": true
},
{
"name": "SLACK_CHANNEL",
"value": "#alerts",
"isSecret": false
}
],
"secretsAvailable": true,
"definitionRev": 8,
"hasUnpublishedChanges": true
}
}Every field
Body
variablesRequired · array of objectsnameRequired · stringTrimmed. Letters, digits and underscores, not starting with a digit, at most 128 characters. Duplicates in one request are refused.
valueOptional · stringRequired on a sensitive entry unless
keepis true; a plain entry without it holds an empty string. ForisSecret, at least 6 characters (bytes) and at most 8,192 bytes — a shorter secret is refused rather than stored unprotected, because run-data masking matches the VALUE and would blank out unrelated text.isSecretOptional · booleanDefault
false.keepOptional · booleanSensitive entries only (ignored on a plain one): retain the stored value, since the client was never given it and cannot send it back. Refused with 422 if there is nothing stored under that name.
Default
false.expectedRevOptional · integerOptimistic lock, as on
PUT /api/workflows/{id}: thedefinitionRevyou last read. If the workflow has been written since, the request is refused with 409CONFLICTand nothing is changed. Omit it (or send 0) for an unconditional write.
Response · 200 OK
dataobjectvariablesarray of objectsSensitive variables first, then by name.
namestringvaluestringThe value for a PLAIN variable. Always an empty string for a sensitive one — there is no read path for a secret.
isSecretbooleanTrue = stored encrypted outside the definition and takes effect immediately, without a publish. False = lives in the draft definition and reaches production only when you publish.
secretsAvailablebooleanFalse when the server has no encryption key configured — writing any
isSecretvariable will then be refused with 422.definitionRevintegerThe workflow’s revision as this answer leaves it. Plain variables live in the draft definition, so a
PUTmoves it: send this asexpectedRevon your next write to the workflow (PUT /api/workflows/{id}or this endpoint).hasUnpublishedChangesbooleanWhether the draft is now ahead of the published version — a variable change on a live workflow takes effect only when published.