Exports API

Create bulk data export jobs to download identities, events, or extraction records in JSON or CSV format. Exports run asynchronously and provide a download URL when complete.

Create an export

POST/v1/exports

Start a new export job. The export runs in the background — poll the status endpoint to check when the download is ready.

Request body

FieldTypeRequiredDescription
typestringYesData type to export: identities, events, or extractions
formatstringYesOutput format: json or csv
date_rangeobjectNoFilter by date range with start and end (ISO 8601)

curl

curl -X POST https://api.aidenid.com/v1/exports \
  -H "Authorization: Bearer aid_your_api_key" \
  -H "X-Org-Id: org_abc123" \
  -H "X-Project-Id: proj_def456" \
  -H "Idempotency-Key: <GENERATED_UNIQUE_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "identities",
    "format": "csv",
    "date_range": {
      "start": "2026-03-01T00:00:00Z",
      "end": "2026-04-01T00:00:00Z"
    }
  }'

Python

import requests

resp = requests.post(
    "https://api.aidenid.com/v1/exports",
    headers={
        "Authorization": "Bearer aid_your_api_key",
        "X-Org-Id": "org_abc123",
        "X-Project-Id": "proj_def456",
        "Idempotency-Key": "export-001",
    },
    json={
        "type": "identities",
        "format": "csv",
        "date_range": {
            "start": "2026-03-01T00:00:00Z",
            "end": "2026-04-01T00:00:00Z",
        },
    },
)
export = resp.json()
print(f"Export {export['id']} status: {export['status']}")

Response 201 Created

{
  "id": "exp_r1s2t3u4",
  "type": "identities",
  "format": "csv",
  "status": "pending",
  "date_range": {
    "start": "2026-03-01T00:00:00Z",
    "end": "2026-04-01T00:00:00Z"
  },
  "created_at": "2026-04-06T10:00:00Z"
}

Get export status

GET/v1/exports/{id}

Check the status of an export job. When the status is ready, the response includes a download_url with a time-limited signed URL.

curl

curl "https://api.aidenid.com/v1/exports/exp_r1s2t3u4" \
  -H "Authorization: Bearer aid_your_api_key" \
  -H "X-Org-Id: org_abc123" \
  -H "X-Project-Id: proj_def456"

Response — pending 200 OK

{
  "id": "exp_r1s2t3u4",
  "type": "identities",
  "format": "csv",
  "status": "processing",
  "progress_percent": 45,
  "created_at": "2026-04-06T10:00:00Z"
}

Response — ready 200 OK

{
  "id": "exp_r1s2t3u4",
  "type": "identities",
  "format": "csv",
  "status": "ready",
  "progress_percent": 100,
  "download_url": "https://exports.aidenid.com/exp_r1s2t3u4.csv?token=...",
  "download_expires_at": "2026-04-06T11:00:00Z",
  "row_count": 1247,
  "file_size_bytes": 89432,
  "created_at": "2026-04-06T10:00:00Z",
  "completed_at": "2026-04-06T10:02:15Z"
}

Response — failed 200 OK

{
  "id": "exp_r1s2t3u4",
  "type": "identities",
  "format": "csv",
  "status": "failed",
  "error": "Date range too large. Maximum range is 90 days.",
  "created_at": "2026-04-06T10:00:00Z"
}

Complete export flow

Create an export, poll until ready, then download the file.

TypeScript

const headers = {
  "Authorization": "Bearer aid_your_api_key",
  "X-Org-Id": "org_abc123",
  "X-Project-Id": "proj_def456",
};
const fetchWithTimeout = async (url: string, init: RequestInit = {}, timeoutMs = 10_000) => {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
  try {
    return await fetch(url, { ...init, signal: controller.signal });
  } finally {
    clearTimeout(timeout);
  }
};

// Create the export
const createRes = await fetchWithTimeout("https://api.aidenid.com/v1/exports", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": "export-002" },
  body: JSON.stringify({ type: "extractions", format: "json" }),
});
const { id } = await createRes.json();

// Poll until ready
let downloadUrl: string | undefined;
for (let i = 0; i < 30; i++) {
  const statusRes = await fetchWithTimeout(`https://api.aidenid.com/v1/exports/${id}`, { headers });
  const data = await statusRes.json();

  if (data.status === "ready") {
    downloadUrl = data.download_url;
    break;
  }
  if (data.status === "failed") {
    throw new Error(`Export failed: ${data.error}`);
  }

  await new Promise((r) => setTimeout(r, 5000));
}

if (downloadUrl) {
  console.log("Download:", downloadUrl);
}

Export statuses

StatusDescription
pendingExport job is queued and has not started processing
processingExport is actively being generated
readyExport is complete and the download URL is available
failedExport failed — check the error field for details
Download expiration

Download URLs are signed and expire after 1 hour. If the URL expires, query the export status endpoint again to get a fresh URL.

Error codes

CodeStatusDescription
export_not_found404Export job does not exist
invalid_export_type400Type must be one of: identities, events, extractions
invalid_format400Format must be one of: json, csv
date_range_too_large400Date range exceeds the maximum of 90 days
export_quota_exceeded429Too many concurrent export jobs
missing_idempotency_key400Mutation request missing Idempotency-Key header

Related