> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pixalate.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pixalate.com/_mcp/server.

# Analytics Reports API

> Use the Pixalate Analytics Reports API to query dashboard reports as JSON or CSV, page through results, export large reports asynchronously and check your quota.

The Analytics Reports API gives Pixalate Analytics subscribers programmatic access to the reports they see in the Analytics dashboard. You choose a report, write a short SQL-like query that names the dimensions and metrics you want, and get the rows back as JSON or as a downloadable CSV file.

## Before you start

|                    |                                                                                                                        |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **Access**         | The API is available to Pixalate Analytics subscribers. To have it enabled, contact your Pixalate account manager.     |
| **Authentication** | Send your Pixalate API key in the `x-api-key` request header. See [Authentication and API keys](/apis/authentication). |
| **Base URL**       | `https://api.pixalate.com/api/v2/analytics/reports`                                                                    |
| **Method**         | `GET` for every endpoint                                                                                               |

> **Note**
>
> This API uses API key authentication only. Username and password credentials are deprecated for it. If you were onboarded with a username and password, ask your Pixalate account manager for an API key, and see [Migrating from legacy APIs](/apis/legacy-apis).

The API has two endpoints:

| Endpoint                            | What it does                                                                 | Reference                                                                                         |
| ----------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `GET /analytics/reports`            | Returns your quota state and the date the reports database was last updated. | [Get analytics reports metadata](/api-reference/analytics-reports/get-analytics-reports-metadata) |
| `GET /analytics/reports/{reportId}` | Runs a query against one report and returns the rows.                        | [Get analytics report](/api-reference/analytics-reports/get-analytics-report)                     |

## Make your first request

This request returns the top 10 ad domains by gross ad counts for one day, from the default dashboard report:

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "q=adDomain,impressions,givtSivtRate WHERE day>='2026-02-06' AND day<='2026-02-06' ORDER BY impressions DESC" \
  --data-urlencode "limit=10"
```

`--get` with `--data-urlencode` makes curl URL-encode each value and append it to the URL. The `q` value must be URL-encoded because it contains spaces, quotes and comparison operators. The request curl sends looks like this:

```text
GET /api/v2/analytics/reports/default?q=adDomain%2Cimpressions%2CgivtSivtRate%20WHERE%20day%3E%3D%272026-02-06%27%20AND%20day%3C%3D%272026-02-06%27%20ORDER%20BY%20impressions%20DESC&limit=10
```

The query syntax is documented in [Query language](/apis/analytics-query-language).

## Read the response

A successful request returns `200 OK` with a JSON object:

```json
{
  "numFound": 5828,
  "docs": [
    { "adDomain": "example.com", "impressions": 11069, "givtSivtRate": 0.30762 },
    { "adDomain": "example.org", "impressions": 3587, "givtSivtRate": 0.06635 }
  ]
}
```

| Field      | Type    | Description                                                                                                      |
| ---------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `numFound` | integer | The total number of report items.                                                                                |
| `docs`     | array   | The report items in this response. Each item has one property for each dimension and metric you selected in `q`. |

Values in the example are illustrative. Rate metrics such as `givtSivtRate` are returned as fractions, so `1` means 100%.

Add `pretty=true` to get indented JSON. The default is `false`.

## Choose a report

The `reportId` path segment selects the report to query.

* Use `default` for the default analytics report. This is the *Dashboard* report you see when you first log in to the Pixalate dashboard.
* For any other dashboard report, use its report ID. You can find it in the Analytics dashboard URL (the `reportId=` value) while you view that report.
* The Brand Safety report always needs its own report ID.

The examples on this site use these report IDs:

| Report ID           | Dashboard report                                                                                 |
| ------------------- | ------------------------------------------------------------------------------------------------ |
| `default`           | Dashboard (the default report). The Domain, By Fraud Type and By Seller ID examples also use it. |
| `spo`               | SPO Reports: Supply Path                                                                         |
| `spoSrcDest`        | SPO Reports: Source Destination Traffic                                                          |
| `mobileBrandSafety` | Mobile Brand Safety                                                                              |

There is no endpoint that lists the reports available to your account. If you can't find the ID of a report you need, contact [support@pixalate.com](mailto:support@pixalate.com).

## Check your quota and data freshness

Call the base URL without a report ID to see your quota state and when the reports database was last updated:

```bash
curl "https://api.pixalate.com/api/v2/analytics/reports?pretty=true" \
  -H "x-api-key: YOUR_API_KEY"
