v1

latestOpenAPI 3.0.12026-08-06241391671.8 KB
Reports

Returns aggregated report grouped by the specified dimension(s).

Returns aggregated performance data grouped by the specified dimension(s). This is the primary reporting endpoint for campaign analytics.

Prerequisites

Before building report queries, call these endpoints to discover account-specific configuration:

  • GET /column/info — returns all valid groupBy dimensions (canGroupBy: true) and metric columns with their display labels and types.
  • GET /custom-conversions — returns custom conversion type definitions (index 1-20 mapping to customConversions{N} and customRevenue{N} columns).
  • GET /custom-columns — returns user-defined derived metric names that can be passed as column values alongside built-in metrics.
  • GET /traffic-source — returns each source's customVariables[] array, where every entry carries index, name (user-facing label) and parameter (the URL parameter the source sends on the click). Variable meanings are defined per traffic source — the same slot index can mean different things on different sources.

Key behaviors

  • Date range is half-open [from, to): the 'to' date is exclusive. To query March 5 in full, set from=2026-03-05T00:00:00Z and to=2026-03-06T00:00:00Z.
  • Name columns must be requested explicitly: groupBy=campaignId only returns campaignId. Add campaignName to the column list to get human-readable names.
  • Column is a repeated parameter: use column=visits&column=clicks, not column=visits,clicks.
  • Drilldown filters: use filter1=campaignId&filter1Value=<id> to filter results. Multiple filters: filter1/filter1Value, filter2/filter2Value, etc.

Metric formulas

  • CTR = clicks / visits (lander effectiveness)
  • CR = conversions / clicks (offer quality)
  • CV = conversions / visits (end-to-end funnel efficiency)
  • ROI = (revenue - cost) / cost (expressed as percentage, e.g. 125.0 = 125%)
  • CPA = cost / conversions
  • EPV = revenue / visits
  • EPC = revenue / clicks
  • CPV = cost / visits

Direct-linking campaigns

Campaigns without a lander (direct-linking) never record click events. CTR, CR, clicks, and EPC are always zero — this is expected, not a tracking error. Use CV (conversions/visits) and EPV (revenue/visits) instead. Detection: inspect the campaign's flow for lander presence (GET /campaign/{id}), or run groupBy=landerId filtered to the campaign — if no landers appear, it is direct-linking.

This endpoint vs /report/conversions

This endpoint returns aggregated data grouped by dimensions. For individual conversion events (no grouping), use GET /report/conversions instead — that endpoint does not accept groupBy, conversionTimeMode, or include parameters.

Rate limits and response size

Throttling applies at three levels:

Per Bearer token (per user) — three independent buckets:

BucketBase allocationNotes
Per-second (burst)~4 req/sHit first by most clients
Concurrent in-flight~30Counted while a request is on the wire
Per-minute (sustained)Higher; rarely the binding capOnly hit if you sustain perfectly even pacing

Base allocation only — many accounts have higher negotiated limits. Contact support for your values.

Per IP — anti-abuse cap; authenticated clients from a single host should not normally hit it.

Per-user utilization budget (reports only) — independent of request count. Heavier queries (longer date ranges, wider groupBy, more column values) cost more; light queries cost little. Often the binding cap on heavy analytics workloads — prefer many narrow queries over a few enormous ones if you see 429s without exceeding the per-second cap.

Exceeding any of these returns 429 Too Many Requests with an empty body and no Retry-After header. Back off and retry.

Per-request row cap: see the limit query parameter. Per-account caps and throttling thresholds are configurable; contact support to raise them.

get/report

Query parameters

include'ALL' | 'ACTIVE' | 'ARCHIVED' | 'TRAFFIC'

Controls which entities appear in the report. Default: TRAFFIC.

  • ALL — all entities, including those with no traffic in the period
  • ACTIVE — only active (non-archived) entities, including those with no traffic
  • ARCHIVED — only archived entities, including those with no traffic
  • TRAFFIC — only rows with non-zero traffic events (excludes entities with no traffic)

Entities with no traffic in the period are returned for every value except TRAFFIC.

offsetinteger

Pagination offset (zero-based). Default: 0.

tzstring

Time zone for date aggregation, e.g. 'America/New_York', 'Europe/Warsaw', or 'Etc/GMT'. Default: Etc/GMT. Affects how day, dayOfWeek, and hourOfDay boundaries are calculated.

columnstring[]

Columns to include in the response. Repeated query parameter — use column=visits&column=clicks, NOT comma-separated.

Volume: visits, clicks, conversions, impressions, uniqueVisits, uniqueClicks

Financial: revenue, cost, profit

Rate/efficiency metrics (with formulas):

ColumnFormulaNote
ctrclicks / visitsLander effectiveness. Always 0 for direct-linking campaigns
crconversions / clicksOffer quality. Always 0 for direct-linking campaigns
cvconversions / visitsEnd-to-end funnel. The only rate metric valid for both lander and direct-linking
roi(revenue-cost) / costPercentage, e.g. 125.0 = 125% ROI
cpacost / conversionsCost per acquisition
epvrevenue / visitsEarnings per visit
epcrevenue / clicksAlways 0 for direct-linking campaigns
cpvcost / visitsCost per visit
cpccost / clicksCost per click

Other rate metrics: ecpa, ecpc, ecpm, cpm, ap, rpm, sctr, ictr, viewRate

Quality: suspiciousVisits, suspiciousClicks, robotVisits

Entity names: campaignName, offerName, landerName, trafficSourceName, affiliateNetworkName, countryName, deviceName, connectionTypeName, languageName, flowName

Custom: customConversions1-20, customRevenue1-20 (discover via GET /custom-conversions). User-defined derived metrics (discover via GET /custom-columns).

