Klozer AI
PrepareReviewFlowsSecurity
System flows · v1

From dial to replay,
six stages of a Klozer AI call.

What the trainee sees when the call connects, what's captured while it's live, how the pipeline turns audio into a replayable transcript, and the screen the manager opens an hour later to grade it.

01Call start02Live capture03Call end04Post-call pipeline05DB record06Manager replay
Stage 01

Trainee initiates the call

A button press opens a session. Klozer AI stamps an immutable identifier and locks the scenario, persona, and difficulty so every downstream artifact joins back to one row.

Data captured
call_idUUID v7 — sortable & globally unique
trainee_idFrom auth · scoped by org_id
scenario_idSelected in the picker; immutable for this row
agent_idAI persona attached to scenario
difficultyTier 1–3; baked into the row at start
start_timestampUTC, written when WebRTC connects
credits_beforeWallet snapshot; rate_per_min cached
statusin_progress — flipped on hangup
klozer.app · start a call
Welcome back
Maya Okafor
84 credits
12
calls this week
3.4 h
training time
7-day
streak
Recent calls
Burned by last vendor · 2:4784/100
The gatekeeper · 1:1472/100
Polite ghost · 4:0891/100
Step 1 of 2
Pick a scenario
Burned by last vendor
VP Ops · skeptical
Tier 3
The gatekeeper
EA · time-poor
Tier 1
Polite ghost
Mid-market director
Tier 2
rate 12¢/min · session ~3min
Stage 02

The call goes live

Audio streams in via WebRTC, both channels separate, with the trainee on the left and the AI persona on the right. The wallet ticks down per minute as the conversation runs.

Data captured
audio_streamDual-channel · 48 kHz · chunked to server
trainee_channelLeft · isolated for STT diarization
ai_channelRight · TTS response captured verbatim
credits_tickingLive deduction · DB wallet updated in real-time
session_stateHeartbeat keeps reconnect safe (60s tolerance)
klozer.app · in session · call_8f3a2c
A
Mr. Alvarez · VP Ops
Burned by last vendor · Tier 3
01:2483.6 / 84 credits
Trainee · left channel-12dB peak
AI persona · right channel-18dB peak
Live transcript
Honestly, I'm in the middle of something. What's this about?
Totally fair — thirty seconds. We work with regional carriers on freight visibility.
We tried something like that last quarter. Painful integration.
That comes up a lot. Was it the EDI piece, or the
capture WebRTC · 48kHz · dual-channel
Your goal
Identify the specific integration pain. Don't pitch features yet.
Live coach
Good — naming the specific pain. Stay quiet for 2 beats after he answers.
Objection bank
✓Painful integration
Already have a TMS
Budget locked
Stage 03

The call ends

Hangup seals the session. Klozer AI writes end-side timestamps, status, and credit totals, then hands the audio to the post-call pipeline.

Data captured
end_timestampUTC, on hangup or 60s heartbeat loss
duration_secondsDerived; redundant for fast filters
statuscompleted / abandoned / error
total_credits_usedrate × duration, written once
credits_remaining_afterWallet snapshot post-debit
klozer.app · call ended · call_8f3a2c
Call complete
You ended the call · scenario closed · session sealed
Duration
02:47
ended 14:24 UTC
Status
completed
no errors
Credits used
0.34
0.34 of 84 wallet
Credits left
83.66
≈ 9.7h remaining
Your replay is being prepared
Usually ready in 30–45 seconds. We'll email you and notify your manager.
3 of 4 steps · ~18s left
✓ Audio sealed✓ Uploaded to S3✓ Transcribed⟳ Scoring…
Stage 04

The post-call pipeline runs

Audio is shipped to S3, Whisper transcribes it with word-level timestamps, the JSON is indexed in Postgres, and a scoring job grades the call against the scenario's dimensions.

Data captured
audio_s3_path/org_id/trainee_id/call_id/audio.wav · KMS-encrypted
transcriptPlain text · search-indexed (tsvector)
word_timestampsJSONB · GIN-indexed for fast lookup
overall_score0–100 from weighted dimensions
colour_tags[{ start_ms, end_ms, tag }] per segment
klozer.app · admin · pipeline · call_8f3a2c
Job · call_8f3a2c
Post-call processing
3 of 4 doneelapsed 19.9s · est. 22s total
Audio sealed & uploaded to S3
+0.4s1.2s
Path
/org_92/trn_okafor/call_8f3a2c/audio.wav
Format
16-bit PCM · 48 kHz · dual-channel
Size
26.4 MB
Speech-to-text · Whisper v3
+1.6s11.8s
Model
whisper-large-v3 · en-US
Granularity
word-level timestamps
Words
412 · 2 speakers · 0 errors
Word-timestamp index built
+13.4s0.3s
Format
JSON · [{word, start_ms, end_ms, speaker}]
Size
38 KB
Storage
Postgres jsonb column · GIN-indexed
Scoring · feedback report
+13.7s6.2s
Dimensions
discovery · objection · empathy · compliance · close
Output
overall_score · per-segment colour_tags[]
Status
scoring 4/5 dimensions
Output
On completion: calls.status → “completed”, replay link emitted to manager queue.
Stage 05

