# Asynchronous Exports

Asynchronous exports create a background job and return a downloadable file when processing is complete. Use this flow for historical event data, larger date ranges, or file-based ingestion.

Async exports support Smart Strength workouts, Smart Strength assessments, body measurements, and flexibility measurements.

Async exports can go back up to one year. Requests cannot include event data older than one year, and each export job can cover at most 365 days.

Event exports require member opt-in
Async event exports only include records for members who have opted in to health data and consumer-to-business (C2B) sharing. Records for members without this opt-in are excluded, so an export file may contain fewer rows than the total number of events at the gym.

Every user-related record includes `externalAccountId`, a unique and stable identifier for the member's account. Store this ID alongside the data you ingest from each export file so you can reconcile records across exports and delete a specific member's data later if needed (for example, when they opt out).

## Create an export job

```http
POST /api/v1/data/async
x-api-key: <api-key>
Content-Type: application/json
```

```json
{
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "exportType": "SMART_STRENGTH_WORKOUTS",
  "fileType": "JSONL"
}
```

The API returns the job ID and the initial status.

```json
{
  "jobId": "9f8a7c55-2d2f-4f3b-8a7b-5a32799116a4",
  "status": "IN_PROGRESS"
}
```

## Request fields

| Field | Required | Description |
|  --- | --- | --- |
| `startDate` | Yes | Start date in `YYYY-MM-DD` format. Must not be older than one year. |
| `endDate` | Yes | End date in `YYYY-MM-DD` format. The requested period cannot exceed 365 days or include data older than one year. |
| `exportType` | Yes | Data set to export. |
| `fileType` | No | Output format. Defaults to `JSONL`. |


`startDate` and `endDate` are interpreted as UTC calendar days, and timestamp fields in the exported records (such as `eventTimestamp`) are returned in UTC.

Supported `exportType` values:

- `SMART_STRENGTH_WORKOUTS`
- `SMART_STRENGTH_ASSESSMENTS`
- `FLEXIBILITY_MEASUREMENTS`
- `BODY_MEASUREMENTS`


Supported `fileType` values:

- `JSONL`: one JSON object per line
- `JSON`: JSON array
- `CSV`: comma-separated values with a header row


## Check job status

```http
GET /api/v1/data/async/jobs/9f8a7c55-2d2f-4f3b-8a7b-5a32799116a4
x-api-key: <api-key>
```

```json
{
  "status": "DONE",
  "downloadURL": "https://storage.googleapis.com/..."
}
```

The `downloadURL` field is only present when the job status is `DONE`. It is a signed URL that expires two hours after the job completes. Download the file within that window. If the URL has expired, the job status changes to `EXPIRED`; create a new export job to obtain a fresh `downloadURL`.

## Job statuses

| Status | Meaning |
|  --- | --- |
| `IN_PROGRESS` | The export job was accepted and is still processing. |
| `DONE` | The export file is ready and `downloadURL` is present. |
| `FAILED` | The export job failed. Retry the request or contact support if the issue persists. |
| `EXPIRED` | The export finished previously, but the signed download URL has expired two hours after completion. Create a new job if the file is still needed. |


## File contents

JSON and JSONL files contain the same item objects as the synchronous response `data` arrays. CSV files contain a header row followed by the same fields in column form. The [API Reference](/data-hub/api) lists the fields for each export type.