Vars
Plain configuration for your workflows, set for the workspace or per workflow. Changes apply without a redeploy.
Reading vars
Your code reads vars from the run context. Reading a var that is not set doesn't throw.
import { workflow } from "shiftlabs";
export default workflow<{ id: string }>(async ({ payload, vars, log }) => {
const region = vars.REGION ?? "us-east";
const limit = Number(vars.REFUND_LIMIT_CENTS ?? "5000");
log.info("checking refund", { id: payload.id, region, limit });
});
from shiftlabs import workflow
@workflow
async def refund_check(ctx):
region = ctx.vars.REGION or "us-east"
limit = int(ctx.vars["REFUND_LIMIT_CENTS"] or "5000")
ctx.log.info("checking refund", {"id": ctx.payload["id"], "region": region, "limit": limit})
vars.NAMETypeScript: a string, or
undefinedwhen the var is not set.ctx.vars.NAME
ctx.vars["NAME"]Python: a string, or
Nonewhen the var is not set.{{ var.NAME }}In a connection template, the gateway fills in the calling workflow's value. If the var is not set, the request is refused.
Values are always strings. Parse numbers, flags or JSON yourself.
Workspace and workflow
A workspace var applies to every workflow. A workflow var with the same name overrides it for that workflow only.
# A workspace var (developer key). Answers {"name", "value", "workflow": null, "updatedAt"}.
curl -X PUT https://api.shiftlabs.org/v1/vars/REGION \
-H "authorization: Bearer $SHIFTLABS_API_KEY" -H "content-type: application/json" \
-d '{"value": "us-east"}'
# refund-check's own value wins over the workspace's.
curl -X PUT https://api.shiftlabs.org/v1/workflows/refund-check/vars/REGION \
-H "authorization: Bearer $SHIFTLABS_API_KEY" -H "content-type: application/json" \
-d '{"value": "eu-west"}'
# Delete the override: refund-check reads the workspace value again.
curl -X DELETE https://api.shiftlabs.org/v1/workflows/refund-check/vars/REGION \
-H "authorization: Bearer $SHIFTLABS_API_KEY"
Vars · ridgeline-ops
2| Name | Value | Overridden by |
|---|---|---|
REFUND_LIMIT_CENTS | 5000 | — |
REGION | us-east | refund-check |
Workflow overrides
edit them on each workflow| Workflow | Name | Value |
|---|---|---|
| refund-check | REGION | eu-west |
Updated 2026-10-20 21:05 UTC
- Takes effect
No redeploy needed. Each dispatch loads the current values, including when a run resumes after a sleep.
- Keep a value
To keep the value a run started with, return it from a
step.run. A resumed run gets the stored result. - Before deploy
A workflow's vars can be set before its first deploy.
- Deleting
Deleting a workspace var leaves workflow overrides in place.
Vars are not secrets
Use a var for a region, a channel or a threshold. Put credentials in a secret.
- Readable
Everyone in the workspace, viewers included, can read every var and its value, in the dashboard and at
GET /v1/vars. - Plain text
Secrets are encrypted with your workspace's own data key, and no endpoint returns their values. Vars are stored as plain text and listed with their values.
- In your code
Your code gets the actual value, not a stand-in. It can end up in logs, step results or requests to any host.
- Audited
Every change is written to the audit log as
var_putorvar_delete, with the workflow for an override.
Dashboard and API
Developers and admins add, change and delete vars. Viewers read them.
- Vars screen
The workspace vars, each with the workflows that override it, and the overrides below. Add or change one with its name and value, or edit and delete it from its row.
- Workflows screen
Open a workflow and find its Vars section: its own values, and the workspace vars it inherits marked tenant. Save for this workflow sets an override.
- Names
Uppercase letters, digits and underscores, starting with a letter, up to 64 characters. Secret names follow the same rule. Other names return
400 {"error": "invalid var name"}. - Values
A string of up to 4 KiB (4,096 bytes as UTF-8). A longer value, or one that is not a string, returns
400.
| Route | Method | Minimum role |
|---|---|---|
/v1/vars every var: [{name, value, workflow, updatedAt}], workflow null for workspace vars | GET | viewer |
/v1/vars/:NAME {"value"} | PUT · DELETE | developer |
/v1/workflows/:workflow/vars/:NAME {"value"} | PUT · DELETE | developer |
PUT returns the var. DELETE returns {"deleted": "NAME"}, or 404 {"error": "var not found"}.