> Documentation index: https://docs.beetl.io/llms.txt

# Apps

> Ready-made applications that read your datasets and publish results back as datasets.

Source: https://docs.beetl.io/apps/
Last updated: 2026-10-28

An app is a ready-made application provided by Beetl. It reads datasets you choose, does its job on
each run, and publishes the results back as datasets that you can query like any other. Apps
belong to the workspace, so every user in the tenant can see them and run them.

## Available apps

Each app has its own page with what it does, what it needs as input, what it publishes and its
limits. Apps are grouped by category.

| Category  | App                                    | What it does                        |
| --------- | -------------------------------------- | ----------------------------------- |
| Logistics | [Pallet Planner](https://docs.beetl.io/apps/pallet-planner) | Turns one order into a pallet plan. |

## Create an app

Apps have no sidebar entry. You create them on the Home canvas.

    ### Start from the canvas [#start-from-the-canvas]

    On Home, right-click the canvas and choose **New app**. Pick an app type and give the app a name.

    ### Bind your datasets [#bind-your-datasets]

    Bind each input dataset to an alias, which is the name the app and its input query use for that
    dataset. Only materialized datasets can be bound. Registered and external datasets are refused
    with `APP_INPUT_NOT_VERSIONED`.

    Each binding has a **Trigger on update** switch, on by default. A binding that would create a loop,
    for example by reading an app's own output, is refused with `APP_INPUT_CYCLE`.

    ### Check the input query [#check-the-input-query]

    Open the app's settings and review the input query, then set a schedule if you want one.

On the graph, an app is a node with a Reads edge from each input dataset and a Produces edge to each
output dataset. Click a node to open a settings pane with **Details**, **Config** and **Runs**.
Double-click it to open the app itself. See [Data landscape](https://docs.beetl.io/query/data-landscape).

## Edit the input query

The input query is a `SELECT` over `inputs.<alias>` that shapes what the app receives, for example
renaming columns or filtering to one customer. The settings page shows a 50-row preview so you can
check the shape before you run. The SQL follows the [DataFusion dialect](https://docs.beetl.io/query/datafusion-sql).

A run reads one consistent version of each input dataset, so an update that lands mid-run does not
change what that run sees.

## Run an app

An app starts in one of three ways:

* Manually, from the app.
* On a schedule: a cron expression with a time zone.
* When an input dataset updates, for each binding whose **Trigger on update** switch is on.

A run moves through these states:

| State                | Meaning                                                            |
| -------------------- | ------------------------------------------------------------------ |
| Pending              | Queued, not started.                                               |
| Processing, Retrying | The app is working on the inputs.                                  |
| AwaitingPublication  | The result is ready and is being published to the output datasets. |
| Paused               | Publication did not complete and needs your decision.              |
| Succeeded            | The outputs are published.                                         |
| Failed               | The run ended without publishing.                                  |

You cannot edit an app's settings while a run holds it. The request fails with `APP_BUSY`; try
again when the run finishes. A run cannot be cancelled once it has started. See
[Runs](https://docs.beetl.io/concepts/runs-and-jobs).

## Publication and outputs

Each run publishes its results as Bronze datasets named `app_...`, and replaces them on every run.
Query them in the [SQL editor](https://docs.beetl.io/query/sql-editor) or use them in a [pipeline](https://docs.beetl.io/concepts/pipelines)
as a source. See [Datasets and tiers](https://docs.beetl.io/concepts/datasets-and-tiers).

* Do not use an app's output dataset as a pipeline destination. The app replaces it on every run.
* Deleting an app keeps its output datasets.
* Remove a dataset from an app before you delete the dataset.

## If a run fails or pauses

Open the app's **Runs** tab to see each run and its state.

* **Failed:** read the reason on the run. The previously published outputs are unchanged. Fix the
  input data or the input query and run again.
* **Paused:** publication stopped part way. Choose **Resume publication** to continue, or **Abandon
  publication** to stop. Datasets already published stay as they are, and queued runs can continue.
* **APP\_BUSY:** a run is in progress. Wait and retry the change.

| Code                                 | Meaning and what to do                                   |
| ------------------------------------ | -------------------------------------------------------- |
| `APP_NOT_FOUND`, `APP_RUN_NOT_FOUND` | The app or run does not exist, or was deleted.           |
| `APP_DISABLED`                       | The app is disabled.                                     |
| `APP_UNAVAILABLE`                    | The app type is unavailable. Try again later.            |
| `APP_RUN_NOT_PAUSED`                 | You tried to resume or abandon a run that is not paused. |
| `INVALID_APP_SCHEDULE`               | The cron expression or time zone is invalid.             |
| `UNKNOWN_APP_INPUT_QUERY`            | The app has no input query by that name.                 |
| `APP_INPUT_NOT_FOUND`                | No input is bound under that alias.                      |

See [Error codes](https://docs.beetl.io/reference/error-codes) for the full list.

## Working with the assistant

In chat, the assistant can list, create, configure and run apps, and can open and operate an app's
screens for you. Every change asks for your confirmation in chat before it happens. See
[Building with the assistant](https://docs.beetl.io/chat/building-with-the-assistant) and
[The agent trust boundary](https://docs.beetl.io/concepts/agent-trust-boundary).

Over MCP, apps are read only. A client can list app types and instances, preview an input query and
read runs, but it cannot create or change apps. See [Tool reference](https://docs.beetl.io/mcp/tool-reference).
