Bundle Dispatch
bundle/ad-hoc is a dispatch sentinel, not a regular workflow. Submitting a run with name="bundle/ad-hoc" and an input.bundle array of {workflow, input} entries causes the engine to fan out one parallel slot per entry, each running its own per-entry workflow with its own input. The aggregated outputs come back on outputs[] with each entry’s workflow_name and kind populated.
Use bundle when you want a mixed deck of formats from a single brief — e.g. one carousel, one short video, and one text post for the same topic — without paying the round-trip cost of three separate API submissions.
When to pick which
Section titled “When to pick which”| Knob | Shape | Use case |
|---|---|---|
| single workflow | name="<workflow>", input={...} | One workflow, one output. |
input.variants: 3 | name="<workflow>", input={..., variants: 3} | Same workflow, three variant outputs (e.g. three image variants for selection). |
input.bundle: [...] | name="bundle/ad-hoc", input={bundle: [...]} | Different workflows, heterogeneous outputs (mixed-format deck). |
input.variants and input.bundle are mutually exclusive — the API rejects submissions that try to combine them.
Quick Start
Section titled “Quick Start”curl -X POST "$FABRIC_URL/v1/workflows/run?name=bundle/ad-hoc" \ -H "Authorization: Bearer $FABRIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "bundle": [ { "workflow": "carousel/generate", "input": { "topic": "AI productivity tips", "slide_count": 5 } }, { "workflow": "video/ai-shorts", "input": { "topic": "AI productivity tips" } }, { "workflow": "global/content-generate", "input": { "topic": "AI productivity tips", "content_types": ["text"] } } ] } }'import { FabricClient } from "@fabric-platform/sdk";
const fabric = new FabricClient({ apiKey: process.env.FABRIC_API_KEY });
const run = await fabric.workflows.runs.submit("bundle/ad-hoc", { input: { bundle: [ { workflow: "carousel/generate", input: { topic, slide_count: 5 } }, { workflow: "video/ai-shorts", input: { topic } }, { workflow: "global/content-generate", input: { topic, content_types: ["text"] } }, ], },});Input Shape
Section titled “Input Shape”| Field | Type | Required | Description |
|---|---|---|---|
bundle | array | yes | 1–10 entries; each runs one parallel slot. |
bundle[].workflow | string | yes | Canonical workflow name (must resolve in the registry for the caller’s org/team). |
bundle[].input | object | no | Input dict passed verbatim to the per-entry workflow. Defaults to {}. |
Validation runs before any subprocess spawns:
- Shape errors (missing
workflow, non-objectinput) collect across every entry — you get a single 400 with a per-index error list. - Each
bundle[].workflowis resolved through the hierarchical registry (team → org → global). - When
validate=true, each per-entry input is JSON-Schema-validated against its sub-workflow’sinput_schema.
Output Shape
Section titled “Output Shape”The run’s outputs[] contains one entry per bundle slot, in submission order:
{ "id": "...", "workflow_name": "bundle/ad-hoc", "outputs": [ { "variant_index": 0, "workflow_name": "carousel/generate", "kind": "carousel", "output": { "kind": "carousel", "topic": "...", "slides": [ ... ] } }, { "variant_index": 1, "workflow_name": "video/ai-shorts", "kind": "video", "output": { "platform_exports": [ ... ], "script": { ... } } }, { "variant_index": 2, "workflow_name": "global/content-generate", "kind": "text", "output": { "title": "...", "content": "...", "tags": [ ... ] } } ]}The run row is recorded under workflow_name = "bundle/ad-hoc" so the audit trail and quota accounting see one logical run; the per-slot workflow names live on each output entry.
Limits
Section titled “Limits”| Limit | Value | Reason |
|---|---|---|
bundle length | 1–10 | Matches the variants cap; single subprocess fan-out budget. |
| Mutually exclusive with | input.variants | The two knobs share the same fan-out budget. |
Errors
Section titled “Errors”| Code | When |
|---|---|
400 bundle_shape_invalid | One or more entries are malformed (missing workflow, non-object input, etc.). The details.errors array carries one entry per malformed bundle index. |
400 bundle_unknown_workflow | One or more bundle[].workflow names don’t resolve in the registry. |
| 400 plain | name=bundle/ad-hoc submitted without an input.bundle array — see the input shape above. |
See Also
Section titled “See Also”carousel/generate— slide-ordered deck for a single topicglobal/content-generate— text card with title + caption + tagsvideo/ai-shorts— short-form video with platform exports