```

```json
{
  "database": {
    "lastUpdated": "2022-04-30"
  },
  "quota": {
    "available": 480,
    "used": 520,
    "expiry": "2022-05-01T12:45:23.234Z",
    "limit": 1000,
    "interval": 1000,
    "timeUnit": "month"
  }
}
```

| Field                  | Description                                                                                   |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| `database.lastUpdated` | The date the Analytics Reports database was last updated, as `YYYY-MM-DD`.                    |
| `quota.available`      | The amount of quota available for use.                                                        |
| `quota.used`           | The amount of quota used.                                                                     |
| `quota.expiry`         | When the quota will be refreshed back to the limit, as `YYYY-MM-DDTHH:MM:SS.SSSZ`.            |
| `quota.limit`          | The amount of quota made available when the quota is refreshed.                               |
| `quota.interval`       | The number of time units used to calculate the refresh time.                                  |
| `quota.timeUnit`       | The time unit used to calculate the refresh time: `minute`, `hour`, `day`, `week` or `month`. |

This endpoint doesn't return the dimensions and metrics you can query. Those are listed in [Query language](/apis/analytics-query-language#dimensions) and in the [Get analytics report](/api-reference/analytics-reports/get-analytics-report) reference.

## Query parameters

These are the query parameters for `GET /analytics/reports/{reportId}`.

| Parameter          | Type    | Default | Description                                                                                                                |
| ------------------ | ------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| `q`                | string  |         | The URL-encoded query to run, in a simplified SQL `SELECT` syntax. See [Query language](/apis/analytics-query-language).   |
| `timeZone`         | integer | `0`     | The time zone in which to sync the report data, as the number of minutes from GMT. `0` is UTC.                             |
| `start`            | integer | `0`     | The item in the results to start from.                                                                                     |
| `limit`            | integer | `20`    | The total number of items to return. Ignored when `isAsync` or `isLargeResultSet` is `true`.                               |
| `exportUri`        | boolean | `false` | If `true`, return a URI to the data as a CSV file instead of the data itself.                                              |
| `isAsync`          | boolean | `false` | If `true`, return the CSV URI immediately and process the report in the background. Only recognized when `exportUri=true`. |
| `isLargeResultSet` | boolean | `false` | If `true`, process as for `isAsync` and split the data across several CSV files. Only recognized when `exportUri=true`.    |
| `pretty`           | boolean | `false` | If `true`, return indented JSON.                                                                                           |

## Set the date range

Filter on the `day` dimension in the `WHERE` clause of `q`. Dates use the `yyyy-mm-dd` format inside single quotes. The examples on this site all use this pattern:

```sql
WHERE day>='2026-02-01' AND day<='2026-02-07'
```

For a single day, use the same date twice. The `timeZone` parameter sets the time zone the report data is synced in, as an integer number of minutes from GMT. The default, `0`, is UTC.

## Page through results

Use `start` and `limit` to read results a page at a time. `numFound` in the response tells you how many items there are in total.

```bash
# Items 1-100
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "q=kv7,impressions,sivtImpressions,sivtImpsRate WHERE day>='2026-02-01' AND day<='2026-02-01' GROUP BY kv7 ORDER BY impressions DESC" \
  --data-urlencode "start=0" \
  --data-urlencode "limit=100"

# Items 101-200: send the same request with start=100
```

Send the same `q` for every page, increase `start` by `limit` each time, and stop when `start` reaches `numFound`. If the result is too large to page through, [export it to CSV](#export-to-csv) instead.

## Export to CSV

Add `exportUri=true` and the API returns a URI to the CSV data instead of the data itself:

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "exportUri=true" \
  --data-urlencode "q=kv18,campaignId,siteId,fraudType,impressions,givtSivtRate WHERE day>='2026-01-25' AND day<='2026-01-25' ORDER BY impressions DESC"
```

The response is the URI of the CSV file, for example:

```text
https://dashboardcdn.pixalate.com/www/exported/{client}/2026-01-25/8qak3ig189r58t26rot92v0lid/Report_for_2026-01-25.csv
```

> **Warning**
>
> The CSV resource is public: anyone who has the URI can download it. The URI contains a randomly generated identifier, so the data stays relatively secure as long as you don't make the URI itself public.

### Run an export asynchronously

Add `isAsync=true` (together with `exportUri=true`) to get the CSV URI back immediately while the report is processed in the background. `limit` is ignored.

#### Request the export

Send the request with `exportUri=true` and `isAsync=true`. The API returns the CSV URI right away.

#### Poll the URI

Request the URI. It returns `404 Not Found` until the report has finished processing. Keep polling until you get a status other than `404`.

#### Download the file or handle the error

Once processing has completed, the URI returns the report. If processing failed because the query is invalid, it returns `400 Bad Request`. For any other error it returns `500 Internal Server Error`.

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "exportUri=true" \
  --data-urlencode "isAsync=true" \
  --data-urlencode "q=kv18,campaignId,siteId,fraudType,impressions,givtSivtRate WHERE day>='2026-01-25' AND day<='2026-01-25' ORDER BY impressions DESC"
