Skip to main content
After this guide, your workflow names the Stripe, GitHub, or Linear account it acts through by a key that resolves on whichever agent runs it, and a step whose key has no connection parks for a person instead of failing the run. Declare keys whenever a workflow will run on more than one agent or ship in an agent template; a literal connection id still works for a one-off. Verified against lua-cli 3.33.0. Before you begin
1

Declare the keys and reference them from steps

connections on createWorkflow lists one declaration per account the workflow acts through. A declared key then stands wherever a connection id is accepted: requiredConnections on a code, agent, or tool step, and workspace.credentialsRef for a Job-tier checkout (Use the Job tier).
src/workflows/refund-approval.ts
key matches ^[a-z][a-z0-9_-]{0,63}$ and is unique in the workflow; integrationType is the integration’s catalog slug; required records that the workflow cannot run without it; description tells whoever connects the account what it is for. The declarations travel with every pushed version and are not part of the graph hash. The step’s code still names the integration type: Integrations.passthrough relays the call through the agent’s Unified.to connection of that type, sends data as JSON, and returns the provider’s parsed body as res.data.
2

Compile

lua compile and lua push workflow refuse a requiredConnections entry or credentialsRef that looks like a key but is not declared, whether or not the workflow has a connections block:
Output
The path names the graph entry (graph.2 is the third entry in the chain). A declaration with a key outside the grammar, a duplicate key, or no integrationType is connection-declaration-invalid. A 24-character hex connection id is not a key and passes the compile; the platform verifies it at push.
3

Check per-environment values

Values that differ per agent but are not connections, such as an agent id or a timezone, use env.template('KEY') in the definition. lua push workflow resolves each key from the target environment; env-overlay shows what a version carries and whether each key is present, never the values.
Output
A missing key prints ❌ <n> key(s) missing from the agent env (<KEY>) and exits 1. Keys ending in SECRET, TOKEN, KEY, or PASSWORD are refused at build time (env-template-secret-key); read those with env('KEY') inside execute.
4

Verify how a key resolves

Push the workflow to an agent that has a Stripe connection and start a run. Before the first step that names the key is dispatched, the platform picks one connection and records the choice:
  • Candidates are the connections of the declared integrationType that belong to the agent, else the organization’s. A person’s own connection is never a candidate: a run acts as the agent, not as the user who started it.
  • One candidate is taken. Among several, the one whose account label equals the key wins; otherwise the step fails as ambiguous.
  • The key is resolved once per run, the first time any step needs it, appended to the events as connection.resolved, and printed by lua workflows status <runId> on a Connections: line (stripe → <connectionId> (stripe, agent)).
On an agent with no Stripe connection, postRefund fails with credentials_unresolved and Connect a stripe connection to this agent (or its org) for connection key 'stripe', then retry the step.; with several unlabeled candidates the message lists them and asks you to label one stripe. Because the step declares onError: 'park', the run waits on an exception gate: connect the integration, then lua workflows retry-step <runId> --step postRefund resumes it without losing completed work. A connection that resolves but whose credentials are no longer usable fails the step with credentials_revoked.

Options you may need

Connections in a Job-tier coding turn

toolScope.connectionIds on a Job-tier agent step mounts connections into the coding turn as MCP servers. Declared keys resolve there at run time, but this slot is not checked by lua compile, so a typo surfaces only when the step runs.

Literal ids

A value that is a connection id never enters the resolver: it is mounted or minted as is, and a workflow with no connections block behaves as before. Prefer keys for anything you push to more than one agent.

If it isn’t working

A requiredConnections entry or credentialsRef is a lowercase slug that no declaration names. Add connections: [{ key: '<slug>', integrationType: '<type>' }] to createWorkflow, or replace the slug with a connection id.
No connection of the declared type on the agent or its organization, or several without one labeled with the key. Connect the integration or set one connection’s display name to the key, then lua workflows retry-step <runId> --step <id>.
The resolved connection’s credentials are no longer usable. Reconnect it with lua integrations connect --integration <type>, then retry the step.

Next steps

Use the Job tier

How credentialsRef becomes a short-lived token for the checkout.

About integrations

Unified.to integrations, scopes, and passthrough.

Operate runs

Exception gates, retry-step, and resolve-step.