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

# Devin SDK example: session board

> A Next.js board of every cloud Devin session, grouped by working, needs you, or done, kept live by one server-side WebSocket with no polling.

> [!NOTE]
>
> Source:
> [`session-board`](https://github.com/COG-GTM/devin-sdk-examples/tree/main/session-board)

Every cloud session on one screen, grouped by whether Devin is **working**, **needs you**, or
**done**. A Next.js app: the server holds one connection to Devin, the browser watches the board
move. Each card is one session — its title, where it was started and on which repos, the one thing
you have to do (when there is one), what Devin is doing right now, the last thing it said, and its
pull requests. Clicking a card opens the session in the Devin web app.

![Session board: three columns of session cards labelled needs you, working and done, each card showing the session title, repos, current activity and pull requests](https://mintcdn.com/cognitionai/BR9pVI7VuIdWd-ef/images/sdk/session-board.png?fit=max\&auto=format\&n=BR9pVI7VuIdWd-ef\&q=85\&s=cd0658e7e0bcf91a820545da59035ba9)

The board: needs you, working and done columns

```mermaid theme={null}
flowchart LR
    browser["Browser tabs"] <-- "SSE /api/board/stream" --> server["Next.js server<br/>lib/board.ts"]
    server <-- "one WebSocket<br/>attach() × every session" --> cloud["Devin cloud"]
```

| File | Role |
| - | - |
| `lib/board.ts` | The board, server-side: `createDevin()`, seed from `listSessionsPage()`, `attach()` + `session.events()` per session |
| `lib/card.ts` | The wire model both sides share: `Card`, its columns, the `BoardEvent` stream |
| `app/api/board/stream/route.ts` | The board as server-sent events: a snapshot on connect, then a `card` per change |
| `lib/use-board.ts` | The browser's copy of the board, fed by `EventSource` |
| `app/board.tsx` | Columns, window / search / automation filters, the live indicator |
| `components/session-card.tsx` | One session as a card |
| `Dockerfile` | The deployable: one container that talks to Devin's cloud |

## How it works

* One `createDevin()` connection, on the server, shared by every tab. `listSessionsPage()` seeds a
  card per session from the `_meta` each entry carries (`statusEnum`, `userActionRequired`,
  `pendingRequest`, `currentActivity`, `sessionRepos`, `sessionPRs`, …), so the board is right
  before any live update arrives.
* `devin.attach(id)` joins each session and `session.events()` yields every update for it as typed
  events, from turns started in the web app, Slack, or another script alike. A `status` event moves
  the card and names the ask; `activity` and `tool_call` say what Devin is doing; `message_delta`
  keeps the last thing Devin said; `pull_request` marks a PR as changed until the next scan refreshes
  it; a `permission_request` tool call turns into "Approve …" until it is answered.
* Every 30 s `listSessionsPage({ updatedAfter })` runs again to attach to sessions created or
  updated since, following pagination to the end, and repairs any transition the board missed while
  disconnected. Live session events need no polling.
* Observers leave `onPermission` unset: an observer's answer to a permission request is a real
  decision, and the client driving the session should keep it.
* `/api/board/stream` sends the current board as a `snapshot`, then a `card` per change.
  `EventSource` reconnects on its own and every connection starts with a fresh snapshot, so the
  browser keeps no bookkeeping.

Attached sessions are cheap: one WebSocket and a few megabytes for hundreds of them; idle sessions
send nothing. The board stays attached after the last tab closes, so a tab that opens later gets a
current snapshot at once.

## Run

```sh theme={null}
git clone https://github.com/COG-GTM/devin-sdk-examples
cd devin-sdk-examples/session-board
bun install                     # @cognition-ai/sdk from npm (the pinned beta)
export DEVIN_API_KEY=cog_…
bun run dev                     # http://localhost:3211
```

Start a turn in one of the listed sessions from the web app and watch its card move.

## Deploy

One long-running process — the WebSocket to Devin lives in it — so it wants a host that keeps a
container up (a VM, ECS, Fly, Railway), not serverless. The `Dockerfile` builds it:

```sh theme={null}
docker build -t session-board .
docker run -p 3211:3211 -e DEVIN_API_KEY session-board
```

> [!WARNING]
>
> This is a single-user demo: there is no login, and anyone who can reach the board sees every
> session `DEVIN_API_KEY` can see. Run it on your own machine, or put it behind your own auth or
> network before sharing a URL.

> [card] [Watching sessions](https://docs.devin.ai/sdk/guides/watching-sessions.md)
>
> `attach()`, `events()` and the status metadata the board is built on.


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