```

### Export a large result set

For very large results, add `isLargeResultSet=true` (together with `exportUri=true`). Processing works exactly as it does with `isAsync=true`: you get a URI back immediately and poll it until it stops returning `404`. The difference is the file. It contains a single column, and each row is the URL of a CSV file that holds part of the data. Download every file in the list to get the full result. `limit` is ignored.

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "exportUri=true" \
  --data-urlencode "isLargeResultSet=true" \
  --data-urlencode "q=kv18,fraudType,impressions,givtSivtRate WHERE day>='2026-01-25' AND day<='2026-01-25'"
```

> **Note**
>
> Large results that use `ORDER BY` may return `400 Bad Request`. If that happens, remove the `ORDER BY` clause.

## Output formats

| You want                               | Parameters                             | You get                                                            |
| -------------------------------------- | -------------------------------------- | ------------------------------------------------------------------ |
| JSON rows                              | (default)                              | A JSON object with `numFound` and `docs`                           |
| Indented JSON                          | `pretty=true`                          | The same JSON, indented                                            |
| A CSV file                             | `exportUri=true`                       | A URI to the CSV data                                              |
| A CSV file processed in the background | `exportUri=true&isAsync=true`          | A URI that returns `404` until the CSV is ready                    |
| A large result split across CSV files  | `exportUri=true&isLargeResultSet=true` | A URI to a single-column CSV that lists the URLs of the part files |

## Errors

| Status             | Meaning                                                                                                            | What to do                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `400 Bad Request`  | The request has invalid parameters or an invalid query. A large result that uses `ORDER BY` can also return `400`. | Check `q` against [Query language](/apis/analytics-query-language). Names and values are case sensitive. For large results, remove `ORDER BY`. |
| `401 Unauthorized` | Invalid API key.                                                                                                   | Send a valid key in the `x-api-key` header.                                                                                                    |
| `403 Forbidden`    | Your rate plan has expired or your quota has been exhausted.                                                       | Check your quota with `GET /analytics/reports`, or contact your Pixalate account manager.                                                      |
| `404 Not Found`    | When you poll an export URI with `isAsync` or `isLargeResultSet`: the report is still processing.                  | Keep polling.                                                                                                                                  |
| `5XX`              | The API had an internal error, or the query could not be completed.                                                | If it persists, contact [support@pixalate.com](mailto:support@pixalate.com).                                                                   |

For behavior shared by all Pixalate APIs, see [Quotas, limits and errors](/apis/quotas-and-errors).

## Worked examples

Each example is a complete request. For more queries, including filters on specific values and text matching, see the [query language examples](/apis/analytics-query-language#worked-examples).

#### By advertiser

The default *Dashboard* report, grouped by advertiser:

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "q=advertiserId,reach,impressions,viewability,views,viewsRate,adsAboveTheFold,givtImpsRate,sivtImpsRate WHERE day>='2026-02-01' AND day<='2026-02-01' GROUP BY advertiserId ORDER BY impressions DESC" \
  --data-urlencode "start=0" \
  --data-urlencode "limit=10"
```

#### By fraud type

The *By Fraud Type* report from Pre-Set Reports. Each row holds the data for one fraud type. A row with a fraud type value is always 100% IVT. A row with no fraud type value is 100% IVT-free.

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/default" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "q=fraudType,impressions,sivtImpressions,sivtImpsRate,givtImpressions,givtImpsRate WHERE day>='2026-02-01' AND day<='2026-02-01' GROUP BY fraudType ORDER BY impressions DESC" \
  --data-urlencode "limit=10"
```

#### Supply path

The *SPO Reports: Supply Path* report:

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/spo" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "q=kv18,kv55,node1SellerId,node2SellerId,nodePathComplete,impressions,givtSivtRate WHERE day>='2026-02-01' AND day<='2026-02-01' ORDER BY impressions DESC" \
  --data-urlencode "start=0" \
  --data-urlencode "limit=10"
```

#### Brand safety

App IDs with high adult risk, from the Mobile Brand Safety report:

```bash
curl --get "https://api.pixalate.com/api/v2/analytics/reports/mobileBrandSafety" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "exportUri=true" \
  --data-urlencode "q=kv18,adultRisk,impressions WHERE day>='2023-10-24' AND day<='2023-10-24' AND adultRisk='high' ORDER BY impressions DESC"
```

## Related

#### [Query language](/apis/analytics-query-language)

The `q` syntax, filters, dimensions and metrics.

#### [API reference](/api-reference/analytics-reports/get-analytics-report)

Every parameter and response field for the report endpoint.

#### [Authentication and API keys](/apis/authentication)

How to send your API key.

#### [Migrating from legacy APIs](/apis/legacy-apis)

Moving from the older username and password endpoints.

Questions? Contact [support@pixalate.com](mailto:support@pixalate.com).