Guides

Concepts & how things work

The reference tells you what to send. This page explains why — how a call moves through verification, what enrolling a voice actually does, and what each response property means.

The call lifecycle

A reseller works inbound calls for a child institution. Each call is identified by a voiceId — Pindrop's identifier for that call's audio, and the handle you pass to every call-scoped endpoint.

  1. AssignPOST /external/calls/assign links an inbound call (by phone number or existing voiceId) to a member (personId) and returns the voiceId.
  2. QueueGET /external/calls/queue lists calls awaiting verification, with optional search and date filters.
  3. InspectGET /external/calls/{voiceId}/details returns the full call record: enrollment/verification flags, risk, and the Pindrop event log.
  4. DecidePOST …/enroll to accept the caller's voice, or POST …/reject-voice to reject it.

How voice enrollment works

Enrolling a voice (POST /external/calls/{voiceId}/enroll) is how a reseller manually authenticates a caller and tells Pindrop to trust and keep that caller's voiceprint. A single call does several things atomically:

  • Records a verification for the member, tagged with the validationType you supplied (voice, OTP, KBA, …).
  • Tells Pindrop the interaction succeeded — it sends account-interaction feedback keyed by the account alias {institutionKey}-{personId} against this voiceId, with status SUCCESSFUL. This is what lets Pindrop enroll and reuse the voiceprint on future calls.
  • Applies the “Green Manual Authentication” policy to the call. This signals to Pindrop's call-end webhook that the enrollment should be preserved even if an automated voice-match rule would otherwise reject it.
  • Writes two activity recordsAcceptCallerVoice (the reseller explicitly accepted the voice) and FullAuthentication (the caller is fully authenticated). The FullAuthentication activity is what stops the call-end webhook from discarding the voiceprint.
Net effect

After a successful enroll, the member's voiceprint is trusted in Pindrop and future calls from that member can be voice-authenticated automatically — no further manual verification needed.

Enroll a voice
curl -X POST https://api.getconfirmed.org/external/calls/<voiceId>/enroll \
  -H "SsoToken: <sso-token>" \
  -H "InstitutionKey: acme-cu" \
  -H "RequestedBy: jdoe" \
  -H "Content-Type: application/json" \
  -d '{ "personId": "00123", "validationType": "VoiceAuth", "notes": "Verified by agent" }'

→ { "success": true }

Voice authentication thresholds

Separately from the manual /enroll flow above, Pindrop runs its own passive voice biometrics on call audio. Two distinct checks govern this — one for creating a voiceprint (enrollment) and one for matching against an existing voiceprint (verification). Both require a low device risk_rating.

ScenarioRequired conditionsResult
New enrollment
(first voiceprint for a member)
voiceStrength = 100 and risk_rating = low Pindrop applies its “Basic Enrollment Speech” enrollment policy, which flips successfulVoiceEnrollment = true on that phone call.
Voice verification
(against an existing enrollment)
voiceScore50 and risk_rating = low The call is treated as voice-verified.
Enrollment discarded
(low liveness)
liveness score is > 0 and < 30 Confirm does not enroll the caller's voice — the audio is most likely synthetic or recorded. successfulVoiceEnrollment stays false.
Low liveness blocks enrollment

When Pindrop's liveness detection returns a low score (greater than 0 and under 30), the caller's voice is treated as probably a clone, deepfake, or playback and is not enrolled even if it would otherwise meet the enrollment threshold. The same low-liveness signal also drives the new Red Low Liveness authentication policies described under Interpreting the validation status.

Note on voiceStrength

voiceStrength is the signal that gates a new enrollment (it must reach 100). It is not currently exposed through the Pindrop API, so it is not returned on the call-detail response — only its effect is observable, via successfulVoiceEnrollment flipping to true once enrollment succeeds.

Build rules on policies, not raw scores

The numeric voiceScore (and the underlying device/voice signals) is only present on Pindrop's call_end and call.enrollment_update webhook events — it is not available mid-call, so it is unreliable as a live decision signal. Pindrop already bakes these scores and thresholds into the policies it returns. Drive your business logic off metaData.pindropPolicies, never off the raw scores. See the next section for how to turn those policies into a status.

Rejecting & un-enrolling a voice

POST /external/calls/{voiceId}/reject-voice is the inverse. It notifies Pindrop of a FAILED interaction, records a RejectCallerVoice activity, and — importantly — un-enrolls every prior manual authentication for that member: each earlier FullAuthentication activity is moved to FullAuthenticationUnenrolled, so Pindrop discards the previously trusted voiceprint. Use it when a caller's identity can't be trusted.

Call detail properties

Selected fields returned by GET /external/calls/{voiceId}/details. The reference lists the full schema; these are the ones whose meaning isn't obvious.

