# Export Readings

Source: https://help.zira.us/developers/api-reference/export-readings
Summary: Export readings data through the downstream meters-data export flow.
Updated: 2026-08-06

## `GET /export`

Use this endpoint when an integration needs an export payload for readings over a time range.

## Authentication

```http
x-api-key: <your-api-key>
```

See [API Authentication](/developers/api-reference/api-authentication) for how to create a key.

## Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `meterId` | string | yes | Meter or data-source ID to export readings for. |
| `startTime` | string | no | Start time for time mode A. |
| `endTime` | string | no | End time for time mode A. |
| `startHour` | string | no | Start hour for time mode B. |
| `endHour` | string | no | End hour for time mode B. |
| `startOffset` | string | no | Start offset for time mode B. |
| `endOffset` | string | no | End offset for time mode B. |

## Response

`200 OK`

Generates a CSV of the readings in the range and returns a download URL for it. The file is finished before you get the URL, so the link works immediately — download it with a plain `GET` and no `Authorization` header.

```json
{
  "data": {
    "fileUrl": "https://prod-exports-lightapp.s3.us-west-2.amazonaws.com/Line%201%20Water%20Meter_2026-01-01T00%3A00%3A00.000Z_2026-01-08T00%3A00%3A00.000Z.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=%3Ccredential%3E&X-Amz-Date=20260114T091500Z&X-Amz-Expires=604800&X-Amz-Security-Token=%3Ctoken%3E&X-Amz-Signature=%3Csignature%3E&X-Amz-SignedHeaders=host"
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `data` | object (nullable) | Wrapper holding the download URL. It is `null` instead of an object when the range contained no readings. |
| `data.fileUrl` | string | Download URL for the generated CSV. Valid for seven days. |

### Good to know

- An empty range returns `200` with `data` set to `null`. Check for that before reading `data.fileUrl`.
- The download URL is valid for seven days.
- The file is a CSV whose first column is `timestamp`, followed by the data source’s metric names. Timestamps are in the data source’s site time zone — unlike `GET /reading`, which returns UTC.
- The whole range is exported with no row cap, and the request is synchronous with about a 30-second budget. Export wide ranges a day or a week at a time.
- Unlike `GET /reading`, this endpoint ignores `limit` and `sortDesc`.
- Confirm that `data.fileUrl` is actually present rather than relying on the `200` alone.

## Errors

Failures return a JSON body with a `message` and an `internalErrorCode`, at the status shown below. Whenever the underlying error carries structured detail — which every schema-validation failure does — the body is replaced with a generic `Internal server error.` / `02-001` pair while the real status code is kept. Branch on the HTTP status and on `internalErrorCode`; never parse the message text.

```json
{
  "message": "Internal server error.",
  "internalErrorCode": "02-001"
}
```

| Status | Meaning |
| --- | --- |
| `400` | The request failed validation — a missing required field, a field the schema does not allow, an unparseable body, a value out of range, or a malformed `lastValue`. |
| `401` | The API key resolved to a user context that is not allowed to read or write the record you asked for. |
| `403` | The `x-api-key` header is missing or is not a recognised key. API Gateway rejects the call before the endpoint runs, so the body is only `{"message":"Forbidden"}`. |
| `409` | The write conflicts with an existing record, or it references a record that does not exist. |
| `429` | The API key exceeded the rate limit or quota on its usage plan. Also returned by API Gateway rather than the endpoint. |
| `500` | Unexpected server error, or the database returned no result where one was required. |
