Skip to main content
The default application/json envelope is the right answer for almost every interactive call. Bulk reads, agent pipelines, and spreadsheet exports want different shapes. The platform negotiates four output encodings on read endpoints; pick the one that matches your reader by setting Accept or the format query parameter. By the end of this page you will know which encoding to ask for, what it looks like on the wire, and what trade-offs come with each.

The four formats

Asking for a format

Two equivalent ways. Both honor the same negotiation rules.
# Set the Accept header
curl https://api.gavai.app/v1/workspaces/acme/forms/frm_01H.../submissions \
  -H "Authorization: Bearer gak_live_..." \
  -H "Accept: application/x-ndjson"

# Or set the query parameter
curl "https://api.gavai.app/v1/workspaces/acme/forms/frm_01H.../submissions?format=ndjson" \
  -H "Authorization: Bearer gak_live_..."
The query parameter wins if both are set. If neither is set, the server returns application/json. Not every endpoint negotiates every format. Endpoints that return a single resource (GET /v1/workspaces/{slug}) only honor application/json; alternative formats are for endpoints that return a list. A request for a non-supported format on a single-resource endpoint returns 406 not_acceptable rather than silently falling back.

NDJSON: streaming bulk reads

Newline-delimited JSON: one record per line, no wrapping envelope, no trailing comma management. The response body is a stream — bytes start flowing before the server has materialized the whole result set.
{"id":"sub_01H...","submitted_at":"2026-05-09T09:22:11Z","data":{"email":"a@example.com"}}
{"id":"sub_01H...","submitted_at":"2026-05-09T09:22:14Z","data":{"email":"b@example.com"}}
{"id":"sub_01H...","submitted_at":"2026-05-09T09:22:18Z","data":{"email":"c@example.com"}}
Two practical notes:

CSV: spreadsheet exports

Flat columnar output, RFC 4180 quoting, UTF-8 with a BOM by default for Excel compatibility (suppress with ?bom=false). Nested fields are flattened with a dot-separated path:
id,submitted_at,data.email,data.name
sub_01H...,2026-05-09T09:22:11Z,a@example.com,Alex Kim
sub_01H...,2026-05-09T09:22:14Z,b@example.com,Bao Liu
Two constraints to know:

TSON: token-efficient for AI pipelines

TSON (Typed Structured Object Notation) is a compact encoding designed for passing structured data to language models. It encodes the same logical content as JSON but with materially fewer tokens — list a schema once, then reference fields positionally.
@schema[id submitted_at data.email data.name]
sub_01H... 2026-05-09T09:22:11Z a@example.com "Alex Kim"
sub_01H... 2026-05-09T09:22:14Z b@example.com "Bao Liu"
The first line declares the field schema; each subsequent line is a record, with fields in declared order. Strings without whitespace or special characters can be unquoted; quoting only triggers when ambiguity demands it. The format is lossy on schema metadata — a TSON record knows what its fields are called but not what their types are. Use TSON when: When the platform’s MCP servers expose a list endpoint to an AI client, they negotiate TSON automatically. You only request it explicitly when you are passing data to a model through your own pipeline.

Negotiation rules

Three rules apply across all formats.

Compression

All four formats negotiate gzip via Accept-Encoding: gzip and zstd via Accept-Encoding: zstd. Compression is recommended for bulk reads — NDJSON and TSON in particular compress well because their line shapes repeat. The platform applies compression only when the encoded body is over 4 KB; smaller responses are sent uncompressed regardless of negotiation.

Pagination

How cursors work across all four formats — and where each one carries the cursor.