> This page is for Developer Documentation.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.benchling.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.benchling.com/_mcp/server.

# Introduction to App Status

Keeping users informed about ongoing processes, and providing descriptive messaging when
errors occur, is a crucial part of effective app design. Users interacting with app canvases
may need in-place feedback about actions they've taken, while admins debugging apps need a
historical log of app processes instead. Often this information lives in the UI or logs of an
external system, but for simpler scripts and integrations where Benchling is the system of
record, App Status gives app developers a standardized way to communicate it to users in
Benchling.

## Key concepts

Two concepts underpin App Status: **sessions** and **messages**.

* **Sessions** are the 'unit of work' for an app operating on a specific tenant. Think of
  them as individual jobs or tasks an app performs for a tenant. They are time-bounded and
  discrete, and an app can have concurrent sessions representing distinct operations.
* **Messages** are user-facing communications attached to a specific session. Messages are
  appended to a session as the app works, and a session's messages form an immutable log.
  Sessions can be used alone, but messages let developers communicate more granular and
  descriptive updates for tasks in progress.

## Working with App Status

Before an example, we'll cover these concepts in more detail. Use cases for app status vary
widely, but these ideas are broadly relevant and provide a foundation for building robust
applications.

### Sessions

A session represents a unit of work performed by an app for a tenant. The size and scope of
that unit varies from app to app. A session might correspond to a small, short task, or to a
long-lived one like a legacy data import. Either way, the important thing is that sessions
have a duration and a clear endpoint.

Sessions do not need to be uniform in duration, and an app can have multiple concurrent
sessions at any time. Some examples of units of work that fit a single session well:

* An interactive wizard using app canvas, letting a scientist select a set of codons to be
  optimized
* A legacy notebook import script that imports data over the course of several days
* A single stage of an NGS pipeline, with each stage corresponding to a discrete session

### Using sessions

Apps create and manage their own sessions using the Sessions API. An example JSON request
body to create a session:

```json
{
  "appId": "app_197264",
  "messages": [
    {
      "content": "Transferring 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "INFO"
    }
  ],
  "name": "Transfer Reagents",
  "timeoutSeconds": 2592000
}
```

Creating a session involves the following fields, in addition to `appId`:

