Akteora API docs

Exports

Get testimonials out in bulk: a spreadsheet for your team, data for your own systems, or the media files themselves.

format What you get
csv One row per testimonial, ready for Excel and Google Sheets
json Everything, complete, including the transcript's word timings, for developers
mp4 One video testimonial's processed video. The filters must match exactly one testimonial
mp3 One testimonial's voice, from a video or an audio recording. Exactly one
zip The recordings of every matching testimonial, with a manifest.csv

How an export runs

An export is a job, not a request: a hundred videos do not fit in one HTTP response.

1. Optionally, ask what it would contain. Nothing is counted against your plan.

curl -H "Authorization: Bearer $AKTEORA_API_KEY" -H 'content-type: application/json' \
  -d '{ "format": "csv", "filters": { "brand_id": "brd_…", "is_approved": true } }' \
  https://api.akteora.com/v1/exports/preview

The answer gives:

2. Start it.

curl -H "Authorization: Bearer $AKTEORA_API_KEY" -H 'content-type: application/json' \
  -d '{ "format": "csv", "filters": { "brand_id": "brd_…", "is_approved": true } }' \
  https://api.akteora.com/v1/exports

202 Accepted, with { "export_id": "…" }.

3. Wait for it. Fetch GET /v1/exports/{export_id}:

A ZIP bundle, or a list of more than 100 testimonials, also emails the person who started it when it is ready.

4. Download it. Once succeeded:

Filters

The same meanings as the testimonial list's filters. Testimonials the respondent has not sent yet are never exported.

Filter Meaning
ids An explicit selection, up to 1,000. The other filters narrow it further
brand_id, collect_link_id, tag_id Only this brand, link or tag
status processing, ready, failed or rejected
is_approved, is_public true or false
created_after, created_before RFC 3339. after is inclusive, before exclusive
q A search, as in the inbox

The CSV

UTF-8 with a byte-order mark, so Excel reads accents and non-Latin scripts correctly, and lines end in CRLF. One row per testimonial, in these columns:

Column
id The testimonial's id
created_at, updated_at RFC 3339, UTC
brand, brand_id, collect_link_id Where it came from
kind video, audio or text
status processing, ready, failed or rejected
respondent_name, respondent_email, respondent_title, respondent_company, respondent_country As the respondent gave them
rating 1 to 5, if asked
duration_seconds For a recording
text The testimonial's words, as the respondent approved them
text_source Where text came from: the respondent's original, or an ai_cleanup they chose before sending
transcript What was said, for a recording
tags Tags your team set, separated by ;
suggested_tags Themes suggested automatically, not yet accepted
approved, approved_at, public The moderation state
rejected_at, rejection_reason If rejected
public_media_url The permanent public link to the video or audio. See below
public_poster_url The permanent public link to its poster

public_media_url and public_poster_url are the same permanent addresses as public_media. They are set only for testimonials that are published (approved, public, processed, not rejected), and empty for everything else. They are safe to store, paste into a CMS, or hand to an agency. They are never signed links, because a spreadsheet outlives any signature. To get files for testimonials that are not published, export a zip.

Formula safety. Every cell was typed by someone on the internet, and Excel runs a cell that begins with =. A cell beginning with =, +, -, @, a tab or a carriage return is therefore prefixed with '. The JSON export keeps the exact characters.

The JSON

{
  "export_id": "…",
  "exported_at": "2026-09-13T10:00:00.000Z",
  "data": [
    {
      "id": "sub_…",
      "brand": { "id": "brd_…", "name": "Northwind" },
      "kind": "video",
      "respondent": { "name": "Maria López", "email": "…", "title": "…", "company": "…", "country": "ES" },
      "text": "…",
      "text_source": "original",
      "original_text": "…",
      "transcript": {
        "text": "Great team.",
        "language": "en",
        "words": [{ "word": "Great", "start_ms": 0, "end_ms": 300, "confidence": 0.9 }],
        "segments": [{ "text": "Great team.", "start_ms": 0, "end_ms": 700 }]
      },
      "tags": [{ "name": "case study", "source": "operator" }],
      "is_approved": true,
      "is_public": true,
      "public_media_url": "https://cdn.akteora.com/m/7kq2m9xwzr4tn8vbh3jp/video.mp4",
      "public_poster_url": "https://cdn.akteora.com/m/7kq2m9xwzr4tn8vbh3jp/poster.jpg",
      "consent": { "consent_text": "…", "consent_version": "v1", "agreed_at": "…" }
    }
  ]
}

It has the CSV's information and more:

The example above is abridged.

The ZIP bundle

A manifest.csv (the CSV above, plus a file column), and each testimonial's processed recording under media/, named after the respondent and the testimonial's id: media/maria-lopez-sub_….mp4, or .m4a for audio. It is streamed as it is built, so size is limited by your plan, not by memory.

Limits

Each plan allows a number of exports a month, testimonials per export, and recordings per ZIP. An export over a limit is refused before it starts, with 402 and a problem of type plan_limit_exceeded. Its limit member names:

A refused export does not count against the month.