Export conversations as signed IETF vCon containers
The IETF vCon working group is standardising a container for conversation data: parties, dialog, attachments, analysis, and a signature, all in one JSON document. Orbit adopts that container as its canonical conversation export envelope. One API call turns any conversation in your workspace into a standards-conformant file you can hand to another AI system, a carrier, or a compliance archive — and the recipient can verify it was never altered.Worked request
Export one conversation over the per-conversation vCon endpoint. Send your API key in theX-API-Key header (the request needs the conversations:read scope):
exported_at and the signed vCon container under vcon. This route deliberately returns { exported_at, vcon } rather than the generic { data, meta } wrapper other GETs use, so the signed container keeps a stable top-level field name in the artifact.
Content-Disposition response header names the download conversation-<id>-<date>.vcon.json. A 404 means no conversation with that id exists in your workspace; every export is recorded in your audit log.
Terminology squares
These pairs trip up callers when they cross-reference the route against the IETF draft and against Orbit’s other export surfaces — settle them once at the top:- vCon container vs. Orbit envelope. The container is the IETF document in the
vconfield (parties, dialog, attachments, analysis, signatures). The Orbit envelope is the outer JSON body (exported_at+vcon) the API returns — only the container is signed, not the date stamp. - Party index vs. conversation id. Dialog and analysis entries reference parties by their numeric
partyindex (0 = customer, 1 = your side). The per-exportuuidis a fresh public identifier for the artifact; it never equals the internalcnv_*id you called with, on purpose. - Dialog vs. attachment vs. analysis. Dialog carries the turn-by-turn transcript (text bodies and recording URLs, oldest first); attachments carry workspace metadata about the conversation as a whole (channel, status, tags, open/closed times); analysis is the reserved slot for caller-computed results (sentiment, summaries) and ships empty today.
- Signed vs. masked. Signing (the HMAC over the payload) is orthogonal to masking (the PII scan applied before signing). Every export is signed; an export is masked only when you turned on transcript PII redaction in your workspace privacy settings. The signature binds whichever bytes passed the scan.
- Export vs. archive export. This route exports one conversation as a signed container. The archive export is the bulk, unsigned CSV/JSON counterpart for filtered result sets — different identity, different guarantee.
- Hand a support thread to an external AI system that reads vCon directly, with the message order and party roles intact.
- Deliver a thread to a compliance archive as a tamper-evident artifact, not a spreadsheet anyone can edit.
- Prove to the recipient that the export came from your workspace — with your masking preferences already applied.
Why a signed container
A CSV row can be edited after the fact and no one can tell. A vCon is signed at export time, and the signature binds the exact bytes of the parties, dialog, attachments, and analysis sections. If a recipient changes so much as one character, the signature no longer verifies. The container also mints a fresh, tamper-evidentuuid per export, so the artifact is addressable without exposing the internal conversation id.
The export is read-only — it issues no outbound traffic of any kind.
Container anatomy
Verifying the signature
Orbit signs with a symmetric HMAC-SHA256 scheme labelledOrbit-HS256, using the same platform signing secret that protects your share links and CSAT tokens. This is an honest choice, not a shortcut: the platform’s keyring holds an HMAC secret rather than an Ed25519 keypair, so a symmetric scheme is what the signature genuinely is. The consequence to plan around: verification requires the shared secret, so the verifier is a party you have shared that secret with — it is not public-key verification anyone can run.
The signed surface covers the payload_b64 string itself, so stripping the signature from the file yields an invalid artifact rather than an “unsigned but valid” one. Verification also requires the signed payload’s uuid to match the container’s top-level uuid, which defeats a substitution attack that swaps in another validly-exported payload.
To verify by recompute:
payload_b64, compare it with signature, and then confirm the decoded payload’s uuid matches the container’s top-level uuid. Reject anything that fails either check. The same symmetric verification is available inside the platform for re-import; it never throws, so a tampered artifact simply returns false.
PII masking before signing
If you have turned on transcript PII redaction in your workspace privacy settings (pii_redaction_in_transcripts), the export applies the standard PII scan to every dialog body and to the party phone/email addresses before the signature is computed. The exported artifact never carries cleartext values you opted out of storing in transcripts.
Two consequences worth understanding:
- The signature binds the masked bytes, so a masked export verifies against what a recipient actually sees. There is no “cleartext version” of a masked export — masking is not a view.
- The flag fail-opens: if the setting cannot be read (for example a transient cache failure), the export proceeds unmasked, matching the default-off posture of the setting. If your archive requires masked exports, enable the setting before you export.
Import and handoff
A vCon is a complete handoff artifact: parties identify whose thread it is, dialog preserves the message order sender-by-sender, attachments carry the operational context (channel, status, tags), and the signature lets the recipient confirm none of it drifted in transit. Typical flows:- Compliance archive — export on a schedule or per request, push the file into your archive, and let the archive recompute the HMAC against the secret you provisioned there. A file whose signature fails is quarantined, not ingested.
- External AI system — hand the container to a vCon-aware system for case migration or second-opinion analysis. Party roles and the oldest-first dialog survive the move; the per-turn
metagives the receiving system channel and direction without a second lookup. - Carrier handoff — deliver the artifact with the shared secret out of band; the carrier verifies and can import the parties and dialog into their own tooling.
Limits to plan for
- One export per conversation. The endpoint exports a single thread; for bulk filtered exports, use the archive export.
- Two-party shape. Party 0 is the customer, party 1 is your side. The
party_historyextension for multi-party crates (contact moves between participants) is not used by this export. - Per-export identifiers. The
uuidis minted per export and is not the internal conversation id; treat the pair (uuid,created_at) as the artifact’s identity. - Transcript bound. The dialog covers up to 500 messages per conversation, oldest first after export.
- Version track. Exports follow the
"0.3.0"draft track of the IETF vCon container; expect the field to move forward as the draft matures.
See also
- Conversation archive — natural-language search plus bulk CSV/JSON export across channels
- Search message history — fielded single-message lookups by provider reference
- Identity resolution — how Orbit resolves the party addresses the export carries