ConvertFlow ConvertFlow
Open ConvertFlow →

ConvertFlow REST API Reference

OAuth 2.1 bearer tokens, token scopes, and endpoints for contacts, campaigns, and funnel analytics reports. The playground below is interactive; the endpoint reference is also in this page as HTML.

API v1 · Last updated September 9, 2026

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.

ParameterInTypeDescription
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

ParameterInTypeDescription
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.

ParameterInTypeDescription
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

ParameterInTypeDescription
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

ParameterInTypeDescription
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

ParameterInTypeDescription
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)

ParameterInTypeDescription
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

ParameterInTypeDescription
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

ParameterInTypeDescription
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

ParameterInTypeDescription
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

ParameterInTypeDescription
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
}