Skip to main content
Calling a unified operation means naming which steps to run and how to route each service. Nothing fans out by default — that is deliberate.

From your application

In TypeScript targets is a call option; in Python it is the second argument.

Targets

targets is the exact subset of binding steps to execute. One or many are valid, and the set must be dependency-closed — if a step you name depends on another, name that one too. Dependencies are never invoked secretly on your behalf.

Selectors

Selectors are keyed by configured service, while targets is keyed by binding step. That difference matters when several steps share one service: they share the one selector for it.
For a single selected OAuth or OIDC scheme, endUserRef alone is usually enough. One service selector is preflighted once and reused by every selected step and active rollback on that service.
Selectors carry routing identifiers only — never provider tokens or secrets. A selector keyed by an alias step is invalid unless that alias is also the real configured service key.

What preflight checks

Before any provider call, the Engine validates the dependency-closed target set, the selectors, the exact endpoints, and execution-token permission for every selected forward step and active rollback. Any preflight failure rejects the call with zero physical calls and no envelope. Inactive rollback declarations are not preflighted.

Reading the result

Without an operation-level output, you get the all-settled envelope:
Forward results preserve target order and carry success, error, or skipped. Rollbacks carry success or error plus triggeredBy / triggered_by. One provider failure never erases another result. With an operation-level output, your constructed object replaces that envelope entirely — no data wrapper, no {results, rollbacks}. A binding-level output without an operation output replaces only that target’s data inside the ordinary envelope.

When connected auth fails

Forward and rollback connected-auth failures return an authAction / auth_action so your application can complete the existing SDK auth flow and retry deliberately. Handle these rather than retrying blindly — a retry without the corresponding action will fail the same way.

Without the generated package

Unified operations run over REST like any other, with targets and per-service selectors in the body. Unified execution is the case where Idempotency-Key is required, not optional:
For a one-off check from a terminal, fused-cli sdk invoke takes the same targets — see testing from the CLI for its flags. Unified execution never defaults to every declared target, whichever route you take. Naming them is the safeguard.
Both non-package routes bound a unified aggregate at 17 MiB and each provider document at 1 MiB. The generated package keeps its broader gRPC transport, so a large aggregate is a reason to use it rather than curl.

Pagination

Pagination is inherited from each endpoint and its effective service-version policy. Physical calls may only lower the limit, and unified calls take a target-keyed pagination map beside targets and selectors. It remains one buffered graph call. Never loop pages or pass continuation tokens yourself.

Permissions

A generated call needs the SDK identity plus an execution token authorized for every selected forward operation and active rollback. There is no separate unified scope. CLI lookup needs app.read; sdk activity also needs audit.read.

Declare a unified operation

Bindings, dependencies, rollback, and shaping the return value.