It all lands in one row

The calls table is the single artifact the replay UI reads from. Grouped by purpose, narrow on the hot columns, JSONB on the bulky transcript so the player can scan a single column.

Data captured
PKcall_id (UUID v7)
Indexestrainee_id · scenario_id · status · start_timestamp
SecurityRow-level security on org_id
FK joinstrainees · scenarios · ai_personas · feedback_reports
Retention90d audio, 2y transcript, 7y scores
klozer.app · admin · schema · calls
calls
postgres · 24 columns · 6 groups
RLS by org_id
Identifiers6 col
call_id
primary key · indexed
UUID
trainee_id
FK → users
UUID
org_id
FK → orgs · row-level security
UUID
scenario_id
FK → scenarios
UUID
agent_id
FK → ai_personas
UUID
difficulty
1=tier 1 … 3=tier 3
smallint
Timing3 col
start_timestamp
UTC · written on call connect
timestamptz
end_timestamp
UTC · written on hangup
timestamptz
duration_seconds
derived; redundant for fast filters
int
Storage & status3 col
audio_s3_path
/org_id/trainee_id/call_id/audio.wav
text
status
in_progress / completed / abandoned / error
enum
credits_used
6,4 · per-minute deduction × duration
numeric
Transcript data2 col
transcript
full plain text · search-indexed (tsvector)
text
word_timestamps
[ { word, start_ms, end_ms, speaker } ]
jsonb
Scores5 col
overall_score
0–100
numeric
fluency_score
0–100
numeric
accent_score
0–100
numeric
sentiment_score
-1 … 1
numeric
knowledge_score
0–100
numeric
Feedback3 col
feedback_report_id
FK → feedback_reports
UUID
pass_fail_status
pass / coaching_needed / fail
enum
colour_tags
[ { start_ms, end_ms, tag: mistake|improve|excellent } ]
jsonb[]
Joins on trainee_id, scenario_id, agent_id, and feedback_report_id. word_timestamps stored as JSONB so the replay UI can scan a single column.
Stage 06

The manager opens the replay

One screen. The audio scrubs in lockstep with the transcript, the current word glows, colour-coded segments mark what went well and what didn't, and the score panel sits alongside — ready for coach notes.

Data captured
PollingJS reads audio.currentTime every ~50 ms
LookupBinary search across word_timestamps[]
Current wordAmber underline + auto-scroll into view
Segmentsmistake · could-improve · excellent · persistent under highlight
ActionsComment · share replay · export audio · export transcript PDF
klozer.app · review · call_8f3a2c
Back to Maya's history
M
Maya Okafor
SDR · 6 weeks tenure · cohort B
Burned by last vendor
Tier 3 · objections · May 14, 14:22
84/100
+6 vs last
Dual-channel waveform
00:00 ─────── 01:24 ▌ ─────── 02:47
Trainee
AI persona
1:24.6
MistakeCould improveExcellent6 segments tagged · 412 words indexed
0:04Maya
Could improveSoft opener — could anchor on a specific reason
Hi, this is Maya calling from Northwind Logistics — am I catching you at a good moment, Mr. Alvarez?
+ commentClip
0:12Alvarez
Honestly, I'm in the middle of something. What's this about?
+ commentClip
0:17Maya
ExcellentStrong: permission-asking + specific observation
Totally fair. I'll keep it to thirty seconds — we work with regional carriers on freight visibility and I noticed you've been quoting more lanes in the Pacific Northwest.
+ commentClip
0:28Alvarez
We've looked at a couple of those tools. The integration was painful — three months of EDI mapping with our last vendor.
+ commentClip
0:40Maya
ExcellentExcellent mirror — names the specific pain
That comes up a lot. Curious — was it the EDI piece itself, or the TMS handshake?
+ commentClip
0:51Alvarez
Both, honestly. The TMS side never reconciled. But look, we just renewed with our current vendor.
+ commentClip
1:04Maya
MistakeFiller + double-question — loses authority
Got it. So… what does that mean? Like, are you locked in, or just don't want to deal with it again?
+ commentClip
Score breakdown
Discovery92
Objection handling78
Empathy88
Compliance100
Close strength64
Coach notes · 3
@ 0:40Devon (you)
Excellent mirror — exactly the move. Pinning this.
@ 1:04Devon (you)
Watch the double-question. Pick one and let silence work.
Sync engine
Polls audio.currentTime every 50 ms, binary-searches word_timestamps[] for the active word, applies the amber underline.
01:24.6 / 02:47
0.5×0.75×1×1.25×1.5×2×
End-to-end

One row in calls — six surfaces, zero hand-offs.

Every screen on this page reads from the same row written at hangup. No data lake hops, no nightly batches, no “where did the transcript go” support tickets.

← Back to overview