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

# Workflows — runs & examples

> How runs and steps are tracked, the status model, and a complete annotated workflow.

## Runs

Each execution is a **workflow run**.

| Field                         | Meaning                                                                                                  |
| ----------------------------- | -------------------------------------------------------------------------------------------------------- |
| `status`                      | `PENDING → RUNNING → COMPLETED / FAILED / CANCELLED`.                                                    |
| `triggeredAt` / `completedAt` | Start and terminal timestamps.                                                                           |
| `triggerContext`              | `{ entityType, matchedEntityIds, includeTags, excludeTags }` — what the trigger matched.                 |
| `outputSummary`               | Aggregated counters: `totalPlansCreated`, `totalItemsAdded`, `totalItemsSkipped`, `totalErrorsRecorded`. |
| `errorMessage`                | Terminal error reason, if failed.                                                                        |

## Steps

Each node produces one **run step**, so you can see exactly what happened at every node.

| Field                                         | Meaning                                                                   |
| --------------------------------------------- | ------------------------------------------------------------------------- |
| `nodeId` / `nodeType` / `actionType`          | Which node ran.                                                           |
| `status`                                      | `PENDING` · `RUNNING` · `SUCCEEDED` · `FAILED` · `SKIPPED` · `CANCELLED`. |
| `startedAt` / `completedAt` / `durationMs`    | Timing.                                                                   |
| `resolvedInput`                               | The node config **after** interpolation — what actually ran.              |
| `output`                                      | The node's output (feeds `{{steps.<nodeId>.output.*}}`).                  |
| `errorMessage` / `errorCode` / `errorDetails` | Failure detail.                                                           |
| `retryCount`                                  | Attempt number.                                                           |
| `logs`                                        | Per-step logs.                                                            |

<Note>
  Steps are keyed uniquely by `(workflowRunId, nodeId)`, so the data platform can retry a
  run idempotently without duplicating step records. A `SKIPPED` step is intentional (e.g.
  a filter matched nothing or a markdown window wasn't active).
</Note>

## Complete example

A minimal restock automation: *when a `PRODUCT` is tagged, create a restock plan and add
10 units of every item.*

```json theme={null}
{
  "nodes": [
    {
      "id": "n-trigger",
      "type": "trigger",
      "position": { "x": 0, "y": 0 },
      "data": { "nodeType": "TRIGGER", "entityType": "PRODUCT", "includeTags": ["fast-mover"], "excludeTags": [] }
    },
    {
      "id": "n-create",
      "type": "createPlan",
      "position": { "x": 250, "y": 0 },
      "data": {
        "nodeType": "ACTION",
        "actionType": "CREATE_OR_GET_PLAN",
        "planType": "RESTOCK",
        "brandSource": { "kind": "fromTrigger" },
        "collectionSource": { "kind": "fromTrigger" },
        "deadline": { "kind": "relative", "offsetDays": 30 }
      }
    },
    {
      "id": "n-add",
      "type": "addItems",
      "position": { "x": 500, "y": 0 },
      "data": {
        "nodeType": "ACTION",
        "actionType": "ADD_ITEMS_TO_PLAN",
        "planType": "RESTOCK",
        "sourcePlanNodeId": "n-create",
        "quantityStrategy": { "kind": "fixed", "quantity": 10 },
        "shopScope": { "kind": "all" },
        "sizeScope": { "kind": "all" }
      }
    },
    {
      "id": "n-email",
      "type": "sendEmail",
      "position": { "x": 750, "y": 0 },
      "data": {
        "nodeType": "ACTION",
        "actionType": "SEND_EMAIL",
        "to": ["buyer@example.com"],
        "cc": [], "bcc": [],
        "fromAddress": "no-reply@solya.app",
        "fromName": "Solya",
        "subject": "Restock plan {{steps.n-create.output.planName}} ready",
        "bodyFormat": "markdown",
        "bodyTemplate": "Added **{{steps.n-add.output.addedCount}}** items to plan {{steps.n-create.output.planId}}."
      }
    }
  ],
  "edges": [
    { "id": "e1", "source": "n-trigger", "target": "n-create" },
    { "id": "e2", "source": "n-create",  "target": "n-add" },
    { "id": "e3", "source": "n-add",     "target": "n-email" }
  ]
}
```

**What to notice**

* The **trigger** matches `PRODUCT` entities tagged `fast-mover`.
* The **create-plan** node derives brand and collection `fromTrigger`, with a 30-day
  relative deadline.
* The **add-items** node references the create-plan node via `sourcePlanNodeId` and adds a
  fixed 10 units across all shops and sizes.
* The **email** node interpolates the plan name, added count, and plan id from the two
  prior steps' outputs.
