Skip to main content

Voice Biometrics API

Voice-print enrollment and speaker verification Base path: /api/v1/verify/voice-biometrics Endpoint count: 8

title: “Errors worth branching on” description: “Per-endpoint failure templates matching the envelope — what actually fires, what to retry, what to surface to the operator.”

Errors worth branching on

These five failures cover the verify call (POST /api/v1/voice-biometrics/verify), hammered per IVR turn. Each block below is a full { error, meta } envelope as the API returns it, and the matrix at the bottom answers retry vs surface for the same five classes. For the platform-wide decision table these branches plug into, see the error handling guide.

401 — Unauthorized

A 401 on this page is the bearer key failing before the route ran — it never means the resource is wrong. Rotate the key or re-mint the scoped token; retrying the same request changes nothing.

403 — Forbidden

A 403 means the key authenticated but the operation is gated by scope — check the key’s scopes on the developer page; a 403 is never a data-not-found shape.

422 — Schema

A 422 means the payload did not match the request schema — branch on error.details.field and enrol the customer first, then re-fire verify with a long enough sample instead of blind-retrying the same body.

429 — Rate

The Retry-After header and error.details.retry_after are both set on every 429 — resend the SAME request after the lower of the two.

404 — Not found

Surface enrolment — retrying a verify call cannot pass until enrolment completes.

60-second retry matrix


List enrolled voiceprints

GET /api/v1/verify/voice-biometrics
Cursor-paginated list of voiceprints for this tenant. Returns metadata only — no embedding bytes.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get voiceprint enrollment status

GET /api/v1/verify/voice-biometrics/enroll/{id}
Returns the enrollment status of a single voiceprint by id (the id returned by POST /enroll): { id, status, voiceprint_id, confidence? }. Enrollment is synchronous, so a known id reports enrolled; an unknown or GDPR-erased id returns 404.
string
required
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Voice biometrics overview

GET /api/v1/verify/voice-biometrics/overview
Returns enrolled voiceprint count, recent verification events, 7-day false-accept rate trend, and tenant threshold settings.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Issue a verification challenge nonce

POST /api/v1/verify/voice-biometrics/challenge
Issues a per-attempt liveness/replay-resist challenge phrase. The caller reads the returned phrase aloud, records the audio, and submits both the audio AND the nonceId+phrase on the next POST /verify. The verify path one-shot-consumes the nonce and rejects on missing/expired/reused/mismatched values, defeating recorded-voice replay attacks. 5-minute TTL.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
Id of the contact to challenge (1–255 characters). The returned nonce + phrase must echo back on the next POST /verify.

Enroll a voiceprint

POST /api/v1/verify/voice-biometrics/enroll
Upload a WAV audio clip (base64) to enroll a new voiceprint for a contactId. Requires explicit GDPR Art. 9 consent. Rejected if anti-spoof score is below threshold. Returns 429 voiceprint_tenant_cap_exceeded if the tenant has reached its voice_biometrics.tenant_enroll_cap quota.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
Id of the contact the voiceprint belongs to (1–255 characters).
string
required
Base64-encoded WAV clip (max 30s / 2MB) used to build the embedding. Rejected below the anti-spoof floor.
Verbatim GDPR Art. 9 consent text the speaker agreed to (10–5000 characters). Stored for the audit trail.
Version tag of the consent copy (e.g. gdpr-art9-v1), so revoking a version can target the right enrollments.

Verify a caller by voice

POST /api/v1/verify/voice-biometrics/verify
Upload a WAV audio clip (base64) to verify a contactId against their enrolled voiceprints. Both cosine similarity AND anti-spoof gates must pass.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
Id of the contact to verify against their enrolled voiceprints (1–255 characters).
string
required
Base64-encoded WAV probe clip (max 30s / 2MB). Both the cosine-similarity gate AND the anti-spoof gate must pass for a match.
string
The nonceId returned by POST /challenge. One-shot-consumed on verify; reuse/expiry/mismatch is rejected. Omit both challenge fields to skip liveness.
string
The exact phrase the caller read aloud — must match the phrase issued with the nonce.

Update voice biometrics tenant settings

PATCH /api/v1/verify/voice-biometrics/settings
Persist the per-tenant confidence threshold (0.50 permissive → 0.95 strict — governs the cosine-similarity gate on POST /verify) and the auto-escalate-to-2FA-on-low-confidence intent flag. Both values round-trip via GET /overview.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
number
required
Cosine-similarity gate a verification must clear, between 0.50 (permissive) and 0.95 (strict). Values outside the range are rejected.
boolean
required
When true, a below-threshold verification signals downstream step-up flows to escalate to a second factor instead of a hard fail.

Delete a voiceprint (GDPR erasure)

DELETE /api/v1/verify/voice-biometrics/{voiceprintId}
Permanently deletes a voiceprint and its encrypted embedding. GDPR Article 17 right-to-erasure. Real DELETE (not soft-delete). Idempotent.
string
required
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.