---
title: "List a run's sessions"
method: GET
path: "/projects/{projectId}/goal-runs/{runId}/sessions"
tags: ["Swarm runs"]
---

# List a run's sessions

`GET /projects/{projectId}/goal-runs/{runId}/sessions`

One entry per chat session the run produced. Summaries, not transcripts — read a transcript through the chat-session routes using `id`.

## Request body

- object
  - `cursor` string — Opaque pagination cursor from a previous response's `nextCursor`. Don't parse it.

## Response `200`

A page of sessions.

- GoalRunSessionPage
  - `items` GoalRunSession[], required
    - `id` string, required — The session's document id — the same value `GET /chat-sessions` returns as `id`, so a session found here can be looked up there.
    - `chatSessionId` string, required — The RUNTIME key for the same session, used by the chat transport and the app's deep links. Distinct from `id` and NOT interchangeable with it.
    - `projectId` string, required
    - `hostId` string
    - `runId` string
    - `goalId` string
    - `personaId` string
    - `personaLabel` string
    - `status` 'active' | 'archived' | 'null', nullable, required — ARCHIVAL state. A run session stays `active` forever unless archived, so this says nothing about how the run went — read `outcome` for the verdict.
    - `outcome` 'succeeded' | 'failed' | 'rate_limited' | 'running' | 'pending' | 'null', nullable — Attempt execution lifecycle. Read verdict for the graded goal result.
    - `readiness` unknown, required
    - `goalScore` unknown, required
    - `messageCount` integer, required
    - `preview` string — First message only. The transcript is a separate read.
    - `modelId` string
    - `startedAt` number, nullable, required — Epoch milliseconds.
    - `lastActivityAt` number, nullable, required — Epoch milliseconds.
    - `verdict` SwarmSessionVerdict
      - `contractVersion` 1, required
      - `lifecycle` 'pending' | 'running' | 'ran' | 'broke' | 'limited' | 'withdrawn', required
      - `verdict` 'passed' | 'failed' | 'inconclusive' | 'notEstablished', required
      - `reason` 'attemptPending' | 'attemptRunning' | 'withdrawn' | 'spendCapReached' | 'notRun' | 'executionFailed' | 'ungraded' | 'gradingNotClaimed' | 'criteriaPending' | 'judgePending' | 'gatingCriterionFailed' | 'judgeFailed' | 'criteriaGradingErrored' | 'gatingCriterionUnmeasured' | 'judgeErrored' | 'gradingUnavailable' | 'allGatingCriteriaPassed' | 'judgePassed' | 'allGradersPassed', required
      - `verdictSource` 'goalJudge' | 'requiredAssertions' | 'combined' | 'none', required
      - `grading` object, required
        - `state` 'notRequested' | 'queued' | 'running' | 'settled' | 'unavailable', required
        - `reasonCode` string
      - `graders` object, required
        - `criteria` 'notConfigured' | 'notClaimed' | 'pending' | 'scored' | 'errored', required
        - `judge` 'notConfigured' | 'silent' | 'pending' | 'scored' | 'errored', required
      - `counts` object, required
        - `gating` integer, required
        - `gatingPassed` integer, required
        - `gatingFailed` integer, required
        - `gatingUnmeasured` integer, required
        - `advisoryFailed` integer, required
      - `trial` object, nullable, required
        - `status` 'pending' | 'running' | 'completed' | 'failed' | 'setup_failed' | 'cancelled', required
        - `taskVerdict` 'passed' | 'failed'
        - `evaluatorError` true
    - `criteria` object
      - `status` 'pending' | 'completed' | 'failed', required
      - `generation` number, required
      - `criterionIds` string[]
      - `results` object[]
        - `criterionId` string, required
        - `passed` boolean, required
        - `status` 'scored' | 'error'
    - `observations` object[]
      - `evaluatorId` string, required
      - `predicateType` string, required
      - `role` 'required' | 'advisory', required
      - `status` 'passed' | 'failed' | 'pending' | 'unavailable', required
  - `nextCursor` string — Present only when another page exists.

## Other responses

- `401` — Missing, invalid, revoked, or orphaned key (`UNAUTHORIZED`) — or the **target MCP server** needs an OAuth grant (`OAUTH_REQUIRED`), which is a property of the server, not your key.
- `403` — Key is valid but not allowed to do this.
- `404` — Unknown project, server, or resource.
- `429` — Per-key rate limit exceeded (60 requests/minute sustained, bursts up to 10). Honor `Retry-After` and back off with jitter.
- `500` — Something failed on MCPJam's side.

## Changes

- **2026-09-22** `561e4fd0dfa2` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/mcpjam/apis/mcpjam-api/changes/projects/:projectId/goal-runs/:runId/sessions/get.md)

---

[API](https://skmtc.dev/mcpjam/apis/mcpjam-api.md) · [All operations](https://skmtc.dev/mcpjam/apis/mcpjam-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mcpjam/apis/mcpjam-api/revisions/a15a9864fb85?raw)
