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
| Field | Type | Notes |
|---|---|---|
id | string | Server-generated. Treat as opaque. |
name | string | Required on create. Not guaranteed unique. |
prompt | string | The system prompt driving the conversation. See agents-prompting. |
welcome_message | string | First line spoken on pickup. Omit for outbound if you want the Finn to wait for the callee. |
voice_id | string | From the voice catalogue. See api-voices. |
language | string | Primary language code. Multilingual behaviour is configured separately, see agents-multilingual. |
status | string | draft or live. |
tools | array | Tool references attached to this Finn. See tools-overview. |
variables | object | Declared dynamic variables. See agents-variables. |
created_at | string | ISO 8601 timestamp. |
updated_at | string | ISO 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"
| Parameter | Type | Notes |
|---|---|---|
limit | integer | Page size. |
cursor | string | Opaque cursor from the previous page. |
status | string | Filter 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
| Status | Meaning | What to do |
|---|---|---|
400 | Malformed body or unknown field. | Check the field names against the table above. |
401 | Missing or invalid key. | Check the Authorization header. |
404 | No Finn with that ID in this workspace. | Keys are workspace-scoped. A valid ID from another workspace reads as 404. |
409 | Delete blocked by an attached deployment. | Detach the deployment, then delete. |
422 | Body parsed but a value was rejected, for example an unknown voice_id. | Confirm the voice exists in api-voices. |
429 | Rate 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.