For the complete documentation index, see llms.txt. This page is also available as Markdown.

πŸ“šExtensions Cookbook

Worked examples for the extensions adapters use most β€” WTF transcription, lawful basis, SIP signaling, agent session.

The vCon core spec is intentionally small. Most of what adapters actually care about β€” transcripts, recording consent, SIP signaling provenance, AI-agent session tracking β€” lives in extensions. This page is a recipe book for the four extensions adapters use in practice.

Each recipe shows the exact vcon library call, the resulting JSON shape, and links to the corresponding extension page for the full spec.

Spec target: draft-ietf-vcon-vcon-core-02, syntax "0.4.0". Library: vcon β‰₯0.9.4.


WTF Transcription

πŸ“„ Spec: WTF Transcription Extension Β· draft-howe-vcon-wtf-extension Β· Extension name: "wtf" (older code uses "wtf_transcription")

Use WTF when your adapter calls a speech-to-text provider β€” Whisper, Deepgram, AssemblyAI, ElevenLabs, AWS, Azure, Google. The point is that downstream tooling shouldn't have to special-case each provider's output.

Transcripts go in analysis[], not attachments[]. They're derived data, not supplied data.

Recipe

import json
from foo_adapter.vcon_builder import new_vcon

v = new_vcon(subject="Sales call", extensions=["wtf"])
v.add_party(tel="+15555550100", role="caller")
v.add_party(tel="+15555550200", role="agent")
v.add_dialog(
    type="recording",
    start="2026-05-19T14:32:00Z",
    parties=[0, 1],
    url="https://recordings.example/abc.wav",
    content_hash="sha512-...",
    mediatype="audio/wav",
)

wtf_document = {
    "transcript": {"text": "Hello, this is Foo Corp..."},
    "segments": [
        {"start": 0.0, "end": 2.3, "speaker": 0, "text": "Hello, this is Foo Corp."},
        {"start": 2.3, "end": 5.1, "speaker": 1, "text": "Hi, I'm calling about my account."},
    ],
    "language": "en-US",
}

v.add_analysis(
    type="transcript",
    dialog=0,
    vendor="openai-whisper",
    product="whisper-large-v3",
    body=json.dumps(wtf_document),
    encoding="json",
    schema="https://datatracker.ietf.org/doc/draft-howe-vcon-wtf-extension/",
)

Resulting analysis[] entry

Common mistakes

  • ❌ Putting the transcript in attachments[] instead of analysis[]

  • ❌ Storing the WTF document as a Python dict in body β€” body is always a string, paired with encoding="json"

  • ❌ Adding a separate plain-text transcript analysis β€” the WTF document already carries transcript.text

  • ❌ Forgetting vendor (the library will raise TypeError)

  • ❌ Writing schema_version instead of schema


βš–οΈ Spec: Lawful Basis Extension Β· draft-howe-vcon-lawful-basis Β· Extension name: "lawful_basis"

Use this when your adapter handles conversations covered by GDPR, CCPA, HIPAA, TCPA, state-by-state recording consent laws, or when you're generating synthetic data for which you want auditable origin tracking.

Critical exception: the lawful_basis attachment is the one place where attachments use type instead of purpose. This is documented in the spec.

Recipe β€” consent-based (GDPR Article 6(1)(a))

The library's add_lawful_basis_attachment helper requires model objects for purpose_grants and proof_mechanisms. For most adapters it's easier to build the attachment dict directly and append it:

Recipe β€” synthetic data

When generating synthetic conversations (test fixtures, training data, demos), document the synthetic origin rather than forging a real consent record:

Also mark each synthetic party with validation: "synthetic". See the synthetic data section of the compliance checklist.

Common mistakes

  • ❌ Using purpose: "lawful_basis" instead of type: "lawful_basis" β€” this attachment is the one core spec exception

  • ❌ Inventing an ad-hoc synthetic_data_consent attachment shape instead of using lawful_basis with legitimate_interests + external_system proof

  • ❌ Omitting "lawful_basis" from top-level extensions[]

  • ❌ Treating expiration as optional for consent-based grounds β€” GDPR consent without an expiry is brittle


SIP Signaling

πŸ“ž Spec: SIP Signaling Extension Β· draft-howe-vcon-sip-signaling Β· Extension name: "sip-signaling"

Use this when your adapter handles telephony β€” SignalWire, Twilio, Sippy, SIPREC streams, FreeSWITCH. The extension records the SIP-level facts (Call-ID, From/To URIs, P-Asserted-Identity, SDP fingerprints, signaling timestamps) that don't fit cleanly into a generic vCon party/dialog shape.

Recipe

Note this uses purpose=, not type= β€” SIP signaling follows the standard core attachment shape (only lawful_basis is the exception).


Agent Session

πŸ€– Spec: Agent Session Extension Β· draft-howe-vcon-agent-session Β· Extension name: "agent_session"

Use this when your adapter handles AI-agent conversations β€” Claude AI exports, LLM tool-use traces, voice-agent sessions. The extension carries the session-level facts the core spec doesn't model: model identity, tool invocations, system-prompt fingerprints, token counts.

Recipe

The vcon-anthropic-chats adapter is a reference implementation if you're building an LLM-export adapter.


Combining extensions

Most production adapters combine three or more. A contact-center adapter typically ships SIP signaling + WTF + lawful basis on every vCon. A voice-AI adapter combines agent session + WTF + lawful basis. Just list every extension you emit in the top-level extensions[]:

There's no ordering constraint and no limit. List them all, then add the corresponding attachments and analyses below.

Where to read the actual specs

When you need authoritative answers, read the drafts β€” not this cookbook:

Last updated

Was this helpful?