PropertyMeaning
voiceIdPindrop's identifier for the call audio; the handle used by all call-scoped endpoints.
personId / valueForCoreThe matched member id and the core system's internal identifier for that member.
isVoiceEnrolledA voiceprint exists in Pindrop for this member.
isVoiceVerifiedThe voice was verified on this call.
isVoiceMismatchThe caller's voice did not match the enrolled voiceprint — a fraud signal.
successfulVoiceEnrollmentPindrop's enrollment-update webhook confirmed the voiceprint was enrolled on this call.
isHighRiskDevicePindrop's device analysis flagged the originating device as high risk.
statusThe current activity status of the call (see the table below).
hasVoiceMatchValidationRuleThe institution's active validation rule includes a voice-match requirement.
metaData.pindropPoliciesPolicies applied to the call, e.g. "Green Manual Authentication".
pindropEventsThe full event log received from Pindrop's webhooks for this call.

Interpreting the validation status

Our own dashboard shows the agent a single color-coded validation status for each call — a traffic-light that tells them how to proceed. That status is derived entirely from metaData.pindropPolicies (the policies Pindrop applied to the call). If you build your own agent UI, reproduce the same logic so your status matches ours.

The rule is a simple case-insensitive keyword match with a fixed precedence — the first rule that matches wins:

#If any policy contains…StatusWhat it means for the agent
1 green Fully Authenticated
Device & Voice Match
Voice (and device) matched. Proceed with assisting the caller. Shows as “Device & Voice Match” when the institution also has a voice-match validation rule (hasVoiceMatchValidationRule).
2 gray High Risk Device Spoofing, SIM-swap, suspicious VoIP, or other device/network signals. Proceed with caution and ask further verification questions.
3 red (but not answered) High Risk Caller The voice does not match previous records — a high-risk / fraud signal. Policies that also contain answered are excluded here, because the caller passed knowledge-based questions.
4 Account Not Enrolled (e.g. “Yellow/Blue Low Risk Account Not Enrolled”) First Time Caller No previous voiceprint exists. No fraud detected — proceed to knowledge-based questions and/or send an MFA code.
5 anything else (default) Voice Pending
No Identity Claim
The account is enrolled but the voice hasn't matched yet. Shows as “No Identity Claim” for the Yellow Low Risk No ID Claim policy. Continue verifying — voice results may still resolve to green.
Why match on the policy keyword instead of fixed flags?

Matching on the color keyword (rather than a fixed set of boolean fields) lets Confirm introduce new policies driven by new business rules without any code or schema changes — the new policy just needs the right color word in its name. For example, at launch we didn't offer our liveness / deepfake-detection product (Pulse); once we added it, we were able to introduce new Red policies based on liveness scores, and they began surfacing as “High Risk Caller” automatically — no code change required. If you mirror this keyword approach on your side, your UI inherits new policies the same way.

Liveness / deepfake policies (Pulse)

When Pindrop's liveness detection scores a call's audio as low (greater than 0 and under 30) and the liveness reason is not ambient — i.e. the signal looks like a synthetic or recorded voice rather than just background noise — Confirm applies one of the following policies. All three contain red, so they map to High Risk Caller via rule 3 above with no extra handling on your side:

Policy nameApplied when
Red Low Liveness No ID ClaimLow liveness and no personId (identity claim) was provided.
Red Low Liveness Account EnrolledLow liveness and the claimed personId is already voice-enrolled.
Red Low Liveness Account Not EnrolledLow liveness and the claimed personId is not yet voice-enrolled.

Ambient noise is excluded. If Pindrop attributes the low liveness score to ambient conditions (a TV, radio, or other background noise), none of these policies are applied — a noisy line is not treated as fraud.

Two more states are not driven by a policy string — they're behavioural:

StatusWhen
LoadingThe initial state before Pindrop's verification results have arrived for the call.
No Voice MatchA Voice Pending (yellow) call that never resolved to green. Our dashboard re-polls …/details for a short while; if the voice still hasn't matched it settles on “No Voice Match”. This is not necessarily fraud — it can be a cold, a noisy line, etc. — but the account was enrolled and the voice didn't match.
Poll while a call is in progress

A status of Voice Pending means Pindrop is still evaluating. Re-fetch GET /external/calls/{voiceId}/details until the status resolves (to green) or the call ends. As above, base every decision on metaData.pindropPolicies — not on the raw scores in pindropEvents.

Activity status reference

The status on a call (and on individual activity records) is one of the following.

StatusMeaning
FullAuthenticationCaller fully authenticated (by voice or another method).
FullAuthenticationUnenrolledA previous full authentication that has since been rejected / un-enrolled.
AcceptCallerVoiceThe caller's voice was explicitly accepted.
RejectCallerVoiceThe caller's voice was explicitly rejected.
RejectCallerVoiceFromValidationRuleAn automated validation rule rejected the voice.
VoiceMismatchThe voice did not match the enrolled voiceprint.
AnsweredQuestionsThe caller passed knowledge-based authentication (KBA).
MFAValidatedMulti-factor authentication passed.
VoiceOptIn / VoiceOptOutThe caller opted in / out of voice authentication.
CallStarted / CallEndedCall lifecycle markers.

Validation types

The validationType you send when enrolling records how the caller was verified.

ValueMeaning
VoiceAuthVerified by voice biometrics.
OneTimePasswordAuthVerified with a one-time passcode.
KnowledgeBasedAuthVerified via knowledge-based questions.
NoAuthNo additional authentication performed.
OtherAny other verification method.

Open the API reference →