Create or update a single variable: 'mutation variableUpsert($input:VariableUpsertInput!){ variableUpsert(input:$input) }' with input { projectId, environmentId, serviceId, name, value }. Omit serviceId for a shared variable.
Upsert many at once: 'mutation variableCollectionUpsert($input:VariableCollectionUpsertInput!){ variableCollectionUpsert(input:$input) }' with input { projectId, environmentId, serviceId, variables: { KEY: value, ... } }.
Delete a variable: 'mutation variableDelete($input:VariableDeleteInput!){ variableDelete(input:$input) }' with input { projectId, environmentId, serviceId, name }.
Get fully rendered variables for a deployment: 'query variablesForServiceDeployment($projectId:String!,$environmentId:String!,$serviceId:String!){ variablesForServiceDeployment(projectId:$projectId, environmentId:$environmentId, serviceId:$serviceId) }'.
Reference other services' vars with ${{ServiceName.VARIABLE_NAME}} syntax; pass unrendered:true to return unresolved references.
Known gotchas
variableUpsert handles both create and update (idempotent upsert by name).
Skip triggering a redeploy with skipDeploys:true when rotating secrets in batch.
variableCollectionUpsert with replace:true DELETES all variables not included in the new set — dangerous; use with care.
Setting a variable triggers a deployment by default unless skipDeploys is used.
Project tokens must use the Project-Access-Token header.
Reference values resolve at deploy time; unrendered:true shows raw ${{...}} syntax.
Give your agent this knowledge — and 16,500+ more routes
One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?