POST /v1/brands/{brand_id}/exports

Export a brand's history

Start an export of the brand's whole citation and answer history (or the window and reports the filters name) into downloadable files, and return it at once (202 Accepted, with its URL in Location). Use this instead of paging GET .../citations, .../citations/pages or .../prompts/answers through a brand's history: the export reads it in the background, in batches that never compete with live reads.

Workflow:

  1. POST /v1/brands/{brand_id}/exports: returns the export, status: queued.
  2. GET /v1/brands/{brand_id}/exports/{export_id}: poll every few seconds until status is completed; progress_pct says how far it got.
  3. Download each results[].files[].url before links_expire_at (15 minutes); read the export again for fresh links. The files are deleted 24 hours after the export completes.

Each file is gzipped NDJSON, one JSON object per line, oldest answer first. A citations line is one URL one answer cited: answer_id, created_at, platform, position, url, domain, title, prompt_text, prompt_hash, category (the prompt's category in that run), report_id and scheduled_report_id. An answers line is one engine answer: id, created_at, platform, model_version, prompt_text, prompt_hash, category, brand_appears, rank, response (the full text), businesses_categorized, citation_count, report_id, report_name and scheduled_report_id. Only answers of completed reports count.

Filters compose with AND and mirror the list endpoints: report_id (several), scheduled_report_id, platform (several), date_from and date_to. datasets defaults to both.

One export per brand runs at a time for a caller: asking again with the same body returns the one running (or resumes a failed one where it stopped), and a different body while one runs is 409 conflict with its export_id. The citations dataset also needs the read:citations scope. Free: no credits.

Path parameters

Query parameters

  • dry_run boolean optional

    Preview the call without executing it. Runs auth, scope, eligibility and body validation, then returns 200 with a dry_run object reporting the request-unit and credit cost plus a non-consuming quota snapshot. Nothing is debited, reserved, dispatched or mutated. An invalid body still returns 422.

    default: false

Header parameters

  • Idempotency-Key string required

    Required with an API key, else 400 idempotency_key_required: a new value per operation (a UUID works). A retry with the same key and body within 24 hours replays the first response instead of running again. Ignored with dry_run=true.

Request body

application/json required
Type: CreateDataExportRequest
  • datasets array of enum

    citations: one row per cited URL per answer. answers: one row per engine answer, full text included. Default both.

    min items: 1 · max items: 2

  • date_from string (nullable) nullable

    Only answers from this moment on (ISO-8601).

  • date_to string (nullable) nullable

    Only answers before this moment, exclusive (ISO-8601).

  • platform array of enum (nullable) nullable

    Only answers from these engines.

  • report_id array of string (nullable) nullable

    Only these reports (UUIDs).

  • scheduled_report_id string (nullable) nullable

    Only the runs of this Scheduled Report.

Example payload
{
  "datasets": [
    "citations",
    "answers"
  ],
  "date_from": "2026-07-01T00:00:00Z"
}

Responses

Export queued, or the same export already running. application/json
Type: DataExport
  • brand_id string required

    The brand exported.

  • byte_count integer required

    Gzipped bytes written across files.

    min: 0

  • created_at string required

    format: `date-time`

  • datasets array of enum required

    The datasets asked for.

  • filters DataExportFilters required

    The filters the export applies, normalized: ids lowercased and sorted, instants in UTC.

    Show fields
    Type: DataExportFilters
    • date_from string (nullable) nullable

      Only answers from this moment on.

      format: `date-time`

    • date_to string (nullable) nullable

      Only answers before this moment, exclusive.

      format: `date-time`

    • platform array of string (nullable) nullable

      Only answers from these engines.

    • report_id array of string (nullable) nullable

      Only these reports.

    • scheduled_report_id string (nullable) nullable

      Only the runs of this Scheduled Report.

  • id string required

    Export id.

  • progress_pct integer required

    How far the export got, by the time span read so far.

    min: 0 · max: 100

  • results array of DataExportResult required

    One entry per dataset asked for.

  • row_count integer required

    Rows written across datasets.

    min: 0

  • status enum required

    queued, running, completed (files ready), failed (ask again with the same body to resume where it stopped) or expired (files deleted 24 hours after completing).

  • completed_at string (nullable) nullable

    format: `date-time`

  • Every file is gzipped.

    default: `gzip`

  • error string (nullable) nullable

    Why the export failed, when it did.

  • expires_at string (nullable) nullable

    When the files are deleted.

    format: `date-time`

  • format string

    One JSON object per line.

    default: `ndjson`

  • object string

    default: `data_export`

  • started_at string (nullable) nullable

    format: `date-time`

Example response
{
  "brand_id": "5ddd550e-10e0-50ea-80c8-2058f75229d3",
  "byte_count": 41943040,
  "completed_at": "2026-10-07T13:59:40+00:00",
  "compression": "gzip",
  "created_at": "2026-10-07T13:58:02+00:00",
  "datasets": [
    "citations",
    "answers"
  ],
  "expires_at": "2026-10-08T13:59:40+00:00",
  "filters": {
    "date_from": "2026-07-01T00:00:00+00:00"
  },
  "format": "ndjson",
  "id": "3f1c2b8e-6a0d-4c1e-9d2f-7b5a4e3c2d10",
  "links_expire_at": "2026-10-07T14:15:00+00:00",
  "object": "data_export",
  "progress_pct": 100,
  "results": [
    {
      "dataset": "citations",
      "done": true,
      "files": [
        {
          "bytes": 23068672,
          "rows": 653453,
          "url": "/storage/v1/object/sign/data-exports/.../citations-0001.ndjson.gz?token=..."
        }
      ],
      "rows": 653453
    },
    {
      "dataset": "answers",
      "done": true,
      "files": [
        {
          "bytes": 18874368,
          "rows": 111606,
          "url": "/storage/v1/object/sign/data-exports/.../answers-0001.ndjson.gz?token=..."
        }
      ],
      "rows": 111606
    }
  ],
  "row_count": 765059,
  "started_at": "2026-10-07T13:58:03+00:00",
  "status": "completed"
}
Request validation failed application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Missing or invalid credentials application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid credentials"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
You do not have permission to access this resource application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "forbidden",
    "message": "You do not have permission to access this resource"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Resource not found application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "not_found",
    "message": "Resource not found"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Resource conflict application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "conflict",
    "message": "Resource conflict"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Request body did not match the expected schema application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "body_validation_error",
    "message": "Request body did not match the expected schema"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Per-minute rate limit exceeded application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Per-minute rate limit exceeded"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
An unexpected error occurred application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Service temporarily unavailable, please retry application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "service_unavailable",
    "message": "Service temporarily unavailable, please retry"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}