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

# drawer.json

> The action or proactive-flow spec for drawers.

A Drawer is a reusable package. Schema v2 distinguishes an `action` Drawer,
which is pressed as a graph of steps, from a `flow` Drawer, which defines a
proactive board that a platform runtime activates and supervises. Its source of
truth is `drawer.json`.

```text theme={null}
~/.buttons/drawers/<name>/
  drawer.json
  pressed/
```

Project-local drawers use the same shape under `.buttons/drawers/<name>/`.

## Action Drawer example

```json theme={null}
{
  "schema_version": 2,
  "name": "release-flow",
  "drawer_kind": "action",
  "version": "1",
  "inputs": [
    { "name": "env", "type": "enum", "required": true, "values": ["staging", "prod"] }
  ],
  "steps": [
    { "id": "build", "kind": "button", "button": "build-artifact" },
    {
      "id": "publish",
      "kind": "button",
      "button": "publish-artifact",
      "args": {
        "env": "${inputs.env}",
        "version": "${build.output.version}"
      }
    }
  ],
  "return": {
    "version": "${build.output.version}",
    "url": "${publish.output.url}"
  }
}
```

Schema-v1 action Drawers remain readable, installable, and pressable. New
Drawers are written as schema v2.

## Flow Drawer example

Flow Drawers describe arbitrary board stages and policy. They do not contain
`steps` and cannot be pressed locally as action Drawers.

```json theme={null}
{
  "schema_version": 2,
  "name": "software-delivery",
  "drawer_kind": "flow",
  "version": "1",
  "flow": {
    "initial_stage": "intake",
    "manager": {
      "agent": "activation.manager",
      "system_prompt": "Supervise this flow and return one valid decision.",
      "heartbeat_seconds": 300
    },
    "stages": [
      {
        "id": "intake",
        "title": "Intake",
        "worker": { "agent": "activation.worker" },
        "transitions": ["research"]
      },
      {
        "id": "research",
        "title": "Research",
        "transitions": ["done"]
      },
      { "id": "done", "title": "Done" }
    ]
  }
}
```

Create and edit the definition through the CLI:

```bash theme={null}
buttons drawer create software-delivery --kind flow
buttons drawer software-delivery stage add intake --title "Intake"
buttons drawer software-delivery stage add research --title "Research"
buttons drawer software-delivery set flow.initial_stage=intake
buttons drawer software-delivery set flow.manager.agent=activation.manager
buttons drawer software-delivery set 'flow.stages.intake.transitions=["research"]'
```

Publishing a valid flow Drawer adds a normalized `flow-definition.json` to the
immutable artifact and sends its SHA-256 as registry metadata. Installation
rejects the package if that definition does not exactly match `drawer.json`.

## Top-level fields

| Field | Meaning |
| - | - |
| `schema_version` | Drawer spec version. Current version is `2`; version `1` remains supported for legacy action Drawers. |
| `name` | Drawer name. |
| `drawer_kind` | Required in schema v2: `action` or `flow`. |
| `description` | Human-readable one-liner. |
| `version` | Drawer package content version. New drawers start at `1`; registry publish auto-bumps to the next number when the current immutable version already exists. |
| `inputs` | Values supplied at action Drawer press time. |
| `steps` | Ordered action steps; required only for action Drawers. |
| `flow` | Manager, limits, stages, transitions, triggers, sessions, retry, timeout, and concurrency policy; required only for flow Drawers. |
| `output_schema` | Optional JSON Schema for values exposed when called as a sub-drawer. |
| `return` | Map of output fields to `${...}` expressions. |
| `triggers` | Automatic invocation sources. Webhook triggers are live today. |
| `on_error` | Optional drawer to call after failure. |

## Step kinds

| Kind | Status | Purpose |
| - | - | - |
| `button` | Live | Press a button. |
| `drawer` | Live | Call another drawer as a sub-workflow. |
| `for_each` | Live | Iterate nested steps over an array. |
| `switch` | Live | Run the first matching branch. |
| `aggregate` | Live | Pluck values out of an array, often after `for_each`. |
| `wait` | Live | Pause for a duration or until an RFC3339 time. |
| `split`, `merge`, `transform`, `batch` | Reserved | Schema-reserved for future runtimes. |

## References

Step args and drawer fields can use `${...}` expressions. The expression body is CEL.

```text theme={null}
${inputs.env}
${build.output.version}
${env.GITHUB_TOKEN}
${webhooks.on-scrape-done}
${inputs.count * 2}
${has(build.output.url) ? build.output.url : "missing"}
```

Hyphenated step IDs are supported in refs; Buttons rewrites them internally so CEL can parse them.

## Inputs

Drawer inputs mirror button args and add `secret` redaction:

```json theme={null}
{
  "inputs": [
    { "name": "api_key", "type": "string", "required": true, "secret": true }
  ]
}
```

Secret inputs can still flow into a step's resolved args, but they are redacted from drawer history.

## Failure handling

Step-level `on_failure` controls one step:

```json theme={null}
{
  "on_failure": {
    "action": "retry",
    "max_attempts": 3,
    "backoff": {
      "strategy": "exponential",
      "initial_ms": 500,
      "factor": 2,
      "max_ms": 10000,
      "jitter": true
    }
  }
}
```

Supported actions are `stop`, `continue`, and `retry`.

Drawer-level `on_error` calls another drawer after a failed run. The handler receives `drawer`, `run_id`, `failed_step`, `error`, and redacted `inputs`.

## Webhook triggers

Webhook triggers are stored in `triggers`.

```json theme={null}
{
  "triggers": [
    {
      "kind": "webhook",
      "path": "/apify-done",
      "auth": {
        "type": "header",
        "header_name": "X-Buttons-Token",
        "header_value": "$ENV{APIFY_WEBHOOK_TOKEN}"
      }
    }
  ]
}
```

Inside the drawer, the request appears as `${inputs.webhook.body}`, plus headers, query, method, path, and `received_at`.

## Schema

Print the embedded JSON Schema:

```bash theme={null}
buttons drawer schema
```

The published copy lives at `docs/schemas/drawer.schema.json`.

## Related

* [Workflows](/buttons/workflows)
* [Webhook triggers](/buttons/webhook)
* [JSON output](/concepts/json-output)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.