Core concepts
Understand the key concepts that shape the Conduit SDK experience.
Conduit analysis is long-running. The SDK returns a receipt immediately after source materialization, upload, and job acceptance, then expects webhook delivery for completion.
Processing pipeline​
From the SDK point of view, report generation follows one async pipeline:
materialize source -> upload -> transcode -> diarize/fingerprint -> extract target -> score -> generate report -> render -> finalize
What happens:
- The SDK resolves
sourcefrommediaId,file,url, orpath - Conduit processes the recording and selects the requested speaker target
- The completed report becomes available by webhook and later retrieval
Typical duration: around 150 seconds
Status tracking: job status and job stage
Cost: usage follows your plan and pricing rules (see Pricing)
Media reuse​
If you want to analyze the same recording multiple times, upload once and reuse mediaId.
const media = await conduitClient.primitives.media.upload({ path: "./interview.mp4" })
const candidateReceipt = await conduitClient.reports.create({
source: { mediaId: media.mediaId },
output: { template: "general_report" },
target: { strategy: "magic_hint", hint: "the candidate" },
})
const interviewerReceipt = await conduitClient.reports.create({
source: { mediaId: media.mediaId },
output: { template: "general_report" },
target: { strategy: "magic_hint", hint: "the interviewer" },
})
const candidateReport = await candidateReceipt.handle?.wait()
const interviewerReport = await interviewerReceipt.handle?.wait()
This lets you:
- reuse uploaded media across workflows
- analyze different speakers from the same recording
- try different templates without re-uploading bytes
Jobs​
A job represents one report-generation attempt.
Job lifecycle​
create -> queued/running -> succeeded | failed | canceled
Job statuses​
| Status | Description |
|---|---|
queued | Waiting to start |
running | Currently generating |
succeeded | Report ready |
failed | Something failed |
canceled | Job was canceled |
Job stages​
| Stage | Description |
|---|---|
uploaded | Source upload completed |
queued | Accepted and waiting |
transcoding | Media preprocessing |
extracting | Speaker extraction / targeting |
scoring | Behavioral scoring |
rendering | Report rendering |
finalizing | Final persistence and completion |
const receipt = await conduitClient.reports.create({
source: { mediaId: "media_123" },
output: { template: "general_report" },
target: { strategy: "dominant" },
webhook: { url: "https://your-app.com/webhooks/conduit" },
})
console.info(receipt.jobId, receipt.status, receipt.stage)
Use webhooks instead of polling wherever possible. Receipt handles are a fallback for scripts and local development.
Reports​
Reports are the final behavioral analysis output.
Common report fields​
| Field | Description |
|---|---|
markdown | Markdown rendering when available |
summary | Short summary text when available |
sections | Structured sections when available |
metrics | Template-dependent metrics when available |
reportUrl | Hosted report URL when available |
Templates​
| Template | Use for |
|---|---|
general_report | General behavioral analysis |
sales_playbook | Sales-oriented guidance |
Speaker targeting​
Use target to pick the speaker you want analyzed.
| Strategy | Use when |
|---|---|
dominant | One clear primary speaker |
magic_hint | You know the role in natural language |
entity_id | You already track the speaker across sessions |
timerange | You want a specific time window |
const receipt = await conduitClient.reports.create({
source: { mediaId: "media_meeting_123" },
output: { template: "general_report" },
target: {
strategy: "magic_hint",
hint: "the job candidate being interviewed",
onMiss: "fallback_dominant",
},
})
Learn targeting strategies →
Entities​
Conduit creates an entity for a stable speaker identity when the product can resolve one.
Why entities matter:
- reuse the same speaker identity across recordings
- move from best-effort hints to deterministic
entity_idtargeting - label speakers in your own workflow using
conduitClient.primitives.entities.update(...)
const receipt1 = await conduitClient.reports.create({
source: { mediaId: "media_round_1" },
output: { template: "general_report" },
target: { strategy: "magic_hint", hint: "the candidate" },
})
const report1 = await receipt1.handle?.wait()
const entityId = report1?.entity?.id
const receipt2 = await conduitClient.reports.create({
source: { mediaId: "media_round_2" },
output: { template: "general_report" },
target: { strategy: "entity_id", entityId: entityId! },
})
const report2 = await receipt2.handle?.wait()
Advanced entity management →
Credits​
Credits are consumed by the async workflow. To reduce waste:
- reuse
mediaIdwhen analyzing the same recording again - send idempotency keys on create and cancel operations
- prefer webhook completion over aggressive polling
- avoid duplicate submissions when retrying failures
Credit optimization strategies →