Skip to main content

Finn Voice API

Programmatischer Zugriff — Authentifizierung, Endpunkte, Webhooks.

8 min read

Finn Voice API

Der Finn API ist die gleiche Oberfläche, die unser Dashboard verwendet. Erstellen Sie Voice-Agenten, starten Sie Kampagnen, ingest Analytics - alles programmatisch.

Dieser leitfaden bringt sie zu ihrem ersten live-ruf in ca 5 minuten.


Quickstart (3 Schritte)

1. Schnappen Sie sich einen API Schlüssel

Dashboard → Einstellungen → Integrationen → API Schlüssel → Schlüssel erzeugen.

Sie erhalten zwei wichtige Ebenen:

  • fnn_test_* — Sandbox. Keine Carrier-Abrechnung, keine echten Zifferblätter. Verwendung für die Entwicklung.
  • fnn_live_* — Produktion. Echte Anrufe, echtes Geld.

Schlüssel sind org-scoped und erben die Tarifgrenzen Ihres Plans + Quoten.

2. Set Umweltvariablen

export FINN_API_KEY=fnn_test_xxxxxxxxxxxxxxxxxxxx
export FINN_BASE_URL=https://stage-api.hirefinn.ai/v1

Für die Produktion tauschen Sie Folgendes aus:

export FINN_BASE_URL=https://api.hirefinn.ai/v1

3. Machen Sie Ihren ersten Anruf

Listen Sie Ihre Finnen auf:

curl $FINN_BASE_URL/finns \
  -H "Authorization: Bearer $FINN_API_KEY"

Erwartete Antwort:

{
  "data": [
    {
      "id": "fn_abc123",
      "name": "MBBS Callflow",
      "voice_id": "voice_warm_indian_f",
      "language": "en-IN",
      "created_at": "2026-04-12T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 1,
    "has_more": false
  }
}

Geschehen. Du sprichst mit dem API.


Basis-URL

| Umwelt | URL | |------- | Produktion | https://api.hirefinn.ai/v1 | | Bühne | https://stage-api.hirefinn.ai/v1 |

Alle Endpunkte sind unter /v1 versioniert. Breaking ändert sich unter einem neuen Pfadpräfix (/v2, /v3); additive Felder werden in die aktuelle Version aufgenommen.


Authentifizierung

Jede Anfrage benötigt einen API-Schlüssel im Authorization-Header:

Authorization: Bearer fnn_live_xxxxxxxxxxxxxxxxxxxx

Schlüsselverwaltung

  • Generieren in Dashboard → Einstellungen → Integrationen → API Keys.
  • Rotate — gleicher Bildschirm. Alter Schlüssel sofort nach Bestätigung widerrufen.
  • Revoke - sofort. Alle Anfragen während des Fluges, die den widerrufenen Schlüssel verwenden, scheitern mit 401.
  • Scope – Schlüssel sind org-scoped. Verwenden Sie separate Schlüssel pro Umgebung, pro Dienst.

Best Practices

  • Speichern Sie Schlüssel in Umgebungsvariablen oder einem geheimen Manager. Verpflichten Sie sich niemals zur Quelle.
  • Verwenden Sie fnn_test_* für CI und lokale Entwickler. Produktionsanmeldeinformationen sollten niemals einen Entwickler-Laptop sehen.
  • Vierteljährlich rotieren, auch ohne Zwischenfall.
  • Prüfen Sie, welcher Schlüssel welche Ressource über das Feld created_by_key_id auf den meisten Ressourcen erstellt hat.

Codebeispiele

Treten Sie den gleichen Endpunkt in 3 Sprachen.

cURL

curl https://api.hirefinn.ai/v1/finns \
  -H "Authorization: Bearer $FINN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Aria — Dental Reminders",
    "voice_id": "voice_warm_indian_f",
    "language": "en-IN",
    "system_prompt": "You are Aria, a friendly...",
    "welcome_message": "Hi, this is Aria from Smile Dental..."
  }'

Node / TypeScript

import { Finn } from "@finn-voice/sdk";

const finn = new Finn({ apiKey: process.env.FINN_API_KEY });

const agent = await finn.finns.create({
  name: "Aria — Dental Reminders",
  voice_id: "voice_warm_indian_f",
  language: "en-IN",
  system_prompt: "You are Aria, a friendly...",
  welcome_message: "Hi, this is Aria from Smile Dental...",
});

console.log(agent.id);

Python

from finn_voice import Finn

finn = Finn(api_key=os.environ["FINN_API_KEY"])

agent = finn.finns.create(
    name="Aria — Dental Reminders",
    voice_id="voice_warm_indian_f",
    language="en-IN",
    system_prompt="You are Aria, a friendly...",
    welcome_message="Hi, this is Aria from Smile Dental...",
)

print(agent.id)

Antwortformat

Jede erfolgreiche Antwort wickelt die Nutzlast in einen konsistenten Umschlag ein.

Einzelne Ressource

