> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Media Workflows visual builder and API

> Author editable templates or blank typed DAGs that coordinate asset gates, native StackShift services, bounded Stackie reasoning, and approved external integrations.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

Create, validate, publish, approve, activate, run, and inspect an immutable production media workflow.

## Prerequisites

* Assets access
* Publish authority for versions containing production, costly, or external actions
* An active execution principal that retains access to every referenced resource

## Workflow

<Steps>
  <Step>
    Open Assets Workflows and choose a template or blank canvas; both produce the same graph contract.
  </Step>

  <Step>
    Connect typed ports, configure nodes in the inspector, and resolve every validation issue.
  </Step>

  <Step>
    Save the draft with its expected revision. Layout-only edits do not change the semantic digest.
  </Step>

  <Step>
    Publish an immutable version. Review and approve its exact risks and constraints when required.
  </Step>

  <Step>
    Activate that version, then let its trigger dispatch or start a manual run.
  </Step>

  <Step>
    Inspect persisted node attempts, sanitized inputs/outputs, branch decisions, waits, nested Stackie calls, warnings, and approvals.
  </Step>
</Steps>

## Graph contract and validation limits

* One trigger; an acyclic, fully reachable graph; at most 100 nodes, 200 edges, depth 50, branch fan-out 10, and eight concurrently runnable nodes.
* Semantic definition and layout are separate. Position, viewport, grouping, and annotations do not change the semantic digest or invalidate approval.
* Nodes declare retry, timeout, and failure policy. Conditions support equals, not-equals, exists, contains, in, and numeric/date comparisons—no regex or arbitrary expression execution.
* Joins use `all_success`, `all_settled`, or `any_success`. Branches must terminate and edge ports must be type-compatible.
* Inline secrets and credential-bearing strings are rejected. Destructive, credential-revealing, billing, ownership, team-membership, arbitrary SQL/shell/JavaScript, and unrestricted HTTP operations are absent from the catalog.

## Minimal graph

```json theme={null}
{
  "version": 1,
  "nodes": [
    { "id": "upload", "type": "trigger.asset_upload" },
    { "id": "scan", "type": "stackshift.action", "action": "asset.scan", "config": { "asset_id": { "$input": "upload.asset_id" } } },
    { "id": "moderate", "type": "stackshift.action", "action": "asset.moderate", "config": { "asset_id": { "$input": "scan.asset_id" } } },
    { "id": "transform", "type": "stackshift.action", "action": "transform_asset", "config": { "asset_id": { "$input": "moderate.asset_id" }, "preset": "web-ready" } },
    { "id": "publish", "type": "stackshift.action", "action": "asset.publish", "config": { "asset_id": { "$input": "transform.asset_id" } } },
    { "id": "done", "type": "control.success" }
  ],
  "edges": [
    { "id": "e1", "source": "upload", "target": "scan" },
    { "id": "e2", "source": "scan", "target": "moderate" },
    { "id": "e3", "source": "moderate", "target": "transform" },
    { "id": "e4", "source": "transform", "target": "publish" },
    { "id": "e5", "source": "publish", "target": "done" }
  ]
}
```

## Triggers and node catalog

* Triggers: asset upload, asset lifecycle event, typed StackShift event, five-field cron with IANA timezone, signed inbound webhook, and manual run.
* Asset nodes: search/get, scan, moderate, analyze, transform, transcribe, generate, organize/tag/collect/move, branch/version promotion, publish, and signed webhook notification.
* Native StackShift actions cover registered reversible and governed operations across projects/apps, builds/deployments, databases/backups, S2/storage, domains/mail, mobile/commerce, compute/BYOC/sandboxes, incidents/governance, and notifications.
* Native actions invoke owning Go services directly under the workflow principal. They do not call loopback HTTP, mint internal PATs, or bypass service authorization and idempotency.
* Control nodes are condition, parallel split, join, durable delay, success, and failure. Integration nodes are governed Stackie and restricted external HTTP.

## Templates and blank canvas

