Skip to main content

API reference

Finns

Create, read, update and delete voice agents.

Beta. This endpoint is not final. Field names and response shapes can change before general availability.

Overview

A Finn is a voice agent: a prompt, a voice, a language configuration, and a set of tools. The Finns API lets you create and manage those agents programmatically instead of through the dashboard.

Creating a Finn does not put it on a phone line. A Finn only takes or places calls once it is attached to a deployment. See deployments and agents-overview.

Base URL: https://api.hirefinn.ai/v1 Auth: Authorization: Bearer <FINN_API_KEY>. See authentication.

The Finn object

FieldTypeNotes
idstringServer-generated. Treat as opaque.
namestringRequired on create. Not guaranteed unique.
promptstringThe system prompt driving the conversation. See agents-prompting.
welcome_messagestringFirst line spoken on pickup. Omit for outbound if you want the Finn to wait for the callee.
voice_idstringFrom the voice catalogue. See api-voices.
languagestringPrimary language code. Multilingual behaviour is configured separately, see agents-multilingual.
statusstringdraft or live.
toolsarrayTool references attached to this Finn. See tools-overview.
variablesobjectDeclared dynamic variables. See agents-variables.
created_atstringISO 8601 timestamp.
updated_atstringISO 8601 timestamp.

Whether knowledge base attachments are expressed inline on the Finn object or as a separate association is not yet settled. Do not build against a knowledge_base_id field until it appears in changelog.

Create a Finn

curl -X POST https://api.hirefinn.ai/v1/finns \
  -H "Authorization: Bearer $FINN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-support-finn-001" \
  -d '{
    "name": "Support triage",
    "prompt": "You are a support agent for Acme. Identify the caller issue, then route or resolve it. Keep turns under two sentences.",
    "welcome_message": "Hi, this is Acme support. What can I help you with?",
    "voice_id": "voice_en_us_01",
    "language": "en-US"
  }'

Response 201 Created:

{
  "id": "finn_9f3c2a",
  "name": "Support triage",
  "prompt": "You are a support agent for Acme...",
  "welcome_message": "Hi, this is Acme support. What can I help you with?",
  "voice_id": "voice_en_us_01",
  "language": "en-US",
  "status": "draft",
  "tools": [],
  "variables": {},
  "created_at": "2026-07-30T09:14:22Z",
  "updated_at": "2026-07-30T09:14:22Z"
}

name and prompt are required. A create without voice_id falls back to a workspace default. Do not rely on that default staying the same across workspaces.

Retries without an Idempotency-Key create duplicate Finns. See api-idempotency.

Retrieve a Finn

curl https://api.hirefinn.ai/v1/finns/finn_9f3c2a \
  -H "Authorization: Bearer $FINN_API_KEY"

List Finns

curl "https://api.hirefinn.ai/v1/finns?limit=25&status=live" \
  -H "Authorization: Bearer $FINN_API_KEY"
ParameterTypeNotes
limitintegerPage size.
cursorstringOpaque cursor from the previous page.
statusstringFilter to draft or live.

Pagination is cursor-based. Do not construct cursors yourself. See api-pagination.

Update a Finn

PATCH applies a partial update. Fields you omit are left alone.

const res = await fetch(
  "https://api.hirefinn.ai/v1/finns/finn_9f3c2a",
  {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${process.env.FINN_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      prompt: "You are a support agent for Acme. Always confirm the account email before discussing billing.",
    }),
  },
);

if (!res.ok) {
  throw new Error(`Update failed: ${res.status} ${await res.text()}`);
}

const finn = await res.json();
console.log(finn.updated_at);

Editing a Finn that is attached to a live deployment changes the behaviour of calls that start after the write. Calls already in progress keep the configuration they started with. There is no versioning or rollback in this API. Keep your own copy of a prompt before overwriting it.

Delete a Finn

import os
import requests

resp = requests.delete(
    "https://api.hirefinn.ai/v1/finns/finn_9f3c2a",
    headers={"Authorization": f"Bearer {os.environ['FINN_API_KEY']}"},
    timeout=30,
)

if resp.status_code == 409:
    print("Finn is attached to a deployment. Detach it first.")
else:
    resp.raise_for_status()
    print("Deleted")

Deleting a Finn does not delete its call history. Past calls and transcripts stay available through api-calls and call-logs, subject to your retention settings.

Errors

StatusMeaningWhat to do
400Malformed body or unknown field.Check the field names against the table above.
401Missing or invalid key.Check the Authorization header.
404No Finn with that ID in this workspace.Keys are workspace-scoped. A valid ID from another workspace reads as 404.
409Delete blocked by an attached deployment.Detach the deployment, then delete.
422Body parsed but a value was rejected, for example an unknown voice_id.Confirm the voice exists in api-voices.
429Rate limited.Back off. See api-rate-limits.

Error bodies follow the shape in api-errors. Shared conventions for headers, timestamps and IDs are in api-conventions.