ID verification
Tool-triggered ID card capture during web sessions via LiveKit RPC.
Identity verification is not a mandatory popup on join. When proctoring and ID
verification are enabled, the agent opens the capture overlay by calling LiveKit RPC
start_id_capture on the candidate (typically from a Python @function_tool).
After a good frame is detected, the web client uploads two JPEGs to the backend and
notifies the agent via add_context.
Setup
- In Call Session, enable Proctoring and ID verification (“Allow the agent to request ID card capture during the session (via a tool call).”).
- Create an org Python tool (Tools → Create Python tool) and paste the sample below.
- Attach that tool to the agent so the model can call
verify_identitymid-session. - Start a web (share / embed / preview) session with the camera on.
Flow
Agent tool verify_identity
→ perform_rpc("start_id_capture") on candidate
→ Client opens ID overlay and scans camera frames
→ POST /sessions/{id}/participant-files (id-card.jpg)
→ POST /sessions/{id}/participant-files (id-card-full.jpg)
→ Client perform_rpc("add_context") with type "id_captured" (action: generate_reply)
→ Agent chat gets a system message; agent acknowledges and continuesRPC: start_id_capture (agent → candidate)
- Registered only when
session_modalities.proctoring.id_verificationis true. - Payload: empty string (or unused).
- Response:
{"started": true}(JSON string).
Upload: participant files
Authenticated with the candidate’s LiveKit participant JWT:
| Name | Content |
|---|---|
id-card.jpg | Cropped ID card JPEG |
id-card-full.jpg | Full-frame evidence JPEG |
Endpoint: POST /sessions/{id}/participant-files (see worker contract).
RPC: add_context (candidate → agent)
After a successful upload the client injects a system message into the agent session
via add_context (worker: role="system", then generate_reply so the agent continues):
{
"state": "ID card capture completed successfully. The candidate's ID images have been uploaded and submitted for verification. You may continue the conversation.",
"action": "generate_reply",
"type": "id_captured",
"details": {
"confidence": 0.0,
"capturedAt": 0,
"status": "completed"
}
}Sample Python tool
Paste into Create Python Tool. The worker injects host (.agent, .ctx, .state).
@function_tool()
async def verify_identity(self, context: RunContext) -> str:
"""Open the candidate's ID capture overlay in the browser.
Call when the candidate must present a government ID.
Returns when the overlay has been opened — not when the ID is submitted.
"""
try:
room_io = context.session.room_io
except RuntimeError:
return "error: room not available yet"
participant = room_io.linked_participant
if participant is None:
return "error: no candidate participant in the room"
try:
response = await room_io.room.local_participant.perform_rpc(
destination_identity=participant.identity,
method="start_id_capture",
payload="",
)
except Exception as e:
return f"error: RPC failed: {e}"
return f"ID capture started: {response}"How to test
- Enable proctoring + ID verification on the agent.
- Add the Python tool above and attach it to the agent.
- Join a share/embed/preview session with camera enabled.
- Ask the agent to verify your identity (or otherwise invoke
verify_identity). - Hold an ID inside the guide frame until capture succeeds.
- Confirm toast “ID card captured” and that
id-card.jpg/id-card-full.jpgappear on the session’s participant files.
Related
- Worker contract (
start_id_capture,add_context) - Client hook:
apps/web/hooks/useProctoring.ts - Upload helper:
apps/web/lib/proctoring/upload-id-capture.ts