* Secure Image Publish; Video Ready Publish; Scheduled Library Publish; AI Image Generation and Moderation; Moderation Review Branch; Transform, Publish, and Notify.
* Asset Publish and Project Redeploy; Approved Media and Mobile Release Promotion; Media Failure to Incident and Stackie Diagnosis; Asset Event to StackShift Mail Campaign; Cross-service Operations Review.
* Catalog responses mark each template `valid` and include concrete issues if an action is unavailable or configuration is incomplete. A template never silently becomes executable with a missing action.
* Every template opens as an ordinary editable graph. The desktop editor supports search, drag/drop, typed handles, reconnect, copy/paste, multi-select, groups, undo/redo, ELK auto-layout, minimap, and test output. The outline editor is the accessible and small-screen operating surface.

## Workflow API and SDK sequence

<CodeGroup>
  ```ts TypeScript theme={null}
  const catalog = await stackshift.assets.workflows.catalog()
  const draft = await stackshift.assets.workflows.create({
    name: 'Secure product media',
    template_key: 'secure-image-publish',
  })
  const validation = await stackshift.assets.workflows.validate(draft.id)
  if (!validation.valid) throw new Error(JSON.stringify(validation.issues))
  const version = await stackshift.assets.workflows.publish(draft.id, draft.revision)
  // Approve the pending version grant when the catalog marks a node as governed.
  await stackshift.assets.workflows.activate(draft.id, version.id, draft.revision + 1)
  const run = await stackshift.assets.workflows.run(draft.id, { idempotency_key: 'manual:2026-08-18' })
  const detail = await stackshift.assets.workflows.runDetail(run.id)
  ```

  ```bash CLI theme={null}
  stackshift asset workflow-catalog --output json
  stackshift asset workflow-create --data '{"name":"Secure product media","template_key":"secure-image-publish"}' --output json
  stackshift asset workflow-validate "$WORKFLOW_ID" --output json
  stackshift asset workflow-publish "$WORKFLOW_ID" --data '{"expected_revision":1}' --yes --output json
  stackshift asset workflow-approvals --query status=pending --output json
  stackshift asset workflow-approve "$APPROVAL_ID" --data '{"reason":"Reviewed media publish targets"}' --yes --output json
  stackshift asset workflow-activate "$WORKFLOW_ID" --data '{"version_id":"'$VERSION_ID'","expected_revision":2}' --yes
  stackshift asset workflow-run "$WORKFLOW_ID" --data "{}" --output json
  stackshift asset workflow-run-get "$RUN_ID" --output json
  ```
</CodeGroup>

## Expected result

<Check>
  Only the active immutable version receives events or schedules, and no path can publish an asset before successful scan and moderation.
</Check>

## Common failures

<Warning>
  * Autosave receives `412` because another editor changed the revision; compare and reload instead of overwriting.
  * Publish returns `422` because a node is unreachable, an edge type is incompatible, configuration is incomplete, or publish is not dominated by scan and moderation.
  * Activation returns `409` because a required version approval is pending, expired, or bound to an older semantic digest or connection revision.
  * A run fails before a node because the execution principal lost permission to a referenced account resource.
</Warning>

## Related guides

<CardGroup cols={2}>
  <Card title="Media Workflow authority, integrations, and recovery" href="/assets/media-workflow-security-and-operations">
    Operate workflow grants, execution principals, durable waits, restricted HTTP connections, signed inbound hooks, retries, cancellation, and post-publish warnings.
  </Card>

  <Card title="Deterministic image, video, and audio transforms" href="/assets/deterministic-media-transforms">
    Define ordered v2 transforms for images, video renditions, audio extraction, and timestamp thumbnails; store eager presets or materialize durable derivatives.
  </Card>

  <Card title="Stackie asset tools and MCP" href="/assets/stackie-asset-tools-and-mcp">
    Use the same governed asset actions from Stackie, workflow Stackie nodes, and stateless Streamable HTTP MCP clients.
  </Card>
</CardGroup>