{
  "data": {
    "id": "fn_abc123",
    "name": "MBBS Callflow",
    "created_at": "2026-04-12T10:30:00Z"
  }
}

Liste

{
  "data": [ /* array of resources */ ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 312,
    "has_more": true
  }
}

Zeitstempel

Alle Zeitstempel sind ISO-8601 UTC (2026-05-22T14:30:00Z).

IDs

Ressourcen-IDs werden nach Typ für grep-ability vorangestellt:

| Prefix | Ressourcen | |------- | fn_ | Finn (stimme agent) | | aud_ | Publikum | | dep_ | Einsatz | | cal_ | Aufruf | | ph_ | Telefonnummer | | whk_ | Webhook abo |


Pagination

Listenendpunkte akzeptieren:

?page=2&per_page=100
  • page ist standardmäßig 1.
  • per_page ist standardmäßig auf 50, max.
  • Antwort beinhaltet pagination.has_more - wenn true, Inkrement page und Re-fetch.

Cursor-Paginierung für hochkardinale Endpunkte (Calls, Transkripte):

?cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0yMlQxMjowMDowMFoifQ&per_page=100

Cursor ist undurchsichtig - geben Sie es als ist zurück, um die nächste Seite zu holen.


Filterung und Sortierung

Die meisten Listenendpunkte unterstützen:

?filter[status]=active&filter[call_type]=outbound&sort=-created_at
  • filter[field]=value — genaue Übereinstimmung. Einige Felder akzeptieren Arrays: filter[status]=active,paused.
  • sort=field — aufsteigend. Präfix mit - für absteigend. Komma-getrennter Vielfacher: sort=-created_at,name.

Idempotenz

Senden Sie einen eindeutigen Idempotency-Key-Header zu POST-Anfragen, die Ressourcen erstellen. Finn dedupliziert wiederholte Anfragen innerhalb von 24 Stunden.

curl https://api.hirefinn.ai/v1/deployments \
  -H "Authorization: Bearer $FINN_API_KEY" \
  -H "Idempotency-Key: campaign-may-cohort-3-attempt-1" \
  -d '{ "finn_id": "fn_abc123", ... }'

Wenn Sie mit dem gleichen Schlüssel erneut versuchen, erhalten Sie die zwischengespeicherte Antwort vom ersten Aufruf - keine doppelte Ressource.


Fehler

JSON-Umschlag:

{
  "error": {
    "type": "validation_error",
    "code": "missing_field",
    "message": "phone_number_id is required",
    "field": "phone_number_id",
    "request_id": "req_xy12abc"
  }
}

Fügen Sie request_id in jedes Support-Ticket ein - so verfolgen wir Ihren Anruf durch unsere Protokolle.

Statuscodes

| Status | Bedeutung | Retry? | |---------- | 400 | Validierungsfehler — Nutzlastform falsch | Nein | | 401 | API Schlüssel fehlt / ungültig | Nein | 403 | Scoring to different org / plan tier | No | | 404 | Ressource nicht gefunden | Nein | 409 | Konflikt (Doppelname, Telefon bereits gebunden) | Nein | | 422 | Geschäftsregel ablehnen (Compliance, Quote) | Nein | | 429 | Preis begrenzt | Ja – Respekt Retry-After | | 5xx | Serverseite | Ja – exponentielles Backoff |

Gemeinsame Fehlercodes

| Code | Wann | |------- | missing_field | Erforderliches Feld abwesend von der Nutzlast | | invalid_field | Feld vorhanden, aber Wert ungültig | | not_authenticated | Bearer Token fehlt | | invalid_token | Token widerrufen oder missgebildet | | forbidden_scope | Token hat keinen Zugriff auf diese Ressource | | quota_exceeded | Plan Limit Hit | | rate_limited | Zu viele Anfragen pro Sekunde | | compliance_block | Anfrage abgelehnt durch Compliance-Regeln | | wallet_insufficient | Nicht genug Credits, um den Einsatz zu starten |


Zinsbindungen

| Plan | RPS | Täglich |---------- | Starter | 5 | 5.000 | | Pro | 25 | 50.000 | | Wachstum | 100 | 250.000 | Unternehmen | Verhandelt | Verhandelt |

Das Erreichen des Limits gibt 429 mit Headern zurück:

Retry-After: 12
X-RateLimit-Limit: 25
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1716391823

Respektiere Retry-After (Sekunden) oder gehe exponentiell auf 5xx zurück.


Ressourcen auf einen Blick

| Ressourcen | Endpunkt | Beschreibung | |---------- | Finnen | /v1/finns | Voice Agents | | Publikum | /v1/audiences | Kontaktlisten | | Telefonnummern | /v1/phone-numbers | Eigene + gemietete DIDs | | Deployments | /v1/deployments | Kampagnen + Inbound Bindings | | Anrufe | /v1/calls | Einzelne Anrufaufzeichnungen | | Stimmen | /v1/voices | Verfügbare TTS-Stimmen | | Webhooks | /v1/webhooks | Event-Abonnements | | Wallet | /v1/wallet/{orgId} | Balance + Transaktionen |


