The Post-Call Variables endpoints turn the extracted structured fields on workflow_runs.post_call_data into aggregate charts, health metrics, drill-downs, and CSV exports. They power the Extraction Variable charts and the Extraction Health panel on the analytics dashboard. All endpoints are GET, mounted under /api/v1/analytics/post-call-variables/, and scoped to the caller’s currently selected organization. Every requested workflow_id is validated against that organization — an id from another org returns 404 so existence is not leaked.
Authenticate with your PeachDesk API key:
An interactive session token (Authorization: Bearer …) also works — that is what the dashboard uses — but the API key is the credential for programmatic access. See Authentication.

Data pipeline

Where the numbers come from, at a glance:
  1. Workflow config — Each workflow defines a list of PostCallExtractionField entries (id, name, type, optional options, description, optional) under workflow_configurations.post_call_extraction.fields. The four supported types are boolean, selector, number, and text.
  2. Post-call LLM extraction — After a call ends, the extraction task runs an LLM over the transcript and produces a value per configured field. If extraction fails for a row, an error marker is written instead of a value.
  3. JSONB storage — The result lands on workflow_runs.post_call_data as { "model": "...", "data": { "<field_name>": <value>, ... }, "error"?: "..." }.
  4. Aggregation — These endpoints read post_call_data.data.<field_name> across the filtered window (date range, workflow ids, call attributes) and produce a shape appropriate for the field’s type.
There is no separate index on the JSONB payload in v1 — the filter window (date range + workflow ids) uses existing indexes, and the field lookup is applied per row within that window.

Endpoints

Schema

List the extraction fields defined on one or more workflows, plus the cross-workflow intersection when multiple ids are supplied.

Aggregate

Type-discriminated aggregation of a single field: boolean counts, selector option counts, number histogram + stats, or text top-N.

Health

Per-field null_pct and error_pct with a sparkline so extraction failures surface before they distort downstream charts.

Drill-down

Cursor-paginated list of the individual runs behind a bar, segment, or histogram bucket.

CSV export

Stream the raw extracted values for the current filter as a formula-injection-safe CSV.

Single vs. cross-workflow mode

Every endpoint takes workflow_ids as a comma-separated list. The mode is inferred from the length of that list:
  • Single (workflow_ids=42) — Operates on one workflow. /schema returns that workflow’s field list and no shared_fields. /aggregate and /drilldown accept any field defined on that workflow.
  • Cross (workflow_ids=42,43,44) — Intersects field names across all supplied workflows. A field is “shared” only if it exists on every workflow in the request. Types must also match; a field with the same name but different types on two workflows is dropped from the shared set. For selector fields the shared options list is the intersection of options across workflows.
/aggregate, /health, /drilldown, and /export.csv in cross mode operate on the union of the runs belonging to the requested workflows, keyed on the shared field name.

When to use cross-workflow

Charting qualified (boolean) across v1_qualifier and v2_qualifier workflow ids lets you compare qualification rate between two versions of the same script on a single chart.
us_intake, uk_intake, and au_intake share the same extraction schema. Cross-workflow mode gives you a single distribution of age_bracket (selector) across all three deployments.
Same schema, different prompts or voices. Cross-workflow mode aggregates the sentiment_after_ask (selector) result so you can see which variant produces more positive replies without merging the runs table.
Fleet-wide “qualified rate” across every intake workflow in the org, updated as new workflows are added — the aggregate re-uses the intersecting field name and simply widens as more workflows opt in.
Pair /health with the aggregate chart to catch silent extraction regressions. If error_pct or null_pct climbs on one workflow while the others stay flat, the aggregate number is misleading — the health row surfaces the drift before you act on the chart.

Field types and chart shapes

For every type, /aggregate and /health also return null_count and error_count so extraction failures are never silently folded into a chart’s headline number.

Call-attribute filters

Every endpoint except /schema accepts the same optional call-attribute filters, applied on top of the date range and workflow selection. They mirror the fields on the analytics RunFact: Combine any subset. All missing filters mean “no restriction on this attribute”.

Date range

from and to are ISO 8601 timestamps. When both are omitted, the default window is the last 30 days ending at the current time. An inverted range (from > to) returns 400.
  • /api/v1/organizations/usage/runs accepts post_call_field, post_call_value, and post_call_value_min / post_call_value_max so the drill-down URL emitted by the extraction charts loads the underlying runs — see List runs with usage.