Introduction
Get started with the Adverfly API
The Adverfly API allows you to programmatically access data from your workspace. You can retrieve events, sessions, conversions, and ads for analytics.
API Capabilities
| Capability | Description |
|---|---|
| Read Data | Retrieve events, sessions, conversions, and ads via GET endpoints |
When to Use the API vs. JavaScript Pixel
| Use Case | Recommended Method |
|---|---|
| Website tracking | JavaScript Pixel (client-side) |
| Data export / BI integration | API |
| Custom dashboards | API |
| Real-time web analytics | JavaScript Pixel |
Base URL
All API requests should be made to:
https://api.adverfly.comAuthentication
The API uses API keys for authentication. You can generate API credentials in your workspace settings.
| Parameter | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Required | Your workspace API key |
client-secret | string | Required | Your workspace client secret |
curl -X GET "https://api.adverfly.com/v3/events" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
Response Format
All responses are returned in JSON format with a pagination object for navigating results.
{
"data": [...],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true,
"next_offset": 100,
"start_date": "2024-01-01 00:00:00",
"end_date": "2024-01-31 23:59:59"
}
}
Pagination
| Field | Type | Description |
|---|---|---|
limit | integer | Number of records returned |
offset | integer | Number of records skipped |
has_more | boolean | Whether more records are available |
next_offset | integer or null | Offset value for the next page (null when has_more is false) |
start_date | string | Start of the queried date range |
end_date | string | End of the queried date range |
Use next_offset as the offset parameter in your next request to paginate through results. When has_more is false, you have reached the last page.
Rate Limits
| Limit | Value |
|---|---|
| Daily quota | 4,320 requests per day |
| Rate limit | 10 requests per second |
| Burst limit | 20 requests |
| Max records per request | 500 (limit parameter) |
Date Parameters
All endpoints accept start_date and end_date in YYYY-MM-DD format. If omitted, the API defaults to the last 7 days. Aliases from and to are also accepted.
end_date is inclusive: end_date=2026-07-30 runs through 2026-07-30 23:59:59 (UTC), so the last day is never cut off. Pass a full timestamp instead if you need an exact cut-off — it is used verbatim.
Events
Retrieve event data from your workspace
Retrieve event data from your workspace pixel tracking. Events include pageviews, clicks, and custom events tracked by your pixel.
Purchases are not events. Conversions — purchase, lead, subscribe — are stored separately and returned by /v3/conversions. Querying /v3/events?name=purchase returns an empty list on almost every workspace.
/v3/eventsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | Optional | Start date in YYYY-MM-DD format (default: 7 days ago). Alias: from |
end_date | string | Optional | End date in YYYY-MM-DD format (default: today). Alias: to |
name | string | Optional | Filter by event name. Supports wildcards with * (e.g. survey_* to match all survey events). Alias: event_name |
session_id | integer | Optional | Filter by session ID |
visitor_id | integer | Optional | Filter by visitor ID |
source | string | Optional | Filter by ad source. Comma-separated for multiple (e.g. meta,google). Alias: sources |
limit | integer | Optional | Number of records to return (default: 100, max: 500). Alias: page_size |
offset | integer | Optional | Number of records to skip for pagination. Alias: page |
Name filter examples
| Value | Matches |
|---|---|
pageview | Exact match — only pageview events |
survey_* | All events starting with survey_ (e.g. survey_opened, survey_completed) |
*_completed | All events ending with _completed |
curl -X GET "https://api.adverfly.com/v3/events?start_date=2024-01-01&end_date=2024-01-31&name=survey_*&limit=100" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
{
"data": [
{
"store_id": 12345,
"dt": "2024-01-15 10:30:00",
"name": "pageview",
"session_id": 789012345,
"visitor_id": 456789012,
"visitor_timezone": "Europe/Berlin",
"adv_source": "meta",
"adv_campaign_id": "120210123456789",
"adv_adgroup_id": "120210987654321",
"adv_ad_id": "120210111222333",
"adv_asset_group_id": "6502489623",
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "winter_sale",
"utm_content": "video_ad_1",
"utm_term": "",
"device_type": "desktop",
"country_code": "DE",
"hostname": "example.com",
"pathname": "/products",
"referrer": "https://google.com",
"entry_meta_keys": ["fbclid", "gclid"],
"entry_meta_values": ["abc123", ""]
}
],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true,
"next_offset": 100,
"start_date": "2024-01-01 00:00:00",
"end_date": "2024-01-31 23:59:59"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
store_id | integer | Workspace ID |
dt | string | Event timestamp |
name | string | Event name (e.g. pageview, add_to_cart, survey_opened) |
session_id | integer | Session identifier |
visitor_id | integer | Visitor identifier |
visitor_timezone | string | Visitor's timezone |
adv_source | string | Ad platform source (e.g. meta, google) |
adv_campaign_id | string | Campaign ID from ad platform |
adv_adgroup_id | string | Ad group ID from ad platform |
adv_ad_id | string | Ad ID from ad platform |
adv_asset_group_id | string | Asset Group ID (Google Performance Max) |
utm_source | string | UTM source parameter |
utm_medium | string | UTM medium parameter |
utm_campaign | string | UTM campaign parameter |
utm_content | string | UTM content parameter |
utm_term | string | UTM term parameter |
device_type | string | Device type (desktop, mobile, tablet) |
country_code | string | ISO country code (e.g. DE, US) |
hostname | string | Website hostname |
pathname | string | Page path |
referrer | string | Referring URL |
entry_meta_keys | array | Click ID parameter names (e.g. fbclid, gclid) |
entry_meta_values | array | Click ID values (parallel array with entry_meta_keys) |
Sessions
Access session data and user activity
Access session data and user activity information. A session represents a user's visit to your website, grouping multiple events together.
/v3/sessionsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | Optional | Start date in YYYY-MM-DD format (default: 7 days ago). Alias: from |
end_date | string | Optional | End date in YYYY-MM-DD format (default: today). Alias: to |
session_id | integer | Optional | Filter by session ID |
visitor_id | integer | Optional | Filter by visitor ID |
source | string | Optional | Filter by ad source. Comma-separated for multiple. Alias: sources |
limit | integer | Optional | Number of records to return (default: 100, max: 500). Alias: page_size |
offset | integer | Optional | Number of records to skip for pagination. Alias: page |
curl -X GET "https://api.adverfly.com/v3/sessions?start_date=2024-01-01&end_date=2024-01-31&limit=100" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
{
"data": [
{
"store_id": 12345,
"visitor_id": 456789012,
"session_id": 789012345,
"session_start_dt": "2024-01-15 10:25:00",
"session_end_dt": "2024-01-15 10:45:00",
"session_duration_seconds": 1200,
"is_bounce": 0,
"session_entry_page": "/",
"session_exit_page": "/checkout/success",
"events": 12,
"pageviews": 8,
"add_to_carts": 1,
"initiated_checkouts": 1,
"view_contents": 3,
"contacts": 0,
"newsletter_signups": 0,
"completed_registrations": 0,
"app_installs": 0,
"add_payment_infos": 1,
"adv_source": "meta",
"adv_campaign_id": "120210123456789",
"adv_adgroup_id": "120210987654321",
"adv_ad_id": "120210111222333",
"adv_asset_group_id": "6502489623",
"utm_source": "facebook",
"utm_campaign": "winter_sale",
"utm_medium": "cpc",
"utm_content": "video_ad_1",
"utm_term": "",
"device_type": "desktop",
"country_code": "DE",
"referrer": "https://google.com",
"pathname": "/products",
"hostname": "example.com",
"entry_meta_keys": ["fbclid"],
"entry_meta_values": ["abc123"]
}
],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true,
"next_offset": 100,
"start_date": "2024-01-01 00:00:00",
"end_date": "2024-01-31 23:59:59"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
store_id | integer | Workspace ID |
visitor_id | integer | Visitor identifier |
session_id | integer | Session identifier |
session_start_dt | string | Session start timestamp |
session_end_dt | string | Session end timestamp |
session_duration_seconds | integer | Session duration in seconds |
is_bounce | integer | Whether the session was a bounce (1 = bounce, 0 = not) |
session_entry_page | string | Landing page path |
session_exit_page | string | Exit page path |
events | integer | Total number of events in session |
pageviews | integer | Number of page views |
add_to_carts | integer | Number of add-to-cart events |
initiated_checkouts | integer | Number of checkout starts |
view_contents | integer | Number of content views |
contacts | integer | Number of contact events |
newsletter_signups | integer | Number of newsletter signups |
completed_registrations | integer | Number of completed registrations |
app_installs | integer | Number of app installs |
add_payment_infos | integer | Number of payment info submissions |
adv_source | string | Ad platform source |
adv_campaign_id | string | Campaign ID from ad platform |
adv_adgroup_id | string | Ad group ID from ad platform |
adv_ad_id | string | Ad ID from ad platform |
adv_asset_group_id | string | Asset Group ID (Google Performance Max) |
utm_source | string | UTM source parameter |
utm_campaign | string | UTM campaign parameter |
utm_medium | string | UTM medium parameter |
utm_content | string | UTM content parameter |
utm_term | string | UTM term parameter |
device_type | string | Device type (desktop, mobile, tablet) |
country_code | string | ISO country code |
referrer | string | Referring URL |
pathname | string | Page path |
hostname | string | Website hostname |
entry_meta_keys | array | Click ID parameter names |
entry_meta_values | array | Click ID values |
Conversions
Get conversion event data
Get conversion event data for your workspace. Conversions are tracked when users complete desired actions like purchases, signups, or form submissions.
/v3/conversionsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | Optional | Start date in YYYY-MM-DD format (default: 7 days ago). Alias: from |
end_date | string | Optional | End date in YYYY-MM-DD format (default: today). Alias: to |
name | string | Optional | Filter by conversion name. Supports wildcards with * (e.g. purchase_*) |
source | string | Optional | Filter by acquisition channel of the conversion's session, comma-separated (e.g. creator, meta, email). Alias: sources |
exclude_source | string | Optional | Remove channels from the result, comma-separated (e.g. organic). Applied after source. Alias: exclude_sources |
group_by | string | Optional | Return aggregated rows instead of single conversions. Comma-separated dimensions: utm_campaign, utm_content, utm_source, utm_medium, utm_term, adv_source, adv_campaign_id, adv_adgroup_id, adv_ad_id, name, date, country_code |
transaction_id | string | Optional | Filter by transaction/order ID |
customer_id | string | Optional | Filter by customer ID |
is_new_customer | string | Optional | Filter by new/returning customer (accepts 0, 1, true, false) |
limit | integer | Optional | Number of records to return (default: 100, max: 500). Alias: page_size |
offset | integer | Optional | Number of records to skip for pagination. Alias: page |
curl -X GET "https://api.adverfly.com/v3/conversions?start_date=2024-01-01&end_date=2024-01-31&limit=100" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
{
"data": [
{
"store_id": 12345,
"dt": "2024-01-15 10:42:00",
"name": "purchase",
"session_id": 789012345,
"customer_id": "customer@email.com",
"visitor_id": 456789012,
"transaction_id": "ORD-2024-001",
"is_new_customer": 1,
"transaction_gross_revenue": 12999,
"transaction_currency": "EUR",
"transaction_country_code": "DE",
"transaction_city": "Berlin",
"hostname": "example.com",
"adv_source": "creator",
"adv_campaign_id": "",
"adv_adgroup_id": "",
"adv_ad_id": "",
"utm_source": "instagram",
"utm_medium": "creator",
"utm_campaign": "spring_launch",
"utm_content": "",
"utm_term": ""
}
],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true,
"next_offset": 100,
"start_date": "2024-01-01 00:00:00",
"end_date": "2024-01-31 23:59:59",
"sources": null
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
store_id | integer | Workspace ID |
dt | string | Conversion timestamp |
name | string | Conversion type (e.g. purchase, lead) |
session_id | integer | Session identifier |
customer_id | string | Customer identifier (e.g. email) |
visitor_id | integer | Visitor identifier |
transaction_id | string | Order/transaction ID |
is_new_customer | integer | 1 for a first-time customer, 0 for a returning one |
transaction_gross_revenue | integer | Revenue in cents (e.g. 12999 = 129.99) |
transaction_currency | string | Currency code (EUR, USD, etc.) |
transaction_country_code | string | ISO country code |
transaction_city | string | Customer's city |
hostname | string | Website hostname |
adv_source | string | Acquisition channel of the session the conversion happened in. Untagged sessions are reported as organic, matching the dashboard |
adv_campaign_id | string | Platform campaign ID of that session |
adv_adgroup_id | string | Platform ad group ID of that session |
adv_ad_id | string | Platform ad ID of that session |
utm_source | string | UTM source of that session |
utm_medium | string | UTM medium of that session |
utm_campaign | string | UTM campaign of that session |
utm_content | string | UTM content of that session |
utm_term | string | UTM term of that session |
Filtering by channel
Pass source to return only conversions from a given acquisition channel — for example every purchase driven by a creator:
curl -X GET "https://api.adverfly.com/v3/conversions?source=creator&name=purchase&start_date=2024-01-01&end_date=2024-01-31&limit=500" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
source=creator also matches rows recorded before the 2026-07-24 rename, which carry adv_source: "influencer" — you never have to ask for both spellings.
Excluding channels
exclude_source removes channels instead of selecting them — the usual case being "everything except organic":
curl -X GET "https://api.adverfly.com/v3/conversions?name=purchase&exclude_source=organic&group_by=adv_source&start_date=2024-01-01&end_date=2024-01-31" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
A session with no source counts as organic, exactly as it does in the dashboard — so exclude_source=organic also drops untagged traffic, and source=organic returns it. This is usually the largest bucket, so the difference is not cosmetic.
exclude_source runs after source and is never widened by permissions: it can only narrow what a key already sees.
Note that this excludes conversions whose own session came from that channel. The dashboard's attribution setting of the same name works one level deeper — it drops the channel from the attribution path so credit moves to the previous eligible touchpoint. With a single-touch endpoint the two agree; under a multi-touch model they do not.
Breakdowns
Add group_by to get aggregated rows instead of one row per conversion — for example revenue per creator:
curl -X GET "https://api.adverfly.com/v3/conversions?source=creator&name=purchase&group_by=utm_campaign&start_date=2024-01-01&end_date=2024-01-31" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
{
"data": [
{
"utm_campaign": "spring_launch",
"conversions": 73,
"revenue": 911545,
"new_customers": 45,
"unique_customers": 73
}
],
"pagination": { "limit": 100, "offset": 0, "has_more": false, "next_offset": null }
}
| Metric | Description |
|---|---|
conversions | Number of conversions in the group |
revenue | Summed gross revenue in cents |
new_customers | Conversions where is_new_customer is 1 |
unique_customers | Distinct customer_id values |
Aggregate values are JSON numbers. Row-level responses keep IDs and counters as strings, which is how they have always been returned — a group_by response is a new shape, so it does not inherit that.
Dimensions combine — group_by=utm_campaign,date gives one row per creator per day. Rows are sorted by revenue, except when date is among the dimensions, where they are sorted chronologically.
This is not what the Creators app reports. A breakdown here counts purchases whose own session carried the creator tag. The app credits a creator touchpoint up to the attribution window before the purchase, so a visitor who arrives through a creator and buys three days later from a bookmark counts for the app and not here. On a real workspace the difference is a multiple, not a rounding error. Use
/v3/reportfor numbers that match the app.
Which dimension is "a creator" depends on how your links are tagged. Most workspaces put the creator in utm_campaign (this is what the Creators app breaks down by), some use utm_content. Run group_by=utm_campaign,utm_content once to see which field carries the names.
Notes
- Revenue is returned in the smallest currency unit (cents). Divide by 100 for the main currency value.
- Use
transaction_idorcustomer_idfilters to look up specific orders or customers. - Channel fields describe the session the conversion happened in — session-level last touch. They are not a multi-touch attribution model: a purchase whose visitor first arrived through a creator and returned later via a direct visit is reported as direct here. For first-click, linear or U-shaped attribution use the MCP server.
- An unknown value in
sourcereturns400rather than being ignored, so a typo can never silently widen the result to all channels.
Ads
Get advertising performance data
Get advertising performance data for your workspace. Returns spend, impressions, clicks, and reach from connected ad platforms (Meta, Google, TikTok, etc.).
/v3/adsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | Optional | Start date in YYYY-MM-DD format. Defaults to 7 days ago if omitted. |
end_date | string | Optional | End date in YYYY-MM-DD format. Defaults to today if omitted. |
source | string | Optional | Filter by ad platform. Comma-separated for multiple (e.g. meta,google) |
adaccount_id | string | Optional | Filter by ad account ID |
campaign_id | string | Optional | Filter by campaign ID |
adgroup_id | string | Optional | Filter by ad group ID |
ad_id | string | Optional | Filter by ad ID |
limit | integer | Optional | Number of records to return (default: 100) |
offset | integer | Optional | Number of records to skip for pagination |
Supported sources
| Value | Platform |
|---|---|
meta | Meta (includes facebook, instagram, messenger, audience_network, threads) |
facebook | Facebook (subset of Meta) |
instagram | Instagram (subset of Meta) |
google | Google Ads |
tiktok | TikTok Ads |
pinterest | Pinterest Ads |
snapchat | Snapchat Ads |
outbrain | Outbrain |
taboola | Taboola |
organic | Organic traffic |
audience_network | Meta Audience Network (subset of Meta) |
messenger | Meta Messenger (subset of Meta) |
threads | Meta Threads (subset of Meta) |
whatsapp | |
email | Email channels |
curl -X GET "https://api.adverfly.com/v3/ads?start_date=2024-01-01&end_date=2024-01-31&source=meta,google&limit=100" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
{
"data": [
{
"store_id": 12345,
"dt": "2024-01-15",
"adaccount_id": "act_123456789",
"source": "meta",
"campaign_id": "120210123456789",
"campaign_name": "Winter Sale 2024",
"adgroup_id": "120210987654321",
"adgroup_name": "Lookalike - Purchases",
"ad_id": "120210111222333",
"ad_name": "Video - Snow Jacket",
"spend": 4500,
"impressions": 12340,
"clicks": 287,
"reach": 9800
}
],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": true,
"next_offset": 100,
"start_date": "2024-01-01 00:00:00",
"end_date": "2024-01-31 23:59:59",
"sources": ["meta", "google"]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
store_id | integer | Your workspace ID |
dt | string | Date of the ad data (YYYY-MM-DD) |
adaccount_id | string | Ad account identifier |
source | string | Ad platform (meta, google, tiktok, etc.) |
campaign_id | string | Campaign identifier |
campaign_name | string | Campaign name |
adgroup_id | string | Ad group identifier |
adgroup_name | string | Ad group name |
ad_id | string | Ad identifier |
ad_name | string | Ad name |
spend | integer | Spend in smallest currency unit (cents) |
impressions | integer | Number of impressions |
clicks | integer | Number of clicks |
reach | integer | Number of unique users reached (0 if not reported by platform) |
Totals
The ads endpoint also returns a totals object at the top level with aggregated values:
{
"totals": {
"total_ads": 500,
"total_spend": 123456,
"total_impressions": 9876543,
"total_clicks": 54321,
"total_reach": 7654321
},
"data": [...],
"pagination": { ... }
}
Notes
- Spend is returned in the smallest currency unit (e.g. cents). Divide by 100 to get the value in the main currency unit.
- Reach may be 0 for platforms that do not report it (e.g. Google Ads).
- Data is deduplicated per ad per day. If the same ad data is imported multiple times, only the latest version is returned.
- Requires
read:<source>oradmin:adminpermission on your API key.
Report
The dashboard's own aggregated numbers over HTTP
Returns the same aggregates your dashboard shows — metrics × breakdown × attribution model — instead of raw rows.
/v3/reportThis endpoint does not compute anything of its own. It runs the query engine behind /summary and /insights and applies your workspace's display settings, so a /v3/report call and the equivalent screen return the same numbers. Use /v3/conversions when you want individual conversions, and /v3/report when you want totals that have to reconcile with the UI.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | Optional | Start date in YYYY-MM-DD format (default: 7 days ago). Alias: from |
end_date | string | Optional | End date in YYYY-MM-DD format, inclusive (default: today). Alias: to |
metrics | string | Optional | Comma-separated metrics (default: spend, revenue, roas, conversions, sessions) |
breakdown | string | Optional | One of: source, campaign, adgroup, ad, utm_source, utm_campaign, utm_medium, utm_term, utm_content, referrer. Omit for totals only |
interval | string | Optional | Time bucketing, e.g. day, week, month. Omit for a single period |
attribution_model | string | Optional | last_click (default), first_click, linear, u_shaped, total_impact |
attribution_window | integer | Optional | Lookback in days: 1, 7 (default), 28, 90, 180, 365 |
attribution_date | string | Optional | Whether the window is measured from the click or the conversion: conversion (default) or click |
source | string | Optional | Restrict to channels, comma-separated. Alias: sources |
exclude_source | string | Optional | Drop channels from the attribution path — credit moves to the previous eligible touchpoint. Same as the dashboard's ignore-sources setting |
name | string | Optional | Conversion name filter, e.g. purchase |
limit | integer | Optional | Rows per page (default: 100, max: 500) |
offset | integer | Optional | Rows to skip for pagination |
Available metrics
spend, revenue, roas, ctr, cpa, cr, sessions, conversions, impressions, clicks, new_customers, add_to_carts, checkouts
Profit-ladder metrics — cogs, payment_fees, shipping_costs, refunds, gross_profit, contribution_profit, net_profit, gross_margin, net_margin, net_roas — require the read:profit permission on the API key. Requesting one without it returns 403.
curl -X GET "https://api.adverfly.com/v3/report?metrics=revenue,conversions,roas&breakdown=utm_campaign&source=creator&attribution_model=first_click&attribution_window=1&exclude_source=organic&name=purchase&start_date=2024-01-24&end_date=2024-01-30" \
-H "x-api-key: your-api-key" \
-H "client-secret: your-client-secret"
{
"data": [
{
"utm_campaign": "spring_launch",
"revenue": 9115.45,
"conversions": 73,
"roas": 4.2
}
],
"pagination": {
"limit": 100,
"offset": 0,
"has_more": false,
"next_offset": null,
"total_rows": 1,
"start_date": "2024-01-24 00:00:00",
"end_date": "2024-01-30 23:59:59",
"sources": ["creator", "influencer"],
"ignored_sources": ["organic"]
}
}
What comes from your workspace settings
These are read per request and applied exactly as the dashboard applies them — they are not parameters:
- Include unattributed — whether platform-side orders without a pixel match get their own row
- Net merchandise revenue — whether tax and shipping are subtracted from revenue
- Refund netting, excluded transaction IDs, platform revenue resolution and the new-customer correction all happen inside the engine
Change them in the workspace settings and this endpoint follows on the next call. That is the trade: parity with the UI, not an independently tunable API.
report vs conversions
/v3/report | /v3/conversions | |
|---|---|---|
| Returns | Aggregates | One row per conversion |
| Attribution | All models, configurable window | Session-level last touch, fixed |
| Revenue | Platform revenue when matched, refunds netted, workspace settings applied | Raw pixel gross |
| Reconciles with the dashboard | Yes | No — it counts the session a purchase happened in, not the touchpoint that earned the credit. Expect a multiple, not a rounding difference |
| Use it for | Reporting, BI dashboards, alerting | Row exports, order lookups, joining to your own data |
Notes
- Money is returned in the workspace currency, not in cents —
9115.45means 9,115.45 €. This differs from/v3/conversions, which returns raw pixel values in cents. Ratio metrics (roas,net_roas) are plain factors, percentages (ctr,cr,gross_margin,net_margin) are fractions:0.2641means 26.41 %. - A metric that cannot be computed for a row — ROAS without spend, CR without sessions — returns
nullrather than0, so an empty channel is not reported as a zero-performance one. exclude_sourcehere removes the channel from the attribution path, not the row — credit moves to the previous eligible touchpoint. On/v3/conversionsthe same parameter removes rows. The names match the dashboard, where the setting is likewise an attribution setting.- Excluding the creator channel covers both
creatorandinfluencer, so pre-rename data is not half-counted. - Pagination is applied to the aggregated rows, so
total_rowstells you how many groups the breakdown produced.
Errors
API error codes and handling
The Adverfly API uses standard HTTP status codes to indicate the success or failure of requests.
HTTP Status Codes
| Status Code | Status | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 400 | Bad Request | Missing required headers or invalid parameters |
| 401 | Unauthorized | Invalid API key or client secret |
| 403 | Forbidden | Valid credentials but insufficient permissions for the requested source |
| 404 | Not Found | Requested endpoint does not exist |
| 405 | Method Not Allowed | HTTP method not supported |
| 429 | Too Many Requests | Rate limit exceeded (enforced at API Gateway level) |
| 500 | Internal Server Error | Unexpected server error |
Error Response Format
When an error occurs, the API returns a JSON object with a message field:
{
"message": "Invalid API key"
}
Common Error Messages
| Code | Description |
|---|---|
Missing x-api-key header | The x-api-key header was not included in the request (HTTP 400) |
Missing client-secret header | The client-secret header was not included in the request (HTTP 400) |
Invalid API key | The provided API key does not exist or has been revoked (HTTP 401) |
Invalid client secret | The client secret does not match the API key (HTTP 401) |
You do not have access to pixel data | Your API key does not have pixel read permissions (HTTP 403) |
You do not have access to ads data | Your API key does not have ads read permissions (HTTP 403) |
You do not have access to the requested sources | Your API key lacks permission for one or more of the requested source platforms (HTTP 403) |
Unknown source: ... | The source filter contains a value the API does not know. The message lists every accepted source (HTTP 400) |
Invalid start_date or end_date parameter | Date must be in YYYY-MM-DD format (HTTP 400) |
start_date must be before end_date | The start date is after the end date (HTTP 400) |
limit must be a positive integer | The limit parameter must be a positive number (HTTP 400) |
offset must be a non-negative integer | The offset parameter cannot be negative (HTTP 400) |
session_id must be numeric | The session_id filter must be a number (HTTP 400) |
visitor_id must be numeric | The visitor_id filter must be a number (HTTP 400) |
is_new_customer must be one of 0,1,true,false | Invalid value for is_new_customer filter (HTTP 400) |
Method not allowed | The HTTP method used is not supported — use GET (HTTP 405) |
Permissions
API keys use a source-based permission system. Each key can have permissions like read:meta, read:google, etc. Use admin:admin for full access to all sources.
read:creators grants the creator channel — a key holding only that permission reads creator traffic and nothing else.
If you request ads from a source your key does not have permission for, you will receive a 403 Forbidden response.
MCP Server
Query your Adverfly workspace from Claude Desktop, Cursor, or any MCP-compatible client
Adverfly exposes its analytics tools as a Model Context Protocol server. Any MCP-compatible client (Claude Desktop, Cursor, custom agents) can query your workspace data using the same tools the in-product Cortex agent uses — analytics, MMM results, recommendations, attribution, creative performance, and more.
/mcpWhat it gives you
- A read-only view of every Cortex analytics tool, exposed via JSON-RPC 2.0
- Workspace-scoped — the API key picks the workspace (or several, see below)
- Same permission model as the Data API (per-source access controlled by key permissions)
A small set of draft-safe write tools is exposed too: create custom reports and (disabled-by-default) workflows, and build Canvas lists — create lists/whiteboards, add columns and rows, link top creatives. List writes are additive only; there are no delete tools. Other side-effect tools (save note, generate image, send export) stay unexposed.
Authentication
Send your Adverfly API key + client secret in a single Bearer header:
Authorization: Bearer <api_key>:<client_secret>
The two values are separated by a colon. You can also use the standard x-api-key + client-secret headers if your MCP client prefers that.
Generate credentials in Workspace Settings → API Keys.
Multiple workspaces on one connection
When you connect via OAuth (the claude.ai "Add Custom Connector" flow), the consent screen lets you select several workspaces for a single connection — the same way Meta's MCP spans several ad accounts. On a multi-workspace connection:
- Every tool gains a required
workspace_idparameter routing the call to one workspace - A
workspaces_listtool returns the authorized workspaces (id + name) - Each workspace keeps its own permission snapshot — access mirrors your role in that workspace at connect time
Connections scoped to a single workspace are unchanged: no workspace_id parameter, no workspaces_list tool.
Methods
The endpoint speaks JSON-RPC 2.0. Three methods:
| Method | Auth | Description |
|---|---|---|
initialize | No | Server handshake — returns protocol version + server info |
tools/list | Yes | List all available tools with descriptions and (open) input schemas |
tools/call | Yes | Execute a tool. Params: { name, arguments } |
Connecting from Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"adverfly": {
"url": "https://api.adverfly.com/mcp",
"headers": {
"Authorization": "Bearer <api_key>:<client_secret>"
}
}
}
}
Restart Claude Desktop. The Adverfly tools appear in the tools menu and Claude can call them in conversation.
Connecting from Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"adverfly": {
"url": "https://api.adverfly.com/mcp",
"headers": {
"Authorization": "Bearer <api_key>:<client_secret>"
}
}
}
}
Quick test from the terminal
List available tools:
curl -X POST https://api.adverfly.com/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <api_key>:<client_secret>' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Call a tool — e.g. an analytics query for the last 7 days:
curl -X POST https://api.adverfly.com/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <api_key>:<client_secret>' \
-d '{
"jsonrpc":"2.0",
"id":2,
"method":"tools/call",
"params":{
"name":"analytics.query",
"arguments":{
"metrics":["spend","revenue","roas"],
"filters":{"date_from":"2026-05-10","date_to":"2026-05-17"}
}
}
}'
Available tools
The MCP surface starts small on purpose. Call tools/list to see what's live today.
v1 — one tool:
analytics.query— flexible query for any metric (spend, revenue, ROAS, sessions, conversions, profit ladder, etc.) × breakdown (channel, campaign, creative, country, …) × date range × source filter × attribution model (last_click,first_click,linear,u_shaped,total_impact). There is no campaign/ad filter parameter — to read a single campaign or ad, setbreakdown(e.g.campaign_id) and read that entity's row; the Totals block always covers the whole selected scope.analytics.profit-summary— full profit ladder for a date range: revenue, refunds, COGS, payment fees, shipping costs, gross/contribution/net profit, margins and Net-ROAS.
Profit metrics (cogs, payment_fees, gross_profit, contribution_profit, net_profit, gross_margin, net_margin, net_roas) require the read:profit permission on the API key — without it, profit requests return a permission error.
This single tool covers most "show me X" questions.
Canvas list tools (write, additive-only):
lists.get-lists— all Canvas lists with columns and itemslists.create— new list or whiteboard (kind), optionally inside a folderlists.add-column/lists.add-items/lists.update-items— build out columns and rows; rows can link workspace entities (creatives, campaigns, products, …)lists.add-top-creatives— one-shot: rank the workspace's creatives by ROAS/revenue/spend/CTR and add the top N as linked rows
There are deliberately no delete tools — a mistaken row is removed in the Canvas UI. Other side-effect tools stay scoped to the in-product MCP app with its human-approval gate.
Error responses
JSON-RPC error envelope:
{
"jsonrpc": "2.0",
"id": 1,
"error": { "code": -32001, "message": "Invalid API key" }
}
| Code | Meaning |
|---|---|
-32700 | Parse error — request body is not valid JSON |
-32600 | Invalid request — missing method |
-32601 | Unknown method or unknown tool name |
-32602 | Invalid params for the tool |
-32001 | Auth failure (missing / invalid API key) |
-32603 | Internal server error |
HTTP status is 200 for all JSON-RPC responses, including errors — check the error field in the body.