Skip to navigation

Analytics Reports API

Pull your Pixalate Analytics dashboard reports into your own systems.

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

AccessThe API is available to Pixalate Analytics subscribers. To have it enabled, contact your Pixalate account manager.
AuthenticationSend your Pixalate API key in the x-api-key request header. See Authentication and API keys.
Base URLhttps://api.pixalate.com/api/v2/analytics/reports
MethodGET for every endpoint

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.

The API has two endpoints:

EndpointWhat it doesReference
GET /analytics/reportsReturns your quota state and the date the reports database was last updated.Get analytics reports metadata
GET /analytics/reports/{reportId}Runs a query against one report and returns the rows.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:

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:

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.

Read the response

A successful request returns 200 OK with a JSON object:

{
"numFound": 5828,
"docs": [
{ "adDomain": "example.com", "impressions": 11069, "givtSivtRate": 0.30762 },
{ "adDomain": "example.org", "impressions": 3587, "givtSivtRate": 0.06635 }
]
}
FieldTypeDescription
numFoundintegerThe total number of report items.
docsarrayThe 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 IDDashboard report
defaultDashboard (the default report). The Domain, By Fraud Type and By Seller ID examples also use it.
spoSPO Reports: Supply Path
spoSrcDestSPO Reports: Source Destination Traffic
mobileBrandSafetyMobile 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.

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:

curl "https://api.pixalate.com/api/v2/analytics/reports?pretty=true" \
-H "x-api-key: YOUR_API_KEY"
{
"database": {
"lastUpdated": "2022-04-30"
},
"quota": {
"available": 480,
"used": 520,
"expiry": "2022-05-01T12:45:23.234Z",
"limit": 1000,
"interval": 1000,
"timeUnit": "month"
}
}
FieldDescription
database.lastUpdatedThe date the Analytics Reports database was last updated, as YYYY-MM-DD.
quota.availableThe amount of quota available for use.
quota.usedThe amount of quota used.
quota.expiryWhen the quota will be refreshed back to the limit, as YYYY-MM-DDTHH:MM:SS.SSSZ.
quota.limitThe amount of quota made available when the quota is refreshed.
quota.intervalThe number of time units used to calculate the refresh time.
quota.timeUnitThe 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 and in the Get analytics report reference.

Query parameters

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

ParameterTypeDefaultDescription
qstringThe URL-encoded query to run, in a simplified SQL SELECT syntax. See Query language.
timeZoneinteger0The time zone in which to sync the report data, as the number of minutes from GMT. 0 is UTC.
startinteger0The item in the results to start from.
limitinteger20The total number of items to return. Ignored when isAsync or isLargeResultSet is true.
exportUribooleanfalseIf true, return a URI to the data as a CSV file instead of the data itself.
isAsyncbooleanfalseIf true, return the CSV URI immediately and process the report in the background. Only recognized when exportUri=true.
isLargeResultSetbooleanfalseIf true, process as for isAsync and split the data across several CSV files. Only recognized when exportUri=true.
prettybooleanfalseIf 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:

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.

# 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 instead.

Export to CSV

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

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:

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

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.

1

Request the export

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

2

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.

3

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.

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.

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'"

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

Output formats

You wantParametersYou get
JSON rows(default)A JSON object with numFound and docs
Indented JSONpretty=trueThe same JSON, indented
A CSV fileexportUri=trueA URI to the CSV data
A CSV file processed in the backgroundexportUri=true&isAsync=trueA URI that returns 404 until the CSV is ready
A large result split across CSV filesexportUri=true&isLargeResultSet=trueA URI to a single-column CSV that lists the URLs of the part files

Errors

StatusMeaningWhat to do
400 Bad RequestThe request has invalid parameters or an invalid query. A large result that uses ORDER BY can also return 400.Check q against Query language. Names and values are case sensitive. For large results, remove ORDER BY.
401 UnauthorizedInvalid API key.Send a valid key in the x-api-key header.
403 ForbiddenYour 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 FoundWhen you poll an export URI with isAsync or isLargeResultSet: the report is still processing.Keep polling.
5XXThe API had an internal error, or the query could not be completed.If it persists, contact support@pixalate.com.

For behavior shared by all Pixalate APIs, see Quotas, limits 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.

The default Dashboard report, grouped by advertiser:

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"

Questions? Contact support@pixalate.com.