Skip to main content
Most endpoints accept both reviewer and candidate (API key) authentication unless noted otherwise. See Authentication.

Create a session

POST /v1/sessions Manually creates a session. In normal use, sessions are created automatically the first time an event is ingested via POST /v1/hooks/ingest. Use this endpoint only when you need to pre-register a session ID or attach metadata before events arrive. Request body
id
string (UUID)
Optional session ID. If omitted, a UUID is generated. Providing an existing ID is safe — the request returns 409 rather than overwriting the existing session.
sourceService
string
Tool or integration identifier (e.g. claude-code, cursor).
metadata
object
Arbitrary key-value metadata to attach to the session.
Responses
  • 201 — Session created. Returns { session: SessionObject }.
  • 400 — Invalid request body.
  • 409 — A session with this ID already exists. Returns { error: "Session already exists", id: "..." }.

List sessions

GET /v1/sessions Returns a paginated list of sessions for your organization, sorted by startedAt descending (most recent first). Query parameters
assessmentId
string
Filter to sessions linked to a specific assessment via candidate keys.
sourceService
string
Filter by tool or integration identifier.
limit
integer
default:"20"
Maximum results to return. Clamped to 1–100. Defaults to 20.
offset
integer
default:"0"
Results to skip for pagination. Defaults to 0.
Response
{
  "sessions": [...],
  "total": 84,
  "limit": 20,
  "offset": 0
}

Get a session

GET /v1/sessions/:id Returns a single session record. Response fields
id
string
Session UUID.
orgId
string
Organization this session belongs to.
sourceService
string
AI tool or integration that generated this session (e.g. claude-code, cursor, shell).
startedAt
datetime
Timestamp of the first event in the session.
endedAt
datetime
Timestamp when the session was closed. null if still in progress.
lastActivityAt
datetime
Timestamp of the most recently ingested event.
eventCount
integer
Total number of timeline events captured.
decisionFlagCount
integer
Number of architecture decision events captured.
aiAttributionPct
number
Estimated percentage of work attributed to AI, between 0 and 100. null if not yet computed.
metadata
object
Arbitrary metadata. Well-known keys include assessmentId, candidateName, and repoUrl, which are automatically populated from session start events.
Responses
  • 200 — Returns { session: SessionObject }.
  • 404 — Session not found or does not belong to your org.

Update a session

PATCH /v1/sessions/:id Updates endedAt and/or metadata on an existing session. Replaces (does not merge) the metadata object when provided. To merge metadata instead, use PATCH /v1/sessions/:id/metadata. Request body
endedAt
string (ISO-8601 datetime)
Mark the session as ended at this timestamp.
metadata
object
Replace the session’s metadata with this object.
Responses
  • 200 — Returns { session: SessionObject }.
  • 400 — Invalid body.
  • 404 — Session not found.

Delete a session

DELETE /v1/sessions/:id Hard-deletes the session and all associated data: timeline events, raw events, session artifacts, and scores. The candidate key that linked to this session has its sessionId cleared but is not deleted.
This operation is irreversible. All session data is permanently removed.
Requires reviewer authentication. Responses
  • 200 — Returns { ok: true, id: "<session-id>" }.
  • 404 — Session not found.

Get the event timeline

GET /v1/sessions/:id/timeline Returns the ordered list of timeline events for a session, sorted by ts ascending then by insertion order for events with the same timestamp. Query parameters
limit
integer
default:"500"
Maximum events to return. Clamped to 1–2000. Defaults to 500.
after
string
Cursor for pagination. Pass the id of the last event you received to fetch the next page.
Response
{
  "events": [
    {
      "id": "...",
      "kind": "command",
      "ts": "2026-04-01T10:15:00.000Z",
      "data": {
        "command": "pnpm test",
        "exitCode": 0,
        "durationMs": 4200
      }
    }
  ],
  "hasMore": true
}
To page through a large timeline, pass the id of the final event in each response as the after cursor in the next request.

Get decisions

GET /v1/sessions/:id/decisions Returns all decision_event timeline entries for a session, ordered by ts ascending. These are architecture and tradeoff decisions captured by the Promptster MCP server or CLI during the candidate’s session. Response
{
  "decisions": [
    {
      "id": "...",
      "kind": "decision_event",
      "ts": "2026-04-01T11:02:00.000Z",
      "data": {
        "title": "Use JSONB for event payloads over a typed columns approach",
        "chosenOption": "JSONB payload column",
        "context": "Need flexible schema for heterogeneous event payloads",
        "tradeoffs": "Harder to query individual fields without GIN indexes",
        "rationale": "Avoids migrations as schema changes; acceptable read performance for our access patterns",
        "impactScore": 4
      }
    }
  ]
}
  • 200 — Returns { decisions: [...] }. Returns an empty array if no decisions were captured.
  • 404 — Session not found.

Get cohort statistics

GET /v1/sessions/:id/cohort-stats Returns aggregate metrics for the assessment this session belongs to, along with percentile ranks for this session relative to the cohort. The cohort includes all sessions with candidate key status completed, expired, or hired. Percentiles are only computed when the cohort has at least two sessions. Returns { cohortStats: null } if the session is not linked to an assessment or the cohort has no completed sessions. Response
{
  "cohortStats": {
    "sessionCount": 12,
    "metrics": {
      "avgDurationMs": 4320000,
      "avgPromptCount": 38.5,
      "avgCommandFailRate": 0.142,
      "avgVerifyIntensity": 0.61,
      "avgManualEditRatio": 0.33,
      "avgFirstChangeLatencyMs": 180000,
      "testPassRate": 75
    },
    "percentiles": {
      "durationMs": 0.727,
      "promptCount": 0.455,
      "commandFailRate": 0.818,
      "verifyIntensity": 0.636,
      "manualEditRatio": 0.727,
      "firstChangeLatencyMs": 0.364
    }
  }
}
Percentile values are between 0.0 and 1.0. Higher values indicate better relative performance. For commandFailRate, a lower raw value means better performance — the percentile is ranked accordingly.