# OpenMAIC Durable Session API Endpoints: Complete Reference

> Explore the nine OpenMAIC durable session API endpoints for complete agent session management. Create monitor steer cancel resume and stream events in real time.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: api-reference
- Published: 2026-09-02

---

**OpenMAIC provides nine RESTful API endpoints under `/api/agent/sessions` for full lifecycle management of durable agent sessions, including creation, monitoring, steering, cancellation, resumption, and real-time event streaming.**

The **durable session API** in OpenMAIC is implemented as Next.js Route Handlers in the `app/api/agent` directory. These endpoints give client applications complete control over long-running agent workflows that persist across server restarts. This guide covers every endpoint, its implementation file, and practical usage examples.

## Session Lifecycle Endpoints

OpenMAIC organizes durable session management into three categories: **CRUD operations**, **control plane actions**, and **real-time streaming**. All endpoints return JSON except the events stream, which uses Server-Sent Events (SSE).

### List and Create Sessions

The base `/api/agent/sessions` path in [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) handles listing and creation:

- **GET `/api/agent/sessions`** — Returns a paginated list of the caller's durable sessions
- **POST `/api/agent/sessions`** — Creates a new session with initial prompt, material IDs, and optional configuration

```javascript
// Create a new durable session
async function createSession(prompt, materialIds = []) {
  const resp = await fetch('/api/agent/sessions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ prompt, materialIds })
  });
  return resp.json(); // → { sessionId, status: 'queued', ... }
}

```

### Single Session Operations

The same [`route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/route.ts) file handles individual session access at `/api/agent/sessions/:sessionId`:

- **GET `/api/agent/sessions/:sessionId`** — Retrieves session metadata including status, start time, progress, and material links
- **PATCH `/api/agent/sessions/:sessionId`** — Updates mutable fields like title or user tags
- **DELETE `/api/agent/sessions/:sessionId`** — Permanently removes the session and runtime data

```javascript
// Get session details
async function getSession(sessionId) {
  const resp = await fetch(`/api/agent/sessions/${sessionId}`);
  return resp.json();
}

// Update session metadata
async function updateSession(sessionId, updates) {
  const resp = await fetch(`/api/agent/sessions/${sessionId}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(updates)
  });
  return resp.json();
}

```

## Control Plane Endpoints

Active sessions support three specialized control operations, each implemented as a dedicated sub-route.

### Cancel a Running Session

**Implemented in:** `app/api/agent/sessions/[sessionId]/cancel/route.ts`

The cancel endpoint stops processing and marks the session status as `canceled`:

```javascript
async function cancelSession(sessionId) {
  await fetch(`/api/agent/sessions/${sessionId}/cancel`, { method: 'POST' });
}

```

This updates the session's status in the persistent store and signals the runner to terminate.

### Resume a Persisted Session

**Implemented in:** `app/api/agent/sessions/[sessionId]/resume/route.ts`

Resume re-hydrates a previously persisted session, allowing the agent to continue from its checkpoint:

```javascript
async function resumeSession(sessionId) {
  await fetch(`/api/agent/sessions/${sessionId}/resume`, { method: 'POST' });
}

```

This endpoint is critical for recovering sessions after server restarts or intentional pauses.

### Steer an Active Session

**Implemented in:** `app/api/agent/sessions/[sessionId]/steer/route.ts`

Steering sends real-time instructions to a running agent without interrupting the session:

```javascript
async function steerSession(sessionId, instruction) {
  await fetch(`/api/agent/sessions/${sessionId}/steer`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ instruction })
  });
}

```

Common steering instructions include `"regenerate slide 3"` or `"add a quiz"`.

## Real-Time Event Streaming

**Implemented in:** `app/api/agent/sessions/[sessionId]/events/route.ts`

The events endpoint provides a **Server-Sent Events (SSE)** stream for live updates:

```javascript
function subscribeSessionEvents(sessionId, onEvent) {
  const evtSource = new EventSource(`/api/agent/sessions/${sessionId}/events`);
  evtSource.onmessage = e => onEvent(JSON.parse(e.data));
  return () => evtSource.close(); // cleanup function
}

// Usage
const unsubscribe = subscribeSessionEvents('sess_abc123', (event) => {
  console.log(event.type, event.payload); // tool calls, messages, status changes
});

```

The SSE stream pushes incremental tool calls, agent messages, and status updates to connected clients.

## Endpoint Reference Table

| Operation | Method | URL | Implementation File |
|-----------|--------|-----|---------------------|
| List sessions | `GET` | `/api/agent/sessions` | [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) |
| Create session | `POST` | `/api/agent/sessions` | [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) |
| Get details | `GET` | `/api/agent/sessions/:sessionId` | [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) |
| Update metadata | `PATCH` | `/api/agent/sessions/:sessionId` | [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) |
| Delete session | `DELETE` | `/api/agent/sessions/:sessionId` | [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) |
| Cancel | `POST` | `/api/agent/sessions/:sessionId/cancel` | `app/api/agent/sessions/[sessionId]/cancel/route.ts` |
| Resume | `POST` | `/api/agent/sessions/:sessionId/resume` | `app/api/agent/sessions/[sessionId]/resume/route.ts` |
| Steer | `POST` | `/api/agent/sessions/:sessionId/steer` | `app/api/agent/sessions/[sessionId]/steer/route.ts` |
| Stream events | `GET` | `/api/agent/sessions/:sessionId/events` | `app/api/agent/sessions/[sessionId]/events/route.ts` |

## Summary

- **Base path:** All durable session API endpoints are under `/api/agent/sessions`
- **CRUD operations:** Consolidated in [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts) (GET list, POST create, GET detail, PATCH update, DELETE remove)
- **Control actions:** Split into dedicated sub-routes for cancel, resume, and steer operations
- **Real-time updates:** SSE endpoint at `/events` streams live agent output
- **Client compatibility:** Standard fetch API and EventSource; adjust base URL for cross-origin calls

## Frequently Asked Questions

### What distinguishes a "durable" session from a regular agent invocation?

A **durable session** persists its state to a backing store and can survive server restarts, network interruptions, and explicit pauses. Regular invocations are ephemeral—if the process terminates, all context is lost. The durable session API provides endpoints to resume, cancel, and steer these long-running workflows.

### Can I steer a session that is not actively running?

No. The steer endpoint (`POST /api/agent/sessions/:sessionId/steer`) accepts instructions only for sessions in an active running state. Attempting to steer a queued, completed, or canceled session returns an error status. Use the PATCH endpoint to modify metadata on inactive sessions instead.

### How do I handle reconnection if the SSE stream drops?

The EventSource API automatically attempts reconnection with exponential backoff. For production resilience, implement an `onerror` handler that monitors `evtSource.readyState`, applies a maximum retry limit, and falls back to polling `GET /api/agent/sessions/:sessionId` for status updates if SSE remains unavailable.