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

# Export analytics data

> Retrieve a pre-signed download URL, wait for the file to be ready, and download the result.

<Warning>
  Data files expire after 7 days. Download them as soon as the pre-signed URL is
  ready.
</Warning>

## Export flow

<Steps>
  <Step title="Call the Data API" icon="send">
    Send a `GET` request to `https://portal.webless.ai/query-data` with:

    * `company`
    * `start_date`
    * `end_date`
    * `x-api-key` in the request headers
  </Step>

  <Step title="Store the pre-signed URL" icon="link">
    A successful request returns `202 Accepted` and a `presigned_url`. That URL
    becomes valid once the export file is written.
  </Step>

  <Step title="Poll until the file is ready" icon="timer">
    Poll the `presigned_url` every 10 seconds with the `Range: bytes=0-0`
    header. Stop polling when the response returns `200 OK` or
    `206 Partial Content`.
  </Step>

  <Step title="Download the full file" icon="download">
    Reuse the same pre-signed URL to download the completed file.
  </Step>
</Steps>

## Request parameters

| Parameter    | Required | Format       | Description                        |
| ------------ | -------- | ------------ | ---------------------------------- |
| `company`    | Yes      | `string`     | Your client code                   |
| `start_date` | Yes      | `YYYY-MM-DD` | Start of the date range, inclusive |
| `end_date`   | Yes      | `YYYY-MM-DD` | End of the date range, inclusive   |

## Example request

```http theme={null}
GET https://portal.webless.ai/query-data?company=webless&start_date=2025-07-01&end_date=2025-07-03
x-api-key: YOUR_API_KEY
```

## Example response

```json theme={null}
{
  "presigned_url": "https://webless-client-data.s3.us-west-1.amazonaws.com/athena-results/<QUERY_ID>.csv?X-Amz-..."
}
```

## Sample code

<CodeGroup>
  ```python export_data.py theme={null}
  import time
  import requests

  API_KEY = "YOUR_API_KEY"
  API_URL = "https://portal.webless.ai/query-data"

  response = requests.get(
      API_URL,
      params={
          "company": "webless",
          "start_date": "2025-07-01",
          "end_date": "2025-07-03",
      },
      headers={"x-api-key": API_KEY},
      timeout=30,
  )
  response.raise_for_status()
  url = response.json()["presigned_url"]

  while True:
      probe = requests.get(url, headers={"Range": "bytes=0-0"})
      if probe.status_code in (200, 206):
          break
      time.sleep(10)

  download = requests.get(url, stream=True)
  download.raise_for_status()

  with open("webless_results.csv", "wb") as outfile:
      for chunk in download.iter_content(8192):
          outfile.write(chunk)
  ```

  ```javascript export-data.js theme={null}
  const axios = require("axios");
  const fs = require("fs");

  const API_URL = "https://portal.webless.ai/query-data";

  (async () => {
    const trigger = await axios.get(API_URL, {
      params: {
        company: "webless",
        start_date: "2025-07-01",
        end_date: "2025-07-03"
      },
      headers: {
        "x-api-key": "YOUR_API_KEY"
      }
    });

    const url = trigger.data.presigned_url;

    while (true) {
      const probe = await axios.get(url, {
        headers: { Range: "bytes=0-0" },
        validateStatus: (status) => [200, 206, 403, 404].includes(status)
      });

      if ([200, 206].includes(probe.status)) {
        break;
      }

      await new Promise((resolve) => setTimeout(resolve, 10000));
    }

    const response = await axios.get(url, { responseType: "stream" });
    response.data.pipe(fs.createWriteStream("webless_results.csv"));
  })();
  ```
</CodeGroup>

## Error handling

| Status | Meaning                      |
| ------ | ---------------------------- |
| `400`  | Missing or invalid parameter |
| `403`  | Invalid or missing API key   |
| `404`  | Incorrect endpoint           |
| `429`  | Rate limit exceeded          |
| `500`  | Server error                 |

<Note>
  For assistance, email [tech@webless.ai](mailto:tech@webless.ai). The source
  guide states a business-day response target of 4 hours.
</Note>
