read) is enough (legacy exports/interviews keys keep working).
Protected raw-corpus export is a separate, more restrictive workflow described below.
The examples use the US API host. For a workspace on
eu.ontora.com, replace
https://api.ontora.com with https://api.eu.ontora.com.Use a workspace API key for these endpoints. Vault retrieval keys only work with the
/v1/retrieval endpoints and cannot export campaign transcripts or reports.A single transcript
All transcripts as a ZIP
.md file per completed conversation, named by contact.
Dashboard summary
A short Markdown summary of the campaign — useful for embedding in PR descriptions, Notion pages, or status updates.Full synthesis report
The full report is a single long-form Markdown document — ready to send to a stakeholder. It carries the executive narrative (headline, study goals, key findings, who you talked to), the per-question breakdown with response distributions and supporting quotes, findings raised outside the interview guide, and the implications. It is the same report the campaign’s report page shows.CLI shortcuts
Protected complete-corpus export
When a specifically authorized agent must read every protected interview in full, a workspace admin can issue a short-lived Confidential analysis key that combines read-only workspace access with a grant bound to exactly one campaign. Ordinary read/full-access/wildcard keys cannot use this endpoint.response_id, plus completion/release policy and canonical content hashes. Its
scope is completed_or_contentful_conversations; completed empty responses remain visible while
unfinished responses without content do not pretend to be analyzable records. The export contains the
complete available campaign-guide fields, raw response text, structured choice metadata when captured,
and transcript turns with minimal preprocessing. Follow each field’s question_type; the export does
not turn open-ended fields into closed-choice answers. Name, email, person id, contact id,
conversation id, and person-profile seniority_level metadata are absent from the record contract. Campaign-specific
answers such as Q1 and Q2 remain in questions and the transcript. Job title and department appear only when
participant_metadata_output_allowed is true on an eligible raw-citable record. Each field’s
metadata_sources value records whether it came from the stored campaign contact or its linked person;
contact_metadata_source is mixed when the two fields differ. audience_filter_attributes contains
only the raw Personio workgroup1, workgroup2, and workgroup3 values that exist for the linked,
non-anonymous participant; Ontora does not rename, map, or derive them. These analysis dimensions may
appear on raw_citable and named, transcript-hidden aggregate_only records. Anonymous-citable,
name-hidden, report-only, and contactless records use an empty object. For aggregate_only, use
workgroups only for non-reconstructable group analysis, never
as an individual attribution.
The manifest caps a corpus at 500 records, advertises its turn/record/export byte bounds, and binds its
guide aliases with guide_hash. Each record reports question_mapping_status; records with gaps list the
exact unmapped_response_turn_indexes, which must not be guessed into a nearby question. Transcript
turns keep both source_question_id (stored provenance) and resolved question_id/question_key, plus
question_mapping_source. Each question summarizes this evidence in mapping_source_counts and
mapping_conflict_turn_indexes, while structured_answer_present states whether a choice or component
payload was captured. The record-level question_mapping_conflict_turn_indexes identifies stale or
inconsistent source question/topic metadata; use the resolved Q mapping while preserving the conflict
for audit.
The CLI verifies the manifest hash, every record hash, uniqueness and exact record count, and an
unchanged post-download manifest before staging both files with mode 0600. It atomically renames the
JSONL first and the sidecar last. The pair itself is not transactionally atomic: the sidecar is the
completion marker, and the CLI removes an old marker before replacing the JSONL. After interruption or
a filesystem error, use the export only if both files exist and the sidecar’s ndjson_hash matches the
JSONL; otherwise rerun the command. Validation failures happen before installation and leave an existing
pair untouched.
The client enforces a five-minute elapsed-time guard (in addition to HTTP operation timeouts) and
rejects a body over the manifest’s server-enforced bound (currently 128 MiB). For one-record workflows,
ontora corpus get requires --output and never writes protected record JSON to stdout.
Protected REST contract
The CLI uses these exact API-key-authenticated routes:application/x-ndjson and returns
X-Ontora-Corpus-Manifest-Hash, X-Ontora-Corpus-NDJSON-Hash, and
X-Ontora-Corpus-Record-Count. Direct curl does not perform the CLI’s cross-record, post-download,
or sidecar checks; prefer the CLI for a durable snapshot.
This is a trusted-processor restriction rather than post-download technical enforcement. Store and
process the files only in an approved environment; Ontora cannot control output after another process
has read the raw corpus.
When the report isn’t ready yet
If you call the export endpoints before synthesis has completed, you’ll get a409 Conflict with a synthesis_pending error. Subscribe to synthesis.completed instead of polling.