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

# Ordered workflows

> Combine deterministic browser primitives with AI-assisted observe, act, and extract steps.

Ordered workflows are versioned JSON executed one step at a time. Use them when the sequence, failure point, and named outputs must be predictable.

## Build a workflow

<CodeGroup>
  ```typescript TypeScript theme={null}
  const run = await client
    .workflow("account-review")
    .navigate("https://example.com/accounts")
    .type("#account-search", "%account_id%", { submit: true })
    .extract("Return the account name and risk score", {
      name: "account",
      schema: {
        type: "object",
        properties: {
          name: { type: "string" },
          risk_score: { type: "number" }
        },
        required: ["name", "risk_score"]
      }
    })
    .done("Summarize the account review.")
    .run({ variables: { account_id: "acct_123" } })

  console.log(run.result?.outputs?.account)
  ```

  ```python Python theme={null}
  run = (
      client.workflow("account-review")
      .navigate("https://example.com/accounts")
      .type("#account-search", "%account_id%", submit=True)
      .extract(
          "Return the account name and risk score",
          name="account",
          schema={
              "type": "object",
              "properties": {
                  "name": {"type": "string"},
                  "risk_score": {"type": "number"},
              },
              "required": ["name", "risk_score"],
          },
      )
      .done("Summarize the account review.")
      .run(variables={"account_id": "acct_123"})
  )
  ```
</CodeGroup>

Named `read`, `observe`, and `extract` values appear under `run.result.outputs`.

## Choose the smallest useful primitive

| Primitive                       | Use it for                                 | Page-changing |
| ------------------------------- | ------------------------------------------ | ------------- |
| `navigate(url)`                 | Deterministic navigation                   | Yes           |
| `createTab(url?)`               | Open another browser tab                   | Yes           |
| `search(query)`                 | Search the public web                      | Yes           |
| `click(target)`                 | Click a CSS selector or observed index     | Yes           |
| `type(target, text)`            | Fill a field and optionally submit         | Yes           |
| `press(target, key)`            | Send a keyboard key or chord               | Yes           |
| `select(selector, value)`       | Choose a native select value               | Yes           |
| `hover(target)`                 | Hover a selector or observed index         | Yes           |
| `scroll(direction, pixels)`     | Scroll a known amount                      | Yes           |
| `read(options)`                 | Read deterministic page or element content | No            |
| `observe(instruction)`          | Inspect page state and actionable elements | No            |
| `act(instruction)`              | Perform one bounded goal-oriented action   | Yes           |
| `extract(instruction, options)` | Return named semantic data                 | No            |
| `wait(milliseconds)`            | Explicit synchronization                   | No            |
| `done(summary)`                 | Produce the final workflow summary         | No            |

Prefer selectors in reusable workflows. Numeric indexes refer to the most recent observation and are better suited to generated, short-lived flows.

## Portable workflow JSON

The builders send the same contract accepted by `POST /v1/runs`:

```json theme={null}
{
  "version": "1",
  "name": "example",
  "steps": [
    { "kind": "navigate", "url": "https://example.com" },
    { "kind": "click", "selector": "#details" },
    {
      "kind": "extract",
      "instruction": "Return the page title",
      "name": "page"
    }
  ]
}
```

## Variables

Use `%variable_name%` placeholders in string fields. Substitution happens before dispatch, and the SDK revalidates the resulting workflow.

<Warning>
  Do not use workflow variables for secrets. The resolved workflow is stored with the run.
</Warning>

## Validation limits

A workflow can contain at most 100 steps and serialize to at most 128 KB. Explicit waits range from 100 ms to 30 seconds. Navigation URLs must be absolute HTTP(S) URLs without embedded credentials. See [Limits](/production/limits) for the complete boundary.


## Related topics

- [TypeScript SDK](/sdks/typescript.md)
- [Python SDK](/sdks/python.md)
- [Infragrid overview](/overview.md)
- [Cancel a run](/reference/runs/cancel.md)
- [Get a run](/reference/runs/get.md)