| Field            | Type    | Description                                                                                                                                                                                  |
| ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `timeoutSeconds` | integer | A value in seconds, after which Benchling closes the session. All sessions *must* have a timeout. The value can be increased if necessary, up to a maximum of **30 days** (2592000 seconds). |
| `name`           | string  | A user-facing text value describing the session. A session's name *cannot be changed* once set.                                                                                              |
| `messages`       | array   | An array of up to 10 messages in a given PATCH request. See [Messages](#messages) below.                                                                                                     |

Newly created sessions have additional fields set by Benchling:

| Field        | Type        | Description                                                     |
| ------------ | ----------- | --------------------------------------------------------------- |
| `createdAt`  | timestamp   | When the session was created; read-only, set by Benchling.      |
| `modifiedAt` | timestamp   | When the session was last updated; read-only, set by Benchling. |
| `status`     | enumeration | The overall status of the session. See the values below.        |

A session's `status` is one of:

| Status                    | Meaning                                                                                                                    |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `RUNNING`                 | The session and the process it represents are active. This is the default status Benchling sets when a session is created. |
| `SUCCEEDED`               | The session is complete and the process it represents was successful.                                                      |
| `COMPLETED_WITH_WARNINGS` | The session is complete and the process it represents was partially successful.                                            |
| `FAILED`                  | The session is complete and the process it represents has failed.                                                          |
| `TIMEOUT`                 | The session and the process it represents timed out before completing.                                                     |

Along with `createdAt` and `modifiedAt`, which Benchling sets automatically, `status` is set
to `RUNNING` by default when a new session is created. The app later updates the session with
a *terminal status* when the session is complete.

### Messages

A message represents a discrete update related to a particular session. Messages are an
optional component of app status that adds clarity and specificity. A message is *always*
tied to a specific session, and should provide more granular detail on the processes or tasks
the app completes as part of it. Messages are particularly useful when a process includes a
number of small steps, or to report progress on a long-running task.

A session supports an unlimited number of messages, though a maximum of 10 can be included in
a single PATCH request. Messages are immutable and always appear in reverse chronological
order. They can contain a maximum of 200 characters and up to 10 linked Benchling entities
(see below). An app canvas shows only the most recent message for a session, while the
Benchling admin UI shows up to 100 recent messages.

### Using messages

Up to 10 messages can be included at a time when creating or updating a session. An individual
message looks like this:

```json
{
  "content": "Transferred 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
  "style": "SUCCESS"
}
```

A message must include a `content` field and may optionally include a `style` field:

| Field     | Type        | Description                                                                                                                                                                                                                                                                                                      |
| --------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `content` | string      | The message text, up to 200 characters. Can optionally include up to 10 linked Benchling entities, rendered as "chips" in the Benchling UI. These references take the form of a key-value pair surrounded by braces, where `id` is the key and a Benchling API ID is the value, for example `{id:ent_a0SApq3z}`. |
| `style`   | enumeration | An optional enum dictating how the message is rendered in the Benchling UI. Options are `ERROR`, `INFO`, `NONE`, `SUCCESS`, and `WARNING`.                                                                                                                                                                       |

### Associating a session with a canvas

For apps that use [app canvas](/docs/introduction-to-app-canvas) for user interactions,
session information can optionally be shown in place on the canvas.

Use the
[Update canvas endpoint](/docs/api/v2/benchling-api/apps/update-app-canvas) and set
the canvas's `sessionId` to the associated session:

```json
{
  "sessionId": "sesn_nTUPej8K"
}
```

As changes are made to the session, such as its overall status or new messages, they are
automatically shown to any user viewing the associated canvas.

The association can be removed by updating the canvas to set `sessionId` to `null`.

## Example

Here we'll walk through using app status to provide information to users. The relevant unit of
work is completing a transfer of some material into a container. We start by creating a
session using the request body from earlier:

```json
{
  "appId": "app_197264",
  "messages": [
    {
      "content": "Transferring 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "INFO"
    }
  ],
  "name": "Transfer Reagents",
  "timeoutSeconds": 2592000
}
```

The session created by that request looks like this:

```json
{
  "appId": "app_197264",
  "createdAt": "2023-05-22T19:40:52.022Z",
  "id": "sesn_nTUPej8K",
  "messages": [
    {
      "content": "Transferring 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "INFO"
    }
  ],
  "modifiedAt": "2023-05-22T19:40:52.022Z",
  "name": "Transfer Reagents",
  "status": "RUNNING",
  "timeoutSeconds": 2592000
}
```

Once created, a session can be updated using the
[Update session endpoint](/docs/api/v2/benchling-api/apps/update-app-session).
Updating might involve increasing the timeout, appending new messages, or changing the
session status.

Once the transfer completes, updating our session might look like this:

```json
{
  "messages": [
    {
      "content": "Successfully transferred 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "SUCCESS"
    }
  ],
  "status": "SUCCEEDED",
  "timeoutSeconds": 2592000
}
```

This updates the session to reflect that it completed successfully, with a new message
carrying additional detail. The final state of the session:

```json
{
  "appId": "app_197264",
  "createdAt": "2023-05-22T19:40:52.022Z",
  "id": "sesn_nTUPej8K",
  "messages": [
    {
      "content": "Successfully transferred 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "SUCCESS"
    },
    {
      "content": "Transferring 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "INFO"
    }
  ],
  "modifiedAt": "2023-05-22T19:45:52.022Z",
  "name": "Transfer Reagents",
  "status": "SUCCEEDED",
  "timeoutSeconds": 2592000
}
```

Using app status, we provided real-time updates on the transfer to the user in Benchling. Had
the transfer failed instead, we would have made a different update:

```json
{
  "messages": [
    {
      "content": "Could not transfer 4ml of {id:ent_a0SApq3z} to {id:con_ae92kBv9}.",
      "style": "ERROR"
    }
  ],
  "status": "FAILED",
  "timeoutSeconds": 2592000
}
```