Finn Voice API
Accesso programmatico — autenticazione, endpoint, webhook.
Finn Voice API
Il Finn API è la stessa superficie utilizzata dalla nostra dashboard. Costruire agenti vocali, campagne di lancio, analisi ingest — tutti programmaticamente.
Questa guida ti porta al tuo primo live API chiamata in ~5 minuti.
Quickstart (3 passi)
1. Afferra una chiave API
Dashboard → Impostazioni → Integrazioni → API Keys → Genera chiave.
Avrai due livelli chiave:
fnn_test_*— sandbox. Niente bollette, niente veri quadranti. Uso per lo sviluppo.fnn_live_*— produzione. Chiamate vere, soldi veri.
Le chiavi sono org-scoped e ereditano i limiti di tasso del vostro piano + quote.
2. Impostare variabili di ambiente
export FINN_API_KEY=fnn_test_xxxxxxxxxxxxxxxxxxxx
export FINN_BASE_URL=https://stage-api.hirefinn.ai/v1
Per la produzione, scambiare a:
export FINN_BASE_URL=https://api.hirefinn.ai/v1
3. Fai la tua prima chiamata
Elenca le tue pinne:
curl $FINN_BASE_URL/finns \
-H "Authorization: Bearer $FINN_API_KEY"
Risposta prevista:
{
"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
}
}
Fatto. Stai parlando con il API.
URL della base
| Ambiente | URL |
Traduzione:
| Produzione | https://api.hirefinn.ai/v1 |
| Fase | https://stage-api.hirefinn.ai/v1 |
Tutti gli endpoint sono versioneti sotto /v1. I cambiamenti di interruzione nave sotto un nuovo prefisso di percorso (/v2, /v3); i campi additivi rotolano nella versione corrente.
Autenticazione
Ogni richiesta ha bisogno di una chiave API nell'intestazione Authorization:
Authorization: Bearer fnn_live_xxxxxxxxxxxxxxxxxxxx
Gestione chiave
- Generate in Dashboard → Impostazioni → Integrazioni → API Chiavi.
- Rotate — stesso schermo. Vecchia chiave revocata immediatamente alla conferma.
-
- Subito. Tutte le richieste in volo utilizzando la chiave revocata falliscono con
401.
- Subito. Tutte le richieste in volo utilizzando la chiave revocata falliscono con
- Scope — le chiavi sono org-scoped. Utilizzare chiavi separate per ambiente, per servizio.
Migliori pratiche
- Conservare le chiavi in variabili di ambiente o un manager segreto. Mai impegnarsi alla fonte.
- Utilizzare
fnn_test_*per CI e lo sviluppo locale. Le credenziali di produzione non dovrebbero mai vedere un computer portatile sviluppatore. - Ruotare trimestralmente anche senza un incidente.
- Verifica quale chiave ha creato quale risorsa attraverso il campo
created_by_key_idsulla maggior parte delle risorse.
Esempi di codice
Colpire lo stesso punto finale in 3 lingue.
uRL
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..."
}'
Nodo / 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)
Formato di risposta
Ogni risposta di successo avvolge payload in una busta coerente.
Risorse singole
{
"data": {
"id": "fn_abc123",
"name": "MBBS Callflow",
"created_at": "2026-04-12T10:30:00Z"
}
}
Elenco
{
"data": [ /* array of resources */ ],
"pagination": {
"page": 1,
"per_page": 50,
"total": 312,
"has_more": true
}
}
Lampade
Tutti i timestamp sono ISO-8601 UTC (2026-05-22T14:30:00Z).
ID
Gli ID delle risorse sono prefissati per tipo per grep-ability:
| Prefix | Risorse |
Traduzione:
| fn_ | Finn (voce agente) |
| aud_ | Audience |
| dep_ | Distribuzione |
| cal_ | Chiamata |
| ph_ | Numero di telefono |
| whk_ | Webhook abbonamento |
Pagina
Elenco endpoint accetta:
?page=2&per_page=100
pagepredefinito a 1.per_pagepredefinito a 50, max 200.- La risposta include
pagination.has_more— quandotrue, incrementopagee re-fetch.
Cursor impaginazione per endpoint ad alta definizione (call, trascrizioni):
?cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0yMlQxMjowMDowMFoifQ&per_page=100
Cursor è opaco — passalo come-è per prendere la pagina successiva.
Filtro e smistamento
La maggior parte dei punti finali della lista supporta:
?filter[status]=active&filter[call_type]=outbound&sort=-created_at
filter[field]=value— partita esatta. Alcuni campi accettano array:filter[status]=active,paused.sort=field— Ascendente. Prefisso con-per la discesa. Comma-separate multiple:sort=-created_at,name.
Idempot
Invia un'intestazione Idempotency-Key unica su richieste POST che creano risorse. Finn deduplica le richieste ritenute entro 24 ore.
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", ... }'
Se si tenta con la stessa chiave, si ottiene la risposta cache dalla prima chiamata — nessuna risorsa duplicata creata.
Errori
JSON busta:
{
"error": {
"type": "validation_error",
"code": "missing_field",
"message": "phone_number_id is required",
"field": "phone_number_id",
"request_id": "req_xy12abc"
}
}
Includere request_id in qualsiasi biglietto di supporto — è come rintracciamo la vostra chiamata attraverso i nostri registri.
Codici di stato
| Stato | Significato | Retry
Traduzione:
| 400 | Errore di convalida — forma di payload sbagliata | No |
| 401 | API key mancante / invalido | No |
| 403 | Punteggio diverso org / piano tier | No |
| 404 | Risorsa non trovata | No |
| 409 | Conflict (nome duplicato, telefono già legato) | No |
| 422 | Rifiuto di business-rule (compliance, quota) | No |
| 429 | Tasso limitato | Sì — rispetto Retry-After |
| 5xx | lato server | Sì — backoff esponenziale |
Codici di errore comuni
| Codice | Quando |
Traduzione:
| missing_field | Campo obbligatorio assente dal payload |
| invalid_field | Campo presente ma valore non valido |
| not_authenticated | Token Bearer mancante |
| invalid_token | Token revocato o malformato |
| forbidden_scope | Token non ha accesso a questa risorsa |
| quota_exceeded | Limite del piano
| rate_limited | Troppe richieste al secondo
| compliance_block | Richiesta respinta dalle regole di conformità |
| wallet_insufficient | Non bastano i crediti per lanciare la distribuzione |
Limiti di tasso
| Piano | RPS | Quotidiano | Traduzione: | Starter | 5 | 5.000 | | Pro | 25 | 50,000 | | Crescita | 100 | 250.000 | | Enterprise | Negotiated | Negotiated |
Colpire il limite restituisce 429 con intestazioni:
Retry-After: 12
X-RateLimit-Limit: 25
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1716391823
Rispetto Retry-After (secondi) o di nuovo fuori esponenzialmente su 5xx.
Risorse a colpo d'occhio
| Resource | Endpoint | Descrizione |
Traduzione:
| Finns | /v1/finns | Agenti vocali |
| Audiences | /v1/audiences | Elenchi di contatto |
| Numeri telefonici | /v1/phone-numbers | Owned + affittato DIDs |
| Deployments | /v1/deployments | Campagne + binding in entrata |
| Chiamate | /v1/calls | Registrazioni individuali |
| Voci | /v1/voices | Voci TTS disponibili |
| Webhooks | /v1/webhooks | Abbonamenti per eventi |
| Wallet | /v1/wallet/{orgId} | Balance + transazioni |
Webhooks
Iscriviti agli eventi. POST'd al tuo URL con HMAC-SHA256 firma in X-Finn-Signature.
Registrazione
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"
}'
Caricamento in corso
{
"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://..."
}
}
Firma di verifica (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));
}
Catalogo eventi
| Event | Fires when |
Traduzione:
| call.started | Carrier ha ritirato la chiamata |
| call.completed | Chiamata terminata (qualsiasi ragione) |
| call.transferred | Trasferimento caldo all'uomo
| deployment.started | La campagna ha iniziato a comporre |
| deployment.paused | Interruzione manuale |
| deployment.completed | Audience esaurito |
| wallet.low_balance | L'equilibrio è sceso sotto la soglia configurata |
| wallet.topup_complete | Ricarica sicura
| compliance.action_required | Analisi manuale necessaria |
Affidabilità
- Retries su
5xx/ timeout: 5 tentativi su ~10 minuti con backoff esponenziale. - L'ordine è migliore, non garantito — utilizzare i timestamp + idempotent handlers.
- Utilizzare il registro webhook del cruscotto per riprodurre le consegne fallite.
SDKs
Ufficiale:
- Node / TypeScript —
npm install @finn-voice/sdk— completamente digitato, riprova incorporata - Python —
pip install finn-voice— Sincronizzare i clienti
Comunità (non supportata):
- **Vai, Ruby, ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
Tutti gli SDKs avvolgono la superficie REST 1:1, maneggiano i retries e i tipi di nave per ogni risorsa.
OpenAPI spec
Spec leggibile in macchina vive a:
https://api.hirefinn.ai/openapi.json
Utilizzare per generare clienti in qualsiasi lingua, convalidare i corpi di richiesta in CI, o importare in Postman:
Postman → File → Import → Link → https://api.hirefinn.ai/openapi.json
Testare localmente
Per lo sviluppo webhook locale:
# 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
Il CLI inoltre testa le risposte API in modo da poter scrivere test di integrazione senza chiave live.
Versione
- La versione del testo —
/v1,/v2. I cambiamenti di rottura ottengono un nuovo prefisso. - Sunset window — almeno 12 mesi tra annuncio di deprecazione e rimozione.
- Header opt-in per le caratteristiche beta:
X-Finn-Beta: enable=workflow-canvas-v2
Iscriviti al Changelog per il calendario di deprecazione.
Limiti e quote
| Limit | Valore | Traduzione: | Max concomitanze | Per plan (5 Starter → unlimited Enterprise) | | Dimensione massima del pubblico | 5M righe | | Lunghezza massima del prompt del sistema | caratteri 32K | | Lunghezza URL Max webhook | 2048 caratteri | | Webhook payload max size | 1 MB | | Ritenzione di registrazione | 90 giorni di default, configurabile per piano | | API key life | Indefinite (rotate manualmente) |
Prossimo passo
- Costruire un agente — provare il Creare un Finn walkthrough end-to-end via API.
- Lanciare una campagna — utilizzare il Deployments doc come ricetta.
- Wire your CRM — see Integrations for webhook pattern.
- Tune per il costo — leggere Wallet & AI Credits per capire il modello di impulso-billing.
Stuck? [email protected] — includere il request_id dalla risposta di errore se ne avete uno.
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.