Beta. Every endpoint on this page is live and documented as shipped. Shapes can still change before general availability.
Overview
A case is one run of a Finn Operator agent on one subject: a renewal for one client, an onboarding for one record. The Cases API lists and reads cases, reads a case's event log, and starts a case on an agent.
Base URL: https://api.hirefinn.ai/api/v1. Auth: Authorization: Bearer finn_live_.... See authentication and scopes.
Finn passes these requests on to Finn Operator, which runs cases, and returns its answer. Responses are the object itself, with no { "success": true, "data": ... } envelope.
Endpoints
| Method | Path | Scope | Rate limit (per API key) |
|---|---|---|---|
GET | /cases | cases:read | 300 per minute, shared by all reads in Records, Cases and Approvals |
GET | /cases/{id} | cases:read | Read bucket |
GET | /cases/{id}/events | cases:read | Read bucket |
POST | /agents/{id}/cases | cases:write | 60 per minute |
List cases
curl "https://api.hirefinn.ai/api/v1/cases?status=open&limit=50" \
-H "Authorization: Bearer $FINN_API_KEY"
| Query | Notes |
|---|---|
status | open (open, running or waiting), or one of running, waiting, resolved, ended, failed, cancelled. |
agent_id | One agent's cases. |
contact_id | Cases about one record. |
owner_id | One owner's cases; none for unowned. |
outcome_key | One outcome. |
q | Search title and subject. |
limit | 1 to 200. Default 50. |
before | next_before of the previous page. |
{
"cases": [
{
"id": "3c9b1f7e-2a4d-4e6b-8c1d-5f7a9b0c2d3e",
"agent_id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"agent_name": "Renewals",
"version_no": 4,
"status": "waiting",
"title": "Renewal follow-up",
"subject_type": "contact",
"subject_ref": "6f1c2a0e-8d1b-4b7a-9f3e-2c4d5e6f7a8b",
"stage": null,
"owner_id": null,
"outcome_key": null,
"cost_minor": 0,
"participants": [{ "role": "customer", "name": "Ravi Rao" }],
"waiting": { "node_id": "approve_quote", "kind": "action", "event_kinds": ["approval.decided"], "since": "2026-11-03T09:00:00.000Z", "timeout_at": null },
"opened_at": "2026-11-03T08:58:12.000Z",
"closed_at": null
}
],
"next_before": "2026-11-03T08:58:12.000Z"
}
Newest first. Pass next_before as before for the next page. It is null when the page is empty. Test cases are not listed.
Retrieve a case
curl https://api.hirefinn.ai/api/v1/cases/3c9b1f7e-2a4d-4e6b-8c1d-5f7a9b0c2d3e \
-H "Authorization: Bearer $FINN_API_KEY"
The case's fields above (without agent_name, participants summary and waiting), plus:
| Field | Notes |
|---|---|
subject, memory | What the case is about, and what it has stored. |
outcome_reason, error_code, error_message | Why it ended or failed. |
currency, event_seq, next_wake_at, test | |
participants | { id, contact_id?, role, name?, phone?, email? }. |
threads, steps, open_waits, resolutions | The run in detail. |
List a case's events
curl https://api.hirefinn.ai/api/v1/cases/3c9b1f7e-2a4d-4e6b-8c1d-5f7a9b0c2d3e/events \
-H "Authorization: Bearer $FINN_API_KEY"
{ "events": [ { "seq": 1, "type": "case.opened", "actor_type": "user", "actor_id": "8e4d2c1b-6a5f-4e3d-9c2b-1a0f9e8d7c6b", "data": {}, "at": "2026-11-03T08:58:12.000Z" } ], "next_after": 1 }
Oldest first. actor_type is system, ai, user or participant; a case started by an API key shows user with the key's ID.
This endpoint returns the first 200 events. It takes no query parameters yet, so a longer log can't be paged here; read the rest in Finn.
Start a case
curl -X POST https://api.hirefinn.ai/api/v1/agents/1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e/cases \
-H "Authorization: Bearer $FINN_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: renewal-6f1c2a0e-2026-11" \
-d '{
"subject": { "type": "contact", "ref": "6f1c2a0e-8d1b-4b7a-9f3e-2c4d5e6f7a8b" },
"title": "Renewal follow-up",
"participants": [{ "role": "customer", "contact_id": "6f1c2a0e-8d1b-4b7a-9f3e-2c4d5e6f7a8b" }],
"data": { "policy_no": "P-20419" }
}'
The agent must be published and live, with an API Start.
| Field | Type | Required | Notes |
|---|---|---|---|
subject | object | No | { type, ref, data? }. One open case per subject. |
start | string | When several | The Start to begin at. Required if the agent has more than one. |
title | string | No | |
participants | array | No | { role, contact_id?, name?, phone?, email? }. role is required; phone is E.164. |
memory | object | No | Starting memory. Must fit the agent's memory schema. |
data | object | No | Read in the flow as trigger.data. |
owner_id | string | No | Used when the Start takes its owner from the trigger. |
Other fields are dropped.
{ "case_id": "3c9b1f7e-2a4d-4e6b-8c1d-5f7a9b0c2d3e", "trigger_event_id": "9a1e5c3b-7d2f-4b8a-a6e4-1c3f5d7b9e20", "result": "opened", "replayed": false }
result | Status | Meaning |
|---|---|---|
opened | 201 | A new case. |
matched | 200 | A case for this subject was already open; the start went into it. |
reopened | 200 | A recently closed case for this subject was reopened. |
Retries. Send an Idempotency-Key header (up to 200 characters). A repeat with the same key returns the first answer with replayed: true and status 200. Without the header every request is a new start, although subject still keeps it to one open case per subject.
Finn sends case.created and case.completed webhooks; see webhook-events.
Errors
Errors raised by Finn before the request reaches Finn Operator use { "error", "message" }. Errors from Finn Operator use { "code", "message", "details" }. Read error ?? code.
| Status | Code | When |
|---|---|---|
| 400 | invalid_id | A path ID isn't a UUID. |
| 400 | invalid | Malformed body or query value. |
| 403 | insufficient_scope | The key lacks the scope. |
| 404 | not_found | No such case or agent in your organization. |
| 409 | conflict | The agent has no published version, isn't live, or has no API Start. |
| 422 | invalid | A field breaks a rule: start missing, a participant without role, memory that doesn't fit. |
| 429 | rate_limited | Over 60 starts a minute on this key. Wait Retry-After seconds. |
| 429 | cap_reached | A daily case cap. details has used, limit and resets_at. |
| 502, 503 | operator_unavailable | Finn Operator is down or not set up here. Safe to retry reads; for a start, retry with the same Idempotency-Key. |