Eidos
Speaker verification. Eidos saves a person's voice from enrollment recordings, then tells you whether a new recording is the same person.
Is this the right person? That is the question Eidos answers. Use it through the REST API or the MCP server, with the same API key as the other products.
How it works
- Enroll. Send recordings of one person under a
speaker_idyou choose. The speaker is created with the first recording. - Verify. Send a new recording with the same
speaker_id. Eidos compares it with the enrolled voice and answersmatchorno_match.
| Step | Recording length | Speech needed |
|---|---|---|
| Enroll | 15 to 60 seconds | At least 10 seconds |
| Verify | 3 to 60 seconds | At least 2 seconds |
- Each enrollment recording should hold the clear speech of that one person.
- A speaker can have up to 5 enrollment recordings. Enroll 2 or 3 from different sessions, such as different days or devices: verification is then more reliable.
- A
speaker_idis 1 to 64 letters, digits or the characters_ . : -. Use your own identifier, for example a customer number, and add adisplay_nameif you want a readable label in the dashboard.
Read the result
Example verification response, shortened:
{
"request_id": "req_8f14e45fceea167a5a36dedd",
"operation_id": "op_6f1ed002ab5595859014ebf0951522d9",
"object": "speaker.verification",
"speaker_id": "customer-4711",
"result": {
"decision": "match",
"similarity": 0.7412,
"threshold": 0.53,
"duration_seconds": 4.1
}
}| Field | Meaning |
|---|---|
result.decision |
match when similarity is at or above threshold, otherwise no_match. Decide with this field. |
result.similarity |
How alike the two voices are, from -1 to 1 (higher is more alike). It is not a percentage or a probability. |
result.threshold |
The similarity from which the decision is match. |
result.duration_seconds |
Length of the checked audio, in seconds. |
operation_id |
Fetch the result again later, for 30 days. |
The full list of fields is in Verify a speaker.
Use the decision well
- The threshold is set for few false accepts, so a genuine speaker recorded in different conditions is rejected more often. Enrolling recordings from different days or devices helps.
- Phone-quality audio gives less reliable results than clear recordings.
- A match is a signal, not proof. Use it with other checks, and have a person review decisions that matter.
Recording length
An enrollment recording shorter than 15 seconds, longer than 60 seconds or with less than 10 seconds of speech is refused with 422; so is a verification recording outside 3 to 60 seconds or with less than 2 seconds of speech. The error message says what is needed. A sixth enrollment recording is refused with 409 (too_many_samples).
Check for AI-generated speech at the same time
Send detect_deepfake=true with a verification and the same recording is also checked by Aletheia. The key needs the deepfake:detect permission too, and the recording must be longer than 4 seconds for that check.
The response then has a deepfake object with Aletheia's verdict. The two checks are separate: if only the AI-speech check fails, you still get the verification, with deepfake.error.
Manage speakers
- List speakers returns your speakers, newest first, with how many recordings each has. Page through long lists with
limitandcursor. - Get a speaker returns one speaker by its
speaker_id. - Delete a speaker deletes the speaker and its voice profile permanently, together with the recordings used to enroll it. Later verifications for that
speaker_idreturn404.
Enrolled voice profiles are stored encrypted until you delete the speaker or your account; see Privacy.
Quickstart
Create an API key first (see Authentication). Enroll a recording of 15 to 60 seconds:
curl https://platform.detectif.ai/v1/speakers/enroll \
-H "Authorization: Bearer $DETECTIF_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "speaker_id=alice" \
-F "file=@alice-1.wav"import os
import uuid
import requests
with open("alice-1.wav", "rb") as f:
resp = requests.post(
"https://platform.detectif.ai/v1/speakers/enroll",
headers={
"Authorization": f"Bearer {os.environ['DETECTIF_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
data={"speaker_id": "alice"},
files={"file": f},
timeout=300,
)
resp.raise_for_status()
print(resp.json()["speaker"])Then verify a new recording of 3 to 60 seconds against it:
curl https://platform.detectif.ai/v1/speakers/verify \
-H "Authorization: Bearer $DETECTIF_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "speaker_id=alice" \
-F "file=@new-call.wav"import os
import uuid
import requests
with open("new-call.wav", "rb") as f:
resp = requests.post(
"https://platform.detectif.ai/v1/speakers/verify",
headers={
"Authorization": f"Bearer {os.environ['DETECTIF_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
data={"speaker_id": "alice"},
files={"file": f},
timeout=300,
)
resp.raise_for_status()
result = resp.json()["result"]
print(result["decision"], result["similarity"])With MCP, connect your assistant and ask:
Enroll /path/alice-1.wav as speaker "alice".Is /path/new-call.wav Alice? Also check whether it is AI-generated.List my enrolled speakers.The assistant calls enroll_speaker, verify_speaker and list_speakers for you.
Uploaded files are stored for 30 days. Send store_audio=false (in MCP, the store_audio argument) to not store a file; see Privacy.
Fetch a result again
Results are kept for 30 days. Get a result (GET /v1/operations/{operation_id}, or the get_operation tool) returns an enrollment or a verification by its operation_id, for example when your connection dropped before the response arrived. It is shared with Aletheia, so it is listed under Account.
API reference
Base URL: https://platform.detectif.ai.
| Method | Path | Page |
|---|---|---|
POST |
/v1/speakers/enroll |
Enroll a voice sample |
POST |
/v1/speakers/verify |
Verify a speaker |
GET |
/v1/speakers |
List speakers |
GET |
/v1/speakers/{speaker_id} |
Get a speaker |
DELETE |
/v1/speakers/{speaker_id} |
Delete a speaker |
GET |
/v1/operations/{operation_id} |
Get a result. Shared with Aletheia, listed under Account. |
MCP tools
| Tool | What it does | Inputs |
|---|---|---|
enroll_speaker |
Add one enrollment sample for a speaker (creates the speaker on first use) with Eidos. | speaker_id, audio_base64, filename, display_name (optional), idempotency_key (optional), store_audio (optional) |
verify_speaker |
Compare a recording (3-60 s, at least 2 s of speech) with an enrolled speaker using Eidos. | speaker_id, audio_base64, filename, detect_deepfake (optional), idempotency_key (optional), store_audio (optional) |
list_speakers |
List enrolled speakers in this account, newest first. | limit (optional), cursor (optional) |
delete_speaker |
Delete a speaker and its stored voice profile. | speaker_id |
get_operation |
Fetch a stored operation: status and, for 30 days, its result. Shared with Aletheia, listed under Account. | operation_id |