Webhooks

Abonnieren Sie Events. POST'd zu Ihrer URL mit HMAC-SHA256 Unterschrift in X-Finn-Signature.

Register

curl https://api.hirefinn.ai/v1/webhooks \
  -H "Authorization: Bearer $FINN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/finn-webhook",
    "events": ["call.completed", "deployment.completed"],
    "secret": "whsec_yourSecretHere"
  }'

Nutzlast des Ereignisses

{
  "id": "evt_2H4abc",
  "type": "call.completed",
  "created_at": "2026-05-22T14:30:00Z",
  "data": {
    "call_id": "cal_xyz789",
    "deployment_id": "dep_xyz789",
    "duration_seconds": 142,
    "outcome": "qualified",
    "recording_url": "https://...",
    "transcript_url": "https://..."
  }
}

Überprüfung der Signatur (Node)

import crypto from "crypto";

function verify(req: Request, secret: string): boolean {
  const sig = req.headers.get("X-Finn-Signature") || "";
  const body = req.body;  // raw bytes!
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

Veranstaltungskatalog

Event | Feuer wenn | |------- | call.started | Carrier nahm den Anruf ab | | call.completed | Anruf beendet (aus irgendeinem Grund) | | call.transferred | Warme Übertragung auf den Menschen | | deployment.started | Kampagne begann zu wählen | | deployment.paused | Manuell angehalten | | deployment.completed | Publikum erschöpft | | wallet.low_balance | Balance fiel unter die konfigurierte Schwelle | | wallet.topup_complete | Erfolgreiches Aufladen abgerechnet | | compliance.action_required | Manuelle Überprüfung erforderlich |

Zuverlässigkeit

  • Retries on 5xx / Timeout: 5 Versuche über ~10 Minuten mit exponentiellem Backoff.
  • Ordnung ist bester Aufwand, nicht garantiert - verwenden Sie Zeitstempel + idempotente Handler.
  • Verwenden Sie das Webhook-Protokoll des Dashboards, um fehlgeschlagene Lieferungen wiederzugeben.

SDKs

Beamter:

  • Node / TypeScriptnpm install @finn-voice/sdk — vollständig typisiert, eingebautes Retry
  • Pythonpip install finn-voice — sync + async clients

Community (nicht unterstützt):

  • Go, Ruby, PHP — Links im Repo README

Alle SDKs wickeln die REST-Oberfläche 1:1 ein, behandeln Retries und Schiffstypen für jede Ressource.


OpenAPI spec

Machine-readable spec lebt bei:

https://api.hirefinn.ai/openapi.json

Verwenden Sie es, um Clients in einer beliebigen Sprache zu generieren, Anfragestellen in CI zu validieren oder in Postman zu importieren:

Postman → File → Import → Link → https://api.hirefinn.ai/openapi.json

Lokale Tests

Für die lokale Webhook-Entwicklung:

# Forward Finn webhooks to your dev machine
ngrok http 3000

# Or use the Finn CLI's built-in tunnel
finn webhooks listen --forward-to http://localhost:3000/webhook

Die CLI stubs auch API Antworten, so dass Sie Integrationstests ohne Live-Key schreiben können.


Versionierung

  • Wegversionierung/v1, /v2. Breaking Changes erhalten ein neues Präfix.
  • **Sunset-Fenster ** - mindestens 12 Monate zwischen Ankündigung und Entfernung der Abwertung.
  • Header Opt-in für Beta-Features:
X-Finn-Beta: enable=workflow-canvas-v2

Abonnieren Sie den Changelog für den Abwertungskalender].


Limits & Quoten

| Limit | Wert | |------- | Max concurrent deployments | Per plan (5 Starter → unlimited Enterprise) | | Max Publikumsgröße | 5M Reihen | | Max System prompt Länge | 32K Zeichen | | Max Webhook URL Länge | 2048 Zeichen | | Webhook Nutzlast max Größe | 1 MB | | Aufzeichnungsaufbewahrung | 90 Tage Standard, konfigurierbar pro Plan | | API key life | Indefinite (manuell drehen) |


Nächste Schritte

  1. **Bauen Sie einen Agenten ** - versuchen Sie es Erstellen eines Finn Walkthrough Ende-zu-Ende über API].
  2. ** Starten Sie eine Kampagne** - verwenden Sie das Deployments doc als Rezept.
  3. Wire your CRM — siehe Integrationen für Webhook-Muster].
  4. Tune für Kosten - lesen Sie Wallet & AI Credits, um das Pulsabrechnungsmodell zu verstehen.

Stuck? [email protected] - schließen Sie den request_id aus der Fehlerantwort ein, wenn Sie einen haben.

Was this page helpful?

Still stuck or have feedback?

Email [email protected] or use the chat bubble in the bottom-right corner — it's a Finn that knows the Academy cold.