Skip to main content

API reference

Cases

Finn Operator cases: read them and start one.

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

MethodPathScopeRate limit (per API key)
GET/casescases:read300 per minute, shared by all reads in Records, Cases and Approvals
GET/cases/{id}cases:readRead bucket
GET/cases/{id}/eventscases:readRead bucket
POST/agents/{id}/casescases:write60 per minute

List cases

curl "https://api.hirefinn.ai/api/v1/cases?status=open&limit=50" \
  -H "Authorization: Bearer $FINN_API_KEY"
QueryNotes
statusopen (open, running or waiting), or one of running, waiting, resolved, ended, failed, cancelled.
agent_idOne agent's cases.
contact_idCases about one record.
owner_idOne owner's cases; none for unowned.
outcome_keyOne outcome.
qSearch title and subject.
limit1 to 200. Default 50.
beforenext_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:

FieldNotes
subject, memoryWhat the case is about, and what it has stored.
outcome_reason, error_code, error_messageWhy it ended or failed.
currency, event_seq, next_wake_at, test
participants{ id, contact_id?, role, name?, phone?, email? }.
threads, steps, open_waits, resolutionsThe 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.

FieldTypeRequiredNotes
subjectobjectNo{ type, ref, data? }. One open case per subject.
startstringWhen severalThe Start to begin at. Required if the agent has more than one.
titlestringNo
participantsarrayNo{ role, contact_id?, name?, phone?, email? }. role is required; phone is E.164.
memoryobjectNoStarting memory. Must fit the agent's memory schema.
dataobjectNoRead in the flow as trigger.data.
owner_idstringNoUsed 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 }
resultStatusMeaning
opened201A new case.
matched200A case for this subject was already open; the start went into it.
reopened200A 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.

StatusCodeWhen
400invalid_idA path ID isn't a UUID.
400invalidMalformed body or query value.
403insufficient_scopeThe key lacks the scope.
404not_foundNo such case or agent in your organization.
409conflictThe agent has no published version, isn't live, or has no API Start.
422invalidA field breaks a rule: start missing, a participant without role, memory that doesn't fit.
429rate_limitedOver 60 starts a minute on this key. Wait Retry-After seconds.
429cap_reachedA daily case cap. details has used, limit and resets_at.
502, 503operator_unavailableFinn Operator is down or not set up here. Safe to retry reads; for a start, retry with the same Idempotency-Key.