> ## Documentation Index
> Fetch the complete documentation index at: https://docs.userpilot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bulk Data Export API

> This feature is available on the Enterprise plan only or as an add-on to the Growth plan. If interested in adding this feature please contact.

<Note>
  This feature is available on the Enterprise plan only or as an add-on to the
  Growth plan. If interested in adding this feature please contact
  [support@userpilot.com](mailto:support@userpilot.com).
</Note>

The **Userpilot Export Analytics Data API** allows you to export analytics data from Userpilot, enabling you to analyze user behavior, engagement, and more. You can filter the data by date range, user, company, event type, and additional parameters. The API supports exporting data in JSON or CSV formats.

***

## Authorization

Userpilot API uses an API key to authenticate requests. You can find your API key on the [Environment Page](https://run.userpilot.io/environment).

**Authentication Method:**

Include your API key in the `Authorization` header:

```http theme={null}
Authorization: Token {{API_KEY}}
```

<Note>All API requests must be made over HTTPS.</Note>

<Warning>
  Your API key carries many privileges, so be sure to keep it secure! Do not
  share your secret API keys in publicly accessible areas.
</Warning>

***

## Rate Limits

The Export API enforces rate limiting to ensure reliable data export operations and maintain system performance for all users. These limits help balance resource usage while enabling comprehensive analytics data retrieval.

### Rate Limit Details

* **Job Limitation**: **One export job at a time** per application token

### Error Responses

The API returns specific error codes when limits are exceeded:

* **`409 Conflict`**: Returned when attempting to create a new export job while another is in progress

### Best Practices

<Tip>
  **Verify Job Status**: Always check for existing export jobs before initiating a new one to avoid conflicts.

  **Handle Conflicts Gracefully**: When encountering a 409 Conflict error, wait for the current job to complete before retrying.

  **Track Export Progress**: Use job status endpoints to monitor export completion and download files promptly.

  **Optimize Export Requests**: Use specific date ranges and filters to reduce data volume and improve performance.
</Tip>

***

## Data Restrictions

* **Job Status Availability:** Once an export job is created, the job status and related information will be available for **3 days**. After this period, the job status will no longer be accessible via the API.
* **File Download Expiry:** The URLs generated to download the exported data files will expire after **2 days**. Ensure you download the files within this time frame, as the links will no longer be valid afterward.

<Tip>
  Providing a valid email address in the request is recommended. You'll receive
  a notification with download links when the export is ready, eliminating the
  need to manually check job status.
</Tip>

***

<Note>
  For the schema of exported events and data, see the [Event
  Schema](./event-schema) page.
</Note>

<Tip>
  For details on available lookup endpoints and how to use them, see the [Data
  Lookups](./lookups) page.
</Tip>

## Data Schema Reference

The data exported via the Userpilot Export Analytics Data API follows the Userpilot [Event Data Schema](./event-schema). This schema defines the structure, attributes, and relationships of all events, users, and companies included in your export.

**Key points:**

* Each exported event will include fields such as `app_token`, `event_type`, `event_name`, `user_id`, `company_id`, `source`, `inserted_at`, and more.
* Auto-captured attributes (e.g., `hostname`, `device_type`, `browser`, etc.) and custom attributes (in the metadata object) are included as described in the schema.
* The schema covers all event types (`identify_user`, `identify_company`, `track`, `track_feature`, `page_view`, `interaction`, `session_start`, etc.) and their specific attribute structures.

<Warning>
  Your exported data may include new or additional fields as the schema evolves.
  Please ensure your data processing pipelines can handle unexpected fields
  gracefully.
</Warning>

***

## API Endpoints

### 1. Trigger an Export Job

#### Endpoint

```http theme={null}
POST https://appex.userpilot.io/api/v1/analytics/exports
```

#### Description

Creates an export job to extract analytics data based on the specified parameters.

#### Parameters

| Parameter    | Type       | Required | Description                                                                         | Example                                          |
| ------------ | ---------- | -------- | ----------------------------------------------------------------------------------- | ------------------------------------------------ |
| `from`       | `string`   | Yes      | Start date of the export in `YYYY-MM-DD` format.                                    | "2024-05-02"                                     |
| `to`         | `string`   | Yes      | End date of the export in `YYYY-MM-DD` format.                                      | "2024-09-30"                                     |
| `emails`     | `string[]` | No       | List of email addresses to receive the exported data. If omitted, no email is sent. | \["[example@work.com](mailto:example@work.com)"] |
| `event_type` | `string[]` | No       | List of event types to filter. Defaults: see below.                                 | \["track", "page\_view"]                         |
| `user_id`    | `string[]` | No       | Specific user IDs to filter. If omitted, all users are included.                    | \["123456"]                                      |
| `company_id` | `string[]` | No       | Specific company IDs to filter. If omitted, all companies are included.             | \["13162551529"]                                 |
| `segment_id` | `string`   | No       | Filter data based on a specific segment.                                            | "987654"                                         |
| `format`     | `string`   | No       | Format of the exported data. Options: `json` (default) or `csv`.                    | "csv"                                            |
| `exclusions` | `boolean`  | No       | Exclude users/companies set in the web app. Default: `false`.                       | true                                             |

**Default values:**

* `event_type` defaults to `["identify_user", "identify_company", "page_view", "track", "track_feature", "interaction", "session_start"]` if not provided.
* `user_id` and `company_id` default to empty arrays (`[]`), meaning all users or companies are included by default.
* The default export `format` is `json`.

#### Example Request

```bash theme={null}
curl --location 'https://appex.userpilot.io/api/v1/analytics/exports' \
--header 'Authorization: Token {{API_KEY}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "from": "2024-05-02",
    "to": "2024-09-30",
    "emails": ["example@work.com"],
    "event_type": ["identify_user", "identify_company", "page_view", "track"],
    "user_id": ["user_1"],
    "company_id": ["comp_2"],
    "segment_id": "9",
    "format": "csv",
    "exclusions": true
}'
```

<Tabs>
  <Tab title="Success">
    ```json theme={null}
    {
      "environment_app_token": "NX-51f4acf7",
      "environment_name": "production",
      "job_id": "86f4dd75-00c8-40cd-ac6a-3dce8440be0c",
      "links": "/api/v1/analytics/exports/jobs/86f4dd75-00c8-40cd-ac6a-3dce8440be0c",
      "start_time": "2024-10-06T10:44:50.999504"
    }
    ```
  </Tab>

  <Tab title="409 Conflict">
    ```json theme={null}
    {
        "errors": [
            {
                "details": "There is already an export job in progress, you can only have one export job in progress at a time.",
                "error": "Conflict",
                "error_code": "409",
                "message": "The request could not be completed due to a conflict with the current state of the target resource."
            }
        ]
    }
    ```
  </Tab>

  <Tab title="401 Unauthorized">
    ```json theme={null}
    {
        "errors": [
            {
                "details": "Your current plan for application NX-d7ce194a does not support the feature you are trying to access.",
                "error": "Unauthorized",
                "error_code": "401",
                "message": "You are not authorized to perform the requested action."
            }
        ]
    }
    ```
  </Tab>
</Tabs>

***

### 2. Show Jobs

#### Endpoint

```http theme={null}
GET https://appex.userpilot.io/api/v1/analytics/exports/jobs
```

#### Description

Retrieves a list of all export jobs triggered by your API token.

#### Example Request

```bash theme={null}
curl --location 'https://appex.userpilot.io/api/v1/analytics/exports/jobs' \
--header 'Authorization: Token {{API_KEY}}'
```

<Tabs>
  <Tab title="Success">
    ```json theme={null}
    [
      {
        "elapsed_time": "44 seconds",
        "elapsed_time_seconds": 44,
        "end_time": "2024-09-22T11:20:58.006463Z",
        "job_id": "af257e48-c145-40aa-996c-dad64839acb1",
        "progress": "5 out of 5 partitions",
        "start_time": "2024-09-22T11:20:14.731634",
        "status": "completed"
      }
    ]
    ```
  </Tab>
</Tabs>

***

### 3. Show Job by Job ID

#### Endpoint

```http theme={null}
GET https://appex.userpilot.io/api/v1/analytics/exports/jobs/{job_id}
```

#### Description

Retrieves detailed information about a specific export job identified by its `job_id`.

#### Path Parameters

| Parameter | Type   | Required | Description                             |
| --------- | ------ | -------- | --------------------------------------- |
| job\_id   | String | Yes      | The unique identifier of the export job |

#### Example Request

```bash theme={null}
curl --location 'https://appex.userpilot.io/api/v1/analytics/exports/jobs/{job_id}' \
--header 'Authorization: Token {{API_KEY}}'
```

<Tabs>
  <Tab title="Success">
    ```json theme={null}
    {
      "app_token": "<YOUR-APP-TOKEN>",
      "completed_chunks": ["2024-05-01", "2024-06-01"],
      "current_chunk": "2024-09-01",
      "end_time": "2024-09-22T13:18:11.558646Z",
      "job_id": "664314e1-ee60-48eb-a36a-5f38f4c524f1",
      "presigned_urls": [
        {"filename": "2024-07-29.json.gz", "url": "https://..."}
      ],
      "progress": "2 out of 5 partitions",
      "start_time": "2024-09-22T13:17:26.864860Z",
      "status": "completed",
      "all_chunks": ["2024-05-01", "2024-06-01"],
      "type": "export"
    }
    ```
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    {
        "errors": [
            {
                "details": null,
                "error": "Resource not found",
                "error_code": "404",
                "message": "Failed to retrieve job with id ...: job not found"
            }
        ]
    }
    ```
  </Tab>
</Tabs>

<Note>
  * Ensure you retrieve job details within the **3-day** availability window to
    effectively monitor ongoing jobs. - Download links for exported data will
    expire after **2 days**, so make sure to download your data promptly.
</Note>

***

## Understanding File Names and Date Ranges

The Export API partitions data into files by weeks to avoid oversized files. It's important to understand how file names relate to the data they contain.

### File Naming Convention

* **Weekly Partitioning:** Each file represents a weekly partition of data
* **File Name Format:** Each weekly file's name is the date representing the **start of the week (Monday)** in `YYYY-MM-DD` format
* **Data Filtering:** The file name does **not** indicate that the file contains all data from that entire week. The data within each file is still restricted to your requested date range filter

### Example Scenario

If you request data for the date range **November 30, 2025 → December 2, 2025**, you may receive files with names that appear outside this range:

* **File: `2025-11-24.json.gz`**
  * November 30, 2025 belongs to the week starting November 24, 2025 (Monday)
  * This file contains data for **November 30, 2025 only** (matching your filter)
  * The file name reflects the week start date, not the actual data range

* **File: `2025-12-01.json.gz`**
  * December 2, 2025 belongs to the week starting December 1, 2025 (Monday)
  * This file contains data for **December 1, 2025 and December 2, 2025** (matching your filter)
  * Again, the file name reflects the week start date

### Key Points

* File names represent the **week start date (Monday)** for organizational purposes
* The actual data in each file is **filtered to your requested date range**
* You may see file names with dates outside your requested range, but the data inside will only include events within your specified `from` and `to` dates
* This partitioning approach helps manage file sizes while maintaining efficient data retrieval

***

## Contact Support

If you have any questions or need further assistance, please contact our support team at [support@userpilot.com](mailto:support@userpilot.com).
