Endpoints
Server-rendered from the OpenAPI document so crawlers and agents can read paths, parameters,
and examples without executing JavaScript.
ConvertFlow's public v1 API. Endpoints are grouped by namespace, listed in the tags below.
## Authentication
ConvertFlow uses OAuth 2.1 (authorization code + PKCE). Obtain a token from ConvertFlow
and send it as `Authorization: Bearer `. Tokens are website-scoped, so a token
authenticates only for the website(s) you selected when you authorized it. The
`website_id` query param must be one of the token's websites. You can omit it for
single-website tokens, and it's required when the token grants multiple websites
(`GET /api/v1/reports/websites` lists them).
(ConvertFlow also accepts the legacy `Authorization: api_key=` scheme until a
website generates its first OAuth token. That scheme is not scope-restricted.)
### Permissions (scopes)
OAuth tokens carry resource + read/write scopes that you choose at creation, and
ConvertFlow enforces them on every request: `reports` (read analytics),
`contacts:read`/`contacts:write`, `ctas:read`/`ctas:write`, `areas:read`, and
`websites:read`. A request whose token lacks the required scope returns `403`.
## Reports
These read-only endpoints report on funnel performance: website totals, campaigns, A/B
experiments, variant/step/element funnel breakdowns, and the pre-generated weekly
insights snapshot. Most reports endpoints accept a `timeframe` enum
(default `last_30_days`) plus optional `range_start`/`range_end` (ISO 8601, required when
`timeframe=custom`). Account-wide endpoints under `/api/v1/reports/account` aggregate
every website bound to the token and do not require `website_id`.
ConvertFlow stores metrics per day, so any custom range is exact, down to a single day.
The single-subject reports (website, campaign, variant, step, element) also accept
`group_by` (`day`, `week`, `month`, `quarter`, `year`) and return a zero-filled
`timeseries` block alongside the totals, so a daily breakdown takes one request.
## MCP Server
ConvertFlow also exposes this API as a remote MCP server for AI agents
(`https://mcp.convertflow.co/mcp`). For the setup guide and tool reference, see
[developers.convertflow.com/developers/mcp](https://developers.convertflow.com/developers/mcp).
Areas
GET /api/v1/areas
List areas
Returns the website's areas (newest first).
Example request
curl -X GET https://app.convertflow.co/api/v1/areas \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
[
{
"id": 0,
"name": "string",
"website_id": 0,
"created_at": "2017-07-21T17:32:28Z",
"updated_at": "2017-07-21T17:32:28Z"
}
]
Contacts
GET /api/v1/contacts
List contacts
Returns the website's contacts (paginated, 25 per page). Authenticates with a website-bound Bearer token, or the legacy api_key until migrated.
| Parameter | In | Type | Description |
email |
query |
string |
Filter by exact email |
id |
query |
integer |
Filter by contact id |
Example request
curl -X GET https://app.convertflow.co/api/v1/contacts \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
[
{
"id": 0,
"created_at": "2017-07-21T17:32:28Z",
"updated_at": "2017-07-21T17:32:28Z",
"website_id": 0,
"visitor_token": "550e8400-e29b-41d4-a716-446655440000",
"email": "string",
"name": "string",
"last_name": "string",
"phone": "string",
"city": "string",
"avatar_url": "string",
"company_name": "string",
"company_title": "string",
"url": "string",
"state": "string",
"address": "string",
"zip_code": "string",
"country": "string",
"source_url": "string",
"bio": "string",
"utm_source": "string",
"utm_medium": "string",
"utm_campaign": "string",
"utm_term": "string",
"utm_content": "string",
"referral_source": "string",
"first_visit": "string",
"privacy_consent": "string",
"marketing_consent": "string",
"sms_consent": "string",
"ip_address": "string",
"latest_score": "string",
"extra": {
},
"data": {
},
"tags": "string",
"link": "string"
}
]
POST /api/v1/contacts
Create or update a contact
Upserts a contact by email/phone. At least one of email or phone is required; additional custom fields are accepted and stored on the contact.
Example request
curl -X POST https://app.convertflow.co/api/v1/contacts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"string","phone":"string","first_name":"string","last_name":"string"}'
Example response
{
"id": 0,
"created_at": "2017-07-21T17:32:28Z",
"updated_at": "2017-07-21T17:32:28Z",
"website_id": 0,
"visitor_token": "string",
"email": "string",
"name": "string",
"last_name": "string",
"phone": "string",
"city": "string",
"avatar_url": "string",
"company_name": "string",
"company_title": "string",
"url": "string",
"state": "string",
"address": "string",
"zip_code": "string",
"country": "string",
"source_url": "string",
"bio": "string",
"utm_source": "string",
"utm_medium": "string",
"utm_campaign": "string",
"utm_term": "string",
"utm_content": "string",
"referral_source": "string",
"first_visit": "string",
"privacy_consent": "string",
"marketing_consent": "string",
"sms_consent": "string",
"ip_address": "string",
"latest_score": "string",
"extra": {
},
"data": {
},
"tags": "string",
"link": "string"
}
DELETE /api/v1/contacts
Delete a contact by email
| Parameter | In | Type | Description |
email * |
query |
string |
|
Example request
curl -X DELETE https://app.convertflow.co/api/v1/contacts \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"message": "string"
}
Campaigns
GET /api/v1/cta
List campaigns
Returns the website's non-archived campaigns (newest first), each with its variants.
Example request
curl -X GET https://app.convertflow.co/api/v1/cta \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
[
{
"id": 0,
"website_id": 0,
"name": "string",
"views": 0,
"conversions": 0,
"completions": 0,
"conversion_rate": "string",
"completion_rate": "string",
"page_path": "string",
"cta_type": "string",
"test_type": "string",
"created_at": "2017-07-21T17:32:28Z",
"updated_at": "2017-07-21T17:32:28Z",
"variants": [
{
"id": 0,
"name": "string",
"variation": "string",
"percentage": 0,
"created_at": "2017-07-21T17:32:28Z",
"updated_at": "2017-07-21T17:32:28Z",
"screenshot": null,
"website_id": 0,
"views": 0,
"conversions": 0,
"completions": 0,
"conversion_rate": "string",
"completion_rate": "string"
}
]
}
]
Reports
GET /api/v1/reports/account/performance
Account-wide website performance
Aggregate and per-website funnel metrics for every website bound to the token. Omit website_id to include all bound sites; pass website_id or website_ids to subset. Does not require website_id on multi-website tokens.
| Parameter | In | Type | Description |
website_id |
query |
integer |
Optional. When set, limits the report to this bound website. Omit to aggregate every website bound to the token. Unbound ids return 404. Non-positive or non-numeric ids return 422 invalid_website_id. |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
website_ids |
query |
array |
Optional subset of bound website ids. Any id outside the token binding returns 404. Non-positive or non-numeric ids return 422 invalid_website_id. |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/account/performance \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"timeframe": {
"selected": "string",
"label": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"previous_range_start": "2017-07-21T17:32:28Z",
"previous_range_end": "2017-07-21T17:32:28Z"
},
"data": {
"aggregate": {
"website_count": 0,
"viewers": 0.0,
"conversions": 0.0,
"conversion_rate": 0.0,
"subscribes": 0.0,
"subscribe_rate": 0.0,
"orders": 0.0,
"order_rate": 0.0,
"revenue": 0.0,
"aov": 0.0
},
"websites": [
{
"id": 0,
"name": "string",
"viewers": 0.0,
"conversions": 0.0,
"conversion_rate": 0.0,
"conversions_change": 0.0,
"revenue_change": 0.0,
"subscribes": 0.0,
"orders": 0.0,
"revenue": 0.0,
"aov": 0.0
}
]
}
}
GET /api/v1/reports/campaigns
List campaigns with metrics
| Parameter | In | Type | Description |
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
page |
query |
integer |
|
per_page |
query |
integer |
|
sort |
query |
string |
|
cta_type |
query |
string |
Filter by campaign format. |
status |
query |
string |
|
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/campaigns \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string"
},
"data": {
"campaigns": [
{
"id": 0,
"name": "string",
"cta_type": "string",
"status": "string",
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
}
}
],
"pagination": {
"page": 0,
"per_page": 0,
"total_entries": 0,
"total_pages": 0
}
}
}
GET /api/v1/reports/campaigns/{id}
Campaign performance + variants
| Parameter | In | Type | Description |
id * |
path |
integer |
|
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
group_by |
query |
string |
When set, the response gains a `timeseries` object alongside `metrics`: one point per bucket over the same window, each with date, views, conversions, completions, subscribes, submissions, orders and revenue (points carry submissions even where the metrics block does not). Buckets with no activity are returned as zeroes. Under the default count_type=distinct each bucket counts unique visitors within that bucket, so the points do not sum to the headline total (a visitor active on three days counts once overall and three times across the daily points); use count_type=total when the buckets must reconcile. An unrecognized value returns 422 invalid_group_by. On the website report the window may cover at most 92 days (campaign, variant, step and element reports take any range); a range that would exceed 400 points is rejected too. Both return 422 range_too_wide. |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/campaigns/{id} \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string",
"previous_range_start": "2017-07-21T17:32:28Z",
"previous_range_end": "2017-07-21T17:32:28Z"
},
"data": {
"id": 0,
"name": "string",
"cta_type": "string",
"status": "string",
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0,
"previous": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
},
"changes": {
"views": 0.0,
"conversions": 0.0,
"completions": null,
"submissions": null,
"subscribes": null,
"orders": null,
"revenue": null,
"conversion_rate": 0.0,
"completion_rate": null,
"subscribe_rate": null,
"order_rate": null,
"aov": null
}
},
"timeseries": {
"group_by": "string",
"points": [
{
"date": "2017-07-21",
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"submissions": 0,
"orders": 0,
"revenue": 0.0
}
]
},
"variants": [
{
"id": 0,
"name": null,
"variation": "string",
"traffic_percentage": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
}
}
]
}
}
GET /api/v1/reports/elements/{id}
Element performance + field/product breakdown
| Parameter | In | Type | Description |
id * |
path |
integer |
|
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
group_by |
query |
string |
When set, the response gains a `timeseries` object alongside `metrics`: one point per bucket over the same window, each with date, views, conversions, completions, subscribes, submissions, orders and revenue (points carry submissions even where the metrics block does not). Buckets with no activity are returned as zeroes. Under the default count_type=distinct each bucket counts unique visitors within that bucket, so the points do not sum to the headline total (a visitor active on three days counts once overall and three times across the daily points); use count_type=total when the buckets must reconcile. An unrecognized value returns 422 invalid_group_by. On the website report the window may cover at most 92 days (campaign, variant, step and element reports take any range); a range that would exceed 400 points is rejected too. Both return 422 range_too_wide. |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/elements/{id} \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string"
},
"data": {
"id": 0,
"element_type": "string",
"position": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
},
"timeseries": {
"group_by": "string",
"points": [
{
"date": "2017-07-21",
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"submissions": 0,
"orders": 0,
"revenue": 0.0
}
]
},
"fields": [
],
"products": [
{
"value": null,
"selections": 0,
"orders": 0,
"revenue": 0.0
}
]
}
}
GET /api/v1/reports/experiments
Active experiments (live traffic-split variants)
| Parameter | In | Type | Description |
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
limit |
query |
integer |
|
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/experiments \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string"
},
"data": {
"experiments": [
{
"campaign_id": 0,
"campaign_name": "string",
"cta_type": "string",
"variants": [
{
"id": 0,
"name": null,
"variation": "string",
"traffic_percentage": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
}
}
]
}
]
}
}
GET /api/v1/reports/steps/{id}
Step funnel + elements
| Parameter | In | Type | Description |
id * |
path |
integer |
|
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
group_by |
query |
string |
When set, the response gains a `timeseries` object alongside `metrics`: one point per bucket over the same window, each with date, views, conversions, completions, subscribes, submissions, orders and revenue (points carry submissions even where the metrics block does not). Buckets with no activity are returned as zeroes. Under the default count_type=distinct each bucket counts unique visitors within that bucket, so the points do not sum to the headline total (a visitor active on three days counts once overall and three times across the daily points); use count_type=total when the buckets must reconcile. An unrecognized value returns 422 invalid_group_by. On the website report the window may cover at most 92 days (campaign, variant, step and element reports take any range); a range that would exceed 400 points is rejected too. Both return 422 range_too_wide. |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/steps/{id} \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string"
},
"data": {
"id": 0,
"position": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
},
"timeseries": {
"group_by": "string",
"points": [
{
"date": "2017-07-21",
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"submissions": 0,
"orders": 0,
"revenue": 0.0
}
]
},
"elements": [
{
"id": 0,
"element_type": "string",
"position": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
}
}
]
}
}
GET /api/v1/reports/variants/{id}
Variant funnel + steps
| Parameter | In | Type | Description |
id * |
path |
integer |
|
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
group_by |
query |
string |
When set, the response gains a `timeseries` object alongside `metrics`: one point per bucket over the same window, each with date, views, conversions, completions, subscribes, submissions, orders and revenue (points carry submissions even where the metrics block does not). Buckets with no activity are returned as zeroes. Under the default count_type=distinct each bucket counts unique visitors within that bucket, so the points do not sum to the headline total (a visitor active on three days counts once overall and three times across the daily points); use count_type=total when the buckets must reconcile. An unrecognized value returns 422 invalid_group_by. On the website report the window may cover at most 92 days (campaign, variant, step and element reports take any range); a range that would exceed 400 points is rejected too. Both return 422 range_too_wide. |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/variants/{id} \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string"
},
"data": {
"id": 0,
"name": null,
"variation": "string",
"traffic_percentage": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
},
"timeseries": {
"group_by": "string",
"points": [
{
"date": "2017-07-21",
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"submissions": 0,
"orders": 0,
"revenue": 0.0
}
]
},
"funnel_steps": [
{
"id": 0,
"position": 0,
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"submissions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
}
}
]
}
}
GET /api/v1/reports/website
Website performance
| Parameter | In | Type | Description |
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
timeframe |
query |
string |
|
range_start |
query |
string |
Required when timeframe=custom (ISO 8601) |
range_end |
query |
string |
|
count_type |
query |
string |
Count mode for the funnel metrics (views, conversions, completions, subscribes, submissions). distinct = unique visitors via HyperLogLog (default); total = raw event count. Orders and revenue are always summed regardless. Ignored on timeframe=insights_week (the weekly snapshot stores distinct counts only). An unrecognized value returns 422 invalid_count_type. |
previous_period |
query |
boolean |
When true, each metrics block gains a nested `previous` object (same shape, for the immediately preceding period of equal length) and a `changes` object with the percent change per metric (null when the prior value is unavailable). The compared window is echoed as previous_range_start/previous_range_end in the timeframe block. No effect on timeframe=all_time (no prior period) or timeframe=insights_week. |
group_by |
query |
string |
When set, the response gains a `timeseries` object alongside `metrics`: one point per bucket over the same window, each with date, views, conversions, completions, subscribes, submissions, orders and revenue (points carry submissions even where the metrics block does not). Buckets with no activity are returned as zeroes. Under the default count_type=distinct each bucket counts unique visitors within that bucket, so the points do not sum to the headline total (a visitor active on three days counts once overall and three times across the daily points); use count_type=total when the buckets must reconcile. An unrecognized value returns 422 invalid_group_by. On the website report the window may cover at most 92 days (campaign, variant, step and element reports take any range); a range that would exceed 400 points is rejected too. Both return 422 range_too_wide. |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/website \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"timeframe": {
"selected": "string",
"range_start": "2017-07-21T17:32:28Z",
"range_end": "2017-07-21T17:32:28Z",
"timezone": "string",
"previous_range_start": "2017-07-21T17:32:28Z",
"previous_range_end": "2017-07-21T17:32:28Z"
},
"data": {
"metrics": {
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0,
"previous": {
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"orders": 0,
"revenue": 0.0,
"conversion_rate": 0.0,
"completion_rate": 0.0,
"subscribe_rate": 0.0,
"order_rate": 0.0,
"aov": 0.0
},
"changes": {
"views": 0.0,
"conversions": null,
"completions": null,
"subscribes": null,
"orders": null,
"revenue": null,
"conversion_rate": null,
"completion_rate": null,
"subscribe_rate": null,
"order_rate": null,
"aov": null
}
},
"timeseries": {
"group_by": "string",
"points": [
{
"date": "2017-07-21",
"views": 0,
"conversions": 0,
"completions": 0,
"subscribes": 0,
"submissions": 0,
"orders": 0,
"revenue": 0.0
}
]
}
}
}
GET /api/v1/reports/website/insights
Latest weekly insights snapshot
| Parameter | In | Type | Description |
website_id |
query |
integer |
Website id. Must be one of the token's websites. Optional for single-website tokens (derived from the binding); required when the token grants multiple websites (400 website_id_required otherwise). |
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/website/insights \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"report": "string",
"website": {
"id": 0,
"name": "string",
"currency": "string"
},
"data": {
"week": "2017-07-21",
"performance_snapshot": {
"performance": {
"revenue": 0.0,
"viewers": 0
}
},
"ai_recommendations": {
"items": [
"string"
]
}
}
}
GET /api/v1/reports/websites
Websites the token grants access to
Lists the websites bound to the access token. Use the returned ids as the website_id query param on the other reports endpoints.
Example request
curl -X GET https://app.convertflow.co/api/v1/reports/websites \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"websites": [
{
"id": 0,
"name": "string",
"account_id": 0,
"account_name": "string",
"created_at": "2017-07-21T17:32:28Z"
}
]
}
Website
GET /api/v1/websites
Get the authenticated website
Returns the website the credential is bound to. The `name` field is the website root domain name (e.g. example.com).
Example request
curl -X GET https://app.convertflow.co/api/v1/websites \
-H "Authorization: Bearer YOUR_TOKEN"
Example response
{
"id": 0,
"name": "string",
"user_id": null,
"created_at": "2017-07-21T17:32:28Z",
"updated_at": "2017-07-21T17:32:28Z",
"url": null,
"listener": true,
"published": null,
"visitors_count": null,
"active": true,
"account_id": 0,
"screenshot": null,
"data": {
"form-tracking": "string",
"last_published": "string",
"url-identification": "string",
"google-analytics-track": "string"
},
"script_type": "string",
"test": true,
"blacklisted": true,
"brand": "string",
"api_key": "string",
"powered_by": true,
"sub_domain": "string",
"archived": true,
"premium": true,
"conversions": 0,
"completions": 0,
"plan_type": "string",
"support": true,
"context": null,
"research": null,
"context_last_updated": null
}