Integrate voice identity protection into your platform with our REST API. Base URL: https://api.voiceseal.io — every path below already includes the /api/v1 prefix (e.g. POST /api/v1/protect/pre-synthesis-check). Do not add /api/v1 twice.
Endpoints require authentication — a JWT Bearer token (from login) or an X-API-Key for platform integrations. The production pre-synthesis check (POST /api/v1/protect/pre-synthesis-check) requires a key or token; a public, unauthenticated example is available at GET /api/v1/protect/demo/pre-synthesis-check for evaluation.
POST /auth/login
Content-Type: application/json
{
"email": "[email protected]",
"password": "your_password"
}
// Response
{
"access_token": "eyJ...",
"token_type": "bearer",
"user_id": "uuid"
}
Include the token in all subsequent requests: Authorization: Bearer <token>
Enroll and manage voice prints.
/voices/enroll
Enroll a new voice. Requires multipart/form-data with audio file. Biometric consent must be granted first.
/voices
List all enrolled voices for the authenticated user.
/voices/{voice_id}
Remove an enrolled voice and all associated data.
Compare two audio samples for voice-identity similarity. VoiceSeal does not crawl or monitor platforms; provenance of synthetic audio is carried in-band via C2PA Content Credentials (transparency page).
/detection/compare
Submit two audio samples to compare voice-identity similarity. Returns a similarity score and a same-speaker assessment — evidence for review, not a verdict.
// Response
{
"similarity": 0.94,
"is_same_speaker": true,
"embedding1_hash": "sha256:...",
"embedding2_hash": "sha256:..."
}
BIPA-aligned consent management. Required before voice enrollment.
/consent/submit
Grant biometric consent. Must be called before enrollment.
/consent/withdraw
Withdraw consent and trigger data deletion per BIPA requirements.
The VoiceSeal pre-synthesis consent gate. Called by TTS platforms before generating audio to verify biometric identity, consent status, and license scope. This is VoiceSeal's patent-pending flagship capability. VoiceSeal provides an independent, synthesis-agnostic permission and provenance layer designed to operate across voice platforms rather than remaining limited to a single generator's ecosystem.
/api/v1/protect/pre-synthesis-check
Verify consent and license scope before synthesizing audio from a registered voice identity. Returns a single-use, time-limited authorization token on success, or authorization_denied on failure.
🔒 Authentication required — send an X-API-Key (platform integration) or a Bearer token (first-party). To try the gate without credentials, use the public GET /api/v1/protect/demo/pre-synthesis-check (evaluation only).
Platforms can evaluate VoiceSeal's consent gate before committing to an API integration via the public demo endpoint (GET /api/v1/protect/demo/pre-synthesis-check), which returns the same response schema. The production endpoint above requires authentication and writes a full audit record.
Request Body
{
"voice_id": "string (UUID) — the enrolled voice identity to check",
"platform_name": "string — identifying name of the calling platform",
"intended_use": "string — commercial | audiobook | podcast | music | gaming",
"license_token": "string (optional) — existing license token if already held"
}
Response — Approved (200)
{
"status": "approved",
"authorization_token": "string — single-use, time-limited token authorizing this synthesis (present only when approved). Deprecated alias: approval_token (retained until 2026-09-17)",
"voice_id": "string",
"consented": true,
"licensed": true,
"expires_at": "ISO 8601 timestamp",
"check_id": "string — audit trail reference"
}
Response — Blocked (200)
{
"status": "blocked",
"action": "authorization_denied",
"reason": "no_consent | no_license | scope_mismatch",
"voice_id": "string",
"license_url": "https://voiceseal.io/licensing?voice_id={voice_id}",
"check_id": "string",
"authorization_denied": true
}
Response — No registry record (200)
{
"action": "no_registry_record",
"platform_decision_required": true,
"voice_id": null,
"check_id": "string"
}
A voice with no registry record is not a 404 — the check returns 200 with action: no_registry_record and platform_decision_required: true, leaving the decision to your platform's standard terms.
Error Codes
403 | Platform not authorized |
422 | Invalid request body |
401 | Authentication required — missing/invalid X-API-Key or Bearer token |
429 | Rate limit exceeded — 1,000 requests/minute (authenticated) |
Audit record
Every decision — allow or deny — is written to the hash-chained audit log and addressable by its check_id (see GET /api/v1/protect/audit-log). A denial returns decision: "deny" with license_status/consent_status explaining why.
check_id. Separately, VoiceSeal's C2PA marking applies a trusted, in-band AI-disclosure with a signature and RFC 3161 timestamp to marked audio. The C2PA manifest does not currently carry the authorization token, consent, license, or check_id — those live in the audit record, not the credential. (Planned, not yet available: embedding authorization references into the manifest to bind provenance to the consent record.)
/api/v1/protect/demo/pre-synthesis-check
🔓 Public, no auth. A self-describing demo of the pre-synthesis gate for platform evaluators — returns a live example request, the full response schema, and every possible action outcome, so you can see exactly what an integration looks like without enrolling a voice or authenticating first. Rate limit: 100 requests/hour per IP (unauthenticated).
Example Response (abridged)
{
"demo": true,
"endpoint": "POST /api/v1/protect/pre-synthesis-check",
"response_schema": {
"protected": "bool",
"action": "authorized | authorization_denied | no_registry_record",
"decision": "allow | deny | unresolved",
"license_status": "licensed | unlicensed | not_applicable",
"consent_status": "active | withdrawn | unknown",
"platform_decision_required": "bool — true when no registry record exists",
"license_url": "string | null",
"check_id": "uuid — hash-chained audit-trail id"
},
"possible_responses": {
"no_registry_record": { "action": "no_registry_record", "decision": "unresolved", "platform_decision_required": true, "...": "..." },
"protected_no_license": { "action": "authorization_denied", "decision": "deny", "license_status": "unlicensed", "license_url": "...", "...": "..." },
"protected_licensed": { "action": "authorized", "decision": "allow", "license_status": "licensed", "...": "..." }
}
}
Try it live: GET https://api.voiceseal.io/api/v1/protect/demo/pre-synthesis-check
Subscribe to enrollment and licensing events. Every event originates from an action inside VoiceSeal — VoiceSeal does not crawl or monitor platforms — and each delivery is signed with HMAC-SHA256 (sent in the VoiceSeal-Event header).
// Registrable events
"enrollment.complete" // a voice enrollment finished (currently emitted)
"enrollment.ready" // an enrollment session is ready to collect samples
"enrollment.failed" // an enrollment could not complete
"license.renewed" // a license was renewed
"license.expired" // a license reached its expiry
"license.revoked" // a license was revoked by the owner
"voice.deleted" // a voice profile was deleted
// Example delivery
{
"event": "enrollment.complete",
"voice_id": "uuid",
"timestamp": "2026-09-01T14:32:00Z"
}
Register via POST /webhooks/register with your endpoint URL, secret, and the events you want; deliveries are retried with backoff. enrollment.complete is live today; the remaining registrable events are emitted as their source actions are wired.