Documentation

Sub-pipelines

A pipeline can call another as a function — to factor out reusable logic or share a capability across organisations, with a full audit trail.

Beyond a certain point, copying the same sequence of nodes across ten pipelines becomes technical debt. Sub-pipelines allow a pipeline to call another as a function: define a piece of logic once, reuse it everywhere — including across organisations.

Two symmetric building blocks:

  • pipeline_callable (a receiver, declared on the Start node) exposes a pipeline behind a URL, with a typed input and output contract.
  • pipeline_call (a node) calls that pipeline: it maps its inputs from the current context and stores the result in an output key.

Exposing a pipeline (pipeline_callable)

On the "service" pipeline, you add a pipeline_callable receiver that declares:

  • Inputs — the list of expected parameters (name, type, required or optional).
  • Outputs — the keys of the returned result.
  • Response key — which context value constitutes the response (exchange.result by default).
  • Response mode — sync (the caller waits for a JSON response) or stream (real-time progress).
  • Time budget — maximum execution time (60 s by default, 300 s maximum).

An input declared as required and missing from the call makes the call fail (400).

The pipeline then receives a public URL (with a token) to share with the calling pipeline. The token is rotatable at any time to revoke access.

Calling a pipeline (pipeline_call)

On the "consumer" pipeline, the pipeline_call node is configured with:

  • The URL of the target pipeline (fixed, not templatable: it is analyzed on save to detect loops).
  • An input mapping — for each expected parameter, the context selector that supplies it.
  • The output key where the result is stored (exchange.subresult by default).
  • The mode (sync, ack, stream) and a timeout (30 s by default, 300 s maximum).

On failure (timeout, error, malformed response), the pipeline continues: the output key receives null and a ._error key describes what happened. It is your pipeline's responsibility to orchestrate the fallback (fallback branch, alert).

Cross-organisation calls: opt-in and audited

A sub-pipeline can be called by a different organisation — this is the foundation for sharing capabilities between entities. The model remains strict:

  • Rejected by default. Cross-organisation calls are only possible if the administrator of the exposed pipeline explicitly authorises it (allow_cross_org).
  • HMAC signature recommended. Once a cross-org call is opened, a shared secret is activated on both sides: every request is signed (X-Pipeline-Signature header), and the receiver rejects any absent or invalid signature (401). Once saved, this secret is never displayed again, on either side (see The visual editor, section Secrets); removing it on the caller side removes the signature, removing it on the exposed side removes the verification.
  • Everything is traced. Each invocation writes an audit record (calling organisation, node, depth, latency, status) — before execution, so that a trace exists even in the event of an incident. Both parties can consult their own logs (caller side and callee side), in accordance with GDPR access rights.

Billing: the called organisation pays for the resources (LLM, voice…) consumed during execution. Guest logic: you use your host's resources.

Loop prevention

A pipeline that called itself, directly or through a chain, would consume credits indefinitely. Two protections:

  • Static detection at registration (within an organisation): the editor refuses to publish a direct cycle (A → A) or indirect cycle (A → B → C → A), citing the offending chain.
  • Runtime guard (across organisations, where static visibility is impossible): each call propagates its depth; beyond 10 levels, the call is refused.

Execution modes

  • Synchronous (sync) — the node waits for the complete response. Suited to short-running operations.
  • No wait (ack) — the call is launched and the calling pipeline continues immediately; the output key stays empty.
  • Streaming (stream) — for a long-running sub-pipeline (LLM reasoning, batch processing), progress is received in real time (under <output key>._progress); the timeout then applies to the maximum delay without an event, not to the total duration.

When to use it

  • Factor out a sequence reused by multiple pipelines (summarise a thread, qualify a lead, verify a document).
  • Share a capability between organisations — one entity exposes "validate an invoice against the ERP", another consumes it, with an audit trail on both sides.
  • Parallelise a fan-out of independent sub-tasks from a loop.