No Name variant for self-labeling dimensions: region, city, os, osVersion, browser, browserVersion, isp, mobileCarrier, referrerDomain are already human-readable — there is no regionName/cityName/osName/browserName column, and requesting one returns 400. (Code/name pairs like countryCode/countryName and connectionType/connectionTypeName are the exception — those Name columns do exist.)

Tags: the tag column is campaignTags (also offerTags, landerTags) — plain tags is not a column.

To discover all available columns at runtime, call GET /column/info.

filter1string

Drilldown filter dimension — a dimension column to filter the report by an EXACT value, e.g. campaignId. Pair with filter1Value. This is the correct, server-side way to scope a report to a single entity by id; the filter parameter only does free-text name search, which is fragile and can match the wrong row.

compareFromstring

Start date/time (inclusive) for the comparison period. ISO 8601 format. Used for period-over-period analysis.

filter2string

Second drilldown filter dimension (optional), e.g. countryCode. Pair with filter2Value.

groupBystring[] required

Dimension(s) to group results by. Repeated parameter — use groupBy=campaignId&groupBy=countryCode, not comma-separated.

Call GET /column/info to discover all valid groupBy values for this account (filter response for canGroupBy: true). The list evolves — don't hardcode it.

Common examples: campaignId, offerId, landerId, trafficSourceId, affiliateNetworkId, countryCode, day, dayOfWeek, hourOfDay, month, device, os, browser, isp, referrerDomain, flowId, customVariable1 through customVariable10.

Name column mapping — grouping by an entity returns only the ID. You must request the name column explicitly via the 'column' parameter:

groupByName column to request
campaignIdcampaignName
offerIdofferName
landerIdlanderName
trafficSourceIdtrafficSourceName
affiliateNetworkIdaffiliateNetworkName
countryCodecountryName
devicedeviceName
connectionTypeconnectionTypeName
languagelanguageName
flowIdflowName

Custom variables: slot meanings are per-source (slot 1 may be zoneid on PropellerAds, pubid on Reacheffect). Discover labels via GET /traffic-source → each source's customVariables[] array. customVariable1..10 breakdowns must be scoped to a single campaign (or at least a single traffic source) via filter1=campaignId&filter1Value=<id>; unscoped breakdowns mix incompatible populations. The endpoint accepts unscoped queries — scoping is on the caller.

Group by the ID, not the NameName columns (campaignName, offerName, landerName, ...) have canGroupBy: false; grouping by one returns Could not find matching view. Group by the matching ID and request the Name as a column (see the table above).

Self-labeling dimensionsregion, city, os, osVersion, browser, browserVersion, isp, mobileCarrier, referrerDomain return the human-readable value directly and have no Name variant. (Code/name pairs like countryCode/countryName and connectionType/connectionTypeName are the exception — see the table above.)

Common mistakes returning 400: deviceType (use device), campaignName and other Name columns (group by the ID instead — see above), conversion (use /report/conversions endpoint). canGroupBy: true is necessary but not sufficient — some flagged-groupable dimensions (e.g. category, externalCampaignId) still return Could not find matching view for a given account; treat that as a prompt to pick a different dimension, not a bug. Both referrer and referrerDomain are valid groupBy keys; prefer referrerDomain to avoid high-cardinality full-URL rows.

compareTostring

End date/time (exclusive) for the comparison period. ISO 8601 format. Same half-open semantics as the 'to' parameter.

sortstring

Column name to sort by. Can be any valid metric or dimension column. Default: visits.

filter1Valuestring

Exact value for filter1, e.g. the campaign id. Returns only rows matching this value.

filterstring

Free-text substring search over NAME columns only (campaignName, offerName, ...). NOT for ids and NOT exact — a fragment can match several rows or none. To scope a report to a specific entity by id, use the drilldown filters filter1/filter1Value (e.g. filter1=campaignId, filter1Value=<id>); never put an id here.

limitinteger

Maximum rows to return per request. Default: 100. Values above the per-account cap are silently capped; totalRows always reflects the true count. Use offset to page through.

fromstring required

Start date/time (inclusive, required). ISO 8601 format, e.g. 2026-03-01T00:00:00Z.

Must be aligned to an hour boundary — minutes and seconds must be zero.

The date range is half-open [from, to) — 'from' is included in results.

currencystring

Currency code for monetary values in the response, e.g. USD, EUR, GBP. Default: USD.

tostring

End date/time (EXCLUSIVE). ISO 8601 format. The date range is half-open [from, to) — 'to' is NOT included.

Must be aligned to an hour boundary — minutes and seconds must be zero.

Default: start of the next hour in the request timezone (e.g. if current time is 14:30, default to is 15:00). This means omitting to gives you data up to the current hour.

To query the full day of March 5, set to=2026-03-06T00:00:00Z (next day). Common mistake: setting to=2026-03-05T00:00:00Z returns zero results for March 5.

filter2Valuestring

Exact value for filter2.

workspacesstring[]

Workspace IDs to filter by. Only returns data for campaigns in the specified workspaces.

conversionTimeMode'CONVERSION' | 'VISIT'

Controls how conversions are attributed in time. Default: VISIT.

  • VISIT — attribute conversion to the time of the original visit (click time)
  • CONVERSION — attribute conversion to the time the postback was received

Use VISIT when you want conversions aligned with the traffic that generated them. Not applicable to /report/conversions endpoint.

Period-over-period comparisons: use the same mode for both periods (e.g. WoW with compareFrom/compareTo). Mixing VISIT and CONVERSION produces fake late-funnel drops — conversions registered after the first period closes are visible under CONVERSION but invisible under VISIT.

direction'ASC' | 'DESC'

Sort direction. Default: desc (descending).

Response

Aggregated report data.