Skip to main content

Core concepts

Understand the key concepts that shape the Conduit SDK experience.

Why async first?

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 source from mediaId, file, url, or path
  • 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​

StatusDescription
queuedWaiting to start
runningCurrently generating
succeededReport ready
failedSomething failed
canceledJob was canceled

Job stages​

StageDescription
uploadedSource upload completed
queuedAccepted and waiting
transcodingMedia preprocessing
extractingSpeaker extraction / targeting
scoringBehavioral scoring
renderingReport rendering
finalizingFinal 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)
Production tip

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​

FieldDescription
markdownMarkdown rendering when available
summaryShort summary text when available
sectionsStructured sections when available
metricsTemplate-dependent metrics when available
reportUrlHosted report URL when available

Templates​

TemplateUse for
general_reportGeneral behavioral analysis
sales_playbookSales-oriented guidance

See templates reference →


Speaker targeting​

Use target to pick the speaker you want analyzed.

StrategyUse when
dominantOne clear primary speaker
magic_hintYou know the role in natural language
entity_idYou already track the speaker across sessions
timerangeYou 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_id targeting
  • 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 mediaId when 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 →


What's next?​