HomeGuidesAPI Reference
ChangelogHelp CenterCommunityContact Us
API Reference

Reporting API overview

Our Reporting API allows you to fetch 1:1 matches of campaign and flow performance data shown in the Klaviyo UI. You can create two different types of reports:

  • Values report

    Returns requested statistics for a given campaign or flow over a provided time frame. For example, opens for a specified campaign over the last 12 months.

  • Series report

    Returns requested flow statistics broken down by a specified time interval (daily, hourly, weekly, or monthly) over a provided time frame. For example, weekly click rates for a flow email over the last 30 days.

Before you begin

  • Check out our general API overview to make sure you’re ready to get started with specific endpoints.
  • Make sure that you have the following scopes enabled on your private API key to use these endpoints:
    • flows:read
    • campaigns:read
    • forms:read
    • segments:read

The Query Metrics Aggregates endpoint

You may be using our Query Metric Aggregates endpoint to export reporting data for campaigns and flows. It’s important to note that data from the Query Metric Aggregates endpoint does not match the data reflected in the Klaviyo UI. While this endpoint allows you to filter and group campaign and flow data based on the time an event occurred, performance in the Klaviyo UI is calculated based on send date. We recommend our Reporting API to achieve this use case, which is built to fetch 1:1 matches of data shown in the Klaviyo UI.

Use cases

Here are some example use cases supported by the Reporting API:

  • Request 1:1 matches of campaign, flow, form, or segment performance data shown in the Klaviyo app.
  • Return the overall value of statistics for a given campaign, flow, form, or segment.
  • Request data by statistic, time frame, and metric ID.
  • Filter data by channel and/or campaign ID.

📘

Check out our video on how to analyze marketing performance with the Reporting API.

Data model

Values report

A values report request can have the following:

  • type (required)

    The type of report you are requesting. Supported types include:
    - campaign-values-report
    - flow-values-report, flow-series-report
    - form-values-report, form-series-report
    - segment-values-report, segment-series-report

  • attributes

    • statistics (required)
      A list of statistics computed by Klaviyo (see Available statistics).

    • timeframe (required)
      An object that contains fields for setting a predefined time frame (key) or a custom time frame (start and end) to pull data from (max length: 1 year).

    • To set a predefined time frame, use:

    • To set a custom time frame, use:

      • start
        A datetime that represents the start of a custom time frame.
      • end
        A datetime that represents the end of a custom time frame.
    • conversion_metric_id (required)
      The ID of the conversion metric (e.g., the metric ID for Placed Order) used for calculating conversion-based statistics.

    • filter
      A JSON:API filter string for filtering the query.

The conversion_metric_id is used for calculating conversion-based statistics. Other statistics fetched in a campaign or flows report will include all values, regardless of whether or not some values triggered conversions. For example, a query for opens will return all opens, including opens that did not trigger a conversion.

Series report

A series report request follows the same data model as a values report request, but it differs in that it additionally contains an interval field for breaking down performance over a specified time frame by day, week, etc. You can set the interval to daily, hourly, weekly, or monthly.

If the interval is not specified, it will default to weekly.

Campaigns

Campaign values report

The request below to the Query Campaign Values endpoint queries opens and open rate statistics over the last 12 months:

curl --request POST \
     --url https://a.klaviyo.com/api/campaign-values-reports/ \
     --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'revision: 2024-06-15' \
     --data '
{
  "data": {
    "type": "campaign-values-report",
    "attributes": {
      "timeframe": {
        "key": "last_12_months"
      },
      "conversion_metric_id": "RESQ6t",
      "filter": "equals(campaign_id",\"01GMRWDSA0ARTAKE1SFX8JGXAY\")",

      "statistics": [
        "opens",
        "open_rate"
      ]
    }
  }
}
'
{
  "data": {
    "type": "campaign-values-report",
    "attributes": {
      "results": [
        {
          "groupings": {
            "send_channel": "email",
            "campaign_id": "01GMRWDSA0ARTAKE1SFX8JGXAY"
          },
          "statistics": {
            "opens": 123,
            "open_rate": 0.8253
          }
        }
      ]
    },
    "relationships": {
      "campaigns": {
        "data": [
          {
            "type": "campaign",
            "id": "string"
          }
        ],
        "links": {
          "self": "string",
          "related": "string"
        }
      }
    },
    "links": {
      "self": "string"
    }
  }
}

Each object in the results array returned in the response includes groupings (send channel and campaign ID) and their associated statistics (number of opens and open rate).

Flows

Flow values report

The example below uses the Query Flow Values endpoint to query statistics (clicks, unique clicks, and unique conversions) over a custom time frame:

curl --request POST \
     --url https://a.klaviyo.com/api/flow-values-reports/ \
     --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'revision: 2024-06-15 \
     --data '
{
  "data": {
    "type": "flow-values-report",
    "attributes": {
      "timeframe": {
        "start": "2024-05-08T00:00:00+00:00",
        "end": "2024-06-20T00:00:00+00:00"

      },
      "conversion_metric_id": "RESQ6t",
      "filter":"equals(flow_id,\"XVTP5Q\")",
      "statistics": [
        "clicks",
        "clicks_unique",
        "conversion_uniques"
      ]
    }
  }
}
'
{
  "data": {
    "type": "flow-values-report",
    "attributes": {
      "results": [
        {
          "groupings": {
            "flow_id": "XVTP5Q",
            "send_channel": "email",
            "flow_message_id": "01GMRWDSA0ARTAKE1SFX8JGXAY"
          },
          "statistics": {
            "clicks": 123,
            "clicks_unique": 98,
            "conversion_uniques": 3
          }
        },
        {
          "groupings": {
            "flow_id": "XVTP5Q",
            "send_channel": "email",
            "flow_message_id": "01GJTHNWVG93F3KNX71SJ4FDBB"
          },
          "statistics": {
            "clicks": 342,
            "clicks_unique": 208,
            "conversion_uniques": 10
          }
        }
      ]
    },
    "relationships": {
      "flows": {
        "data": [
          {
            "type": "flow",
            "id": "string"
          }
        ],
        "links": {
          "self": "string",
          "related": "string"
        }
      },
      "flow-messages": {
        "data": [
          {
            "type": "flow-message",
            "id": "string"
          }
        ],
        "links": {
          "self": "string",
          "related": "string"
        }
      }
    },
    "links": {
      "self": "string"
    }
  }
}

Flow series report

The example below uses the Query Flow Series endpoint to query statistics for clicks, delivery rate and open rate on a weekly interval over the last 30 days:

curl --request POST \
     --url https://a.klaviyo.com/api/flow-series-reports/ \
     --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'revision: 2024-06-15 \
     --data '
{
  "data": {
    "type": "flow-series-report",
    "attributes": {
      "timeframe": {
        "key": "last_30_days"
      },
      "interval": "weekly",
      "conversion_metric_id": "RESQ6t",
      "filter": "equals(flow_id,\"XVTP5Q\")",
      "statistics": [
        "clicks",
        "delivery_rate",
        "open_rate"
      ]
    }
  }
}
'
{
  "data": {
    "type": "flow-series-report",
    "attributes": {
      "results": [
        {
          "groupings": {
            "flow_id": "XVTP5Q",
            "send_channel": "email",
            "flow_message_id": "01GMRWDSA0ARTAKE1SFX8JGXAY"
          },
          "statistics": {
            "clicks": [
              123,
              156,
              144
            ],
      "delivery_rate": [
              1.00,
              0.56,
              0.84
            ],
            "open_rate": [
              0.8253,
              0.8722,
              0.8398
            ]
          }
        },
        {
          "groupings": {
            "flow_id": "XVTP5Q",
            "send_channel": "email",
            "flow_message_id": "01GJTHNWVG93F3KNX71SJ4FDBB"
          },
          "statistics": {
             "clicks": [
              123,
              156,
              144
            ],
      "delivery_rate": [
              1.00,
              0.56,
              0.84
            ],
            "open_rate": [
              0.8253,
              0.8722,
              0.8398
            ]
          }
        }
      ],
      "date_times": [
        "2024-01-05T00:00:00+00:00",
        "2024-01-06T00:00:00+00:00",
        "2024-01-07T00:00:00+00:00"
      ]
    },
    "relationships": {
      "flows": {
        "data": [
          {
            "type": "flow",
            "id": "string"
          }
        ],
        "links": {
          "self": "string",
          "related": "string"
        }
      },
      "flow-messages": {
        "data": [
          {
            "type": "flow-message",
            "id": "string"
          }
        ],
        "links": {
          "self": "string",
          "related": "string"
        }
      }
    },
    "links": {
      "self": "string"
    }
  }
}

Forms

A form is represented by the following:

  • form_id
    The unique alphanumeric value identifying a single form. Use the equals operator to return a single form_id, or the any operator to return a list of matching form_ids.
  • form_version_id
    The unique alphanumeric value identifying the version for a single form

Results are grouped by form_id by default. Use group_by with the default or add form_version_id to enable form version reporting.

🚧

To group by form_version_id in your request, form_id is also required.

The supported attributes for filtering include both form_id and form_version_id.

Form values report

The Query Forms Values endpoint returns an array of objects that show a form's performance statistics.

curl --request POST
     --url <https://a.klaviyo.com/api/form-values-reports>
     --header 'Authorization: Klaviyo-API-Key your-private-api-key'
     --header 'accept: application/json'
     --header 'revision: 2024-07-15.pre'
{
  "data": {
    "type": "form-values-report",
    "attributes": {
      "timeframe": {
        "key": "last_12_months",
      },
      "filter": "any(form_id,[\"abc123\",\"def456\" ])",
      "statistics": [
          "viewed_form",
          "submits",
          "submit_rate"
      ],
      "group_by": [
          "form_id",
          "form_version_id"
      ]
    }
  }
}
{
  "data": {
    "type": "form-values-report",
    "attributes": {
      "results": [
        {
          "groupings": {
            "form_id": "abc123"
            "form_version_id": "012tuy"
          },
          "statistics": {
            "viewed_form": 90,
            "submits": 9,
            "submit_rate": 0.10
          }
        },
        {
          "groupings": {
            "form_id": "abc123"
            "form_version_id": "765ghi"
          },
          "statistics": {
            "viewed_form": 10,
            "submits": 1,
            "submit_rate": 0.10
          }
        },
        {
          "groupings": {
            "form_id": "def456",
            "form_version_id": "789jkl"
          },
          "statistics": {
            "viewed_form": 200,
            "submits": 10,
            "submit_rate": 0.05
          }
        }
      ]
    }
  }
}

Form series report

The Query Forms Series endpoint returns an array of objects that show performance for individual forms broken down by time series.

For each statistic included in the request, the response outputs a series of dates and the statistic’s corresponding values.

For example:

"viewed_form": {
              "2024-03-01": 20,
              "2024-03-02": 25,
              "2024-03-03": 30
					}

For the viewed_form statistic, form views were captured on three dates within the given timeframe. Each date in the array corresponds to an integer, representing the total number of form views.

curl --request POST
     --url <https://a.klaviyo.com/api/form-series-reports>
     --header 'Authorization: Klaviyo-API-Key your-private-api-key'
     --header 'accept: application/json'
     --header 'revision: 2024-07-15.pre'

{
  "data": {
    "type": "form-series-report",
    "attributes": {
      "timeframe": {
        "key": "last_3_months",
      },
      "interval": "monthly",
      "filter": "equals(form_id,\"abc123\")",
      "statistics": [
        "viewed_form",
        "submits",
        "submit_rate"
      ]
    }
  }
}
{
  "data": {
    "type": "form-series-report",
    "attributes": {
      "results": [
        {
          "groupings": {
            "form_id": "01GMRWDSA0ARTAKE1SFX8JGXAY"
          },
          "statistics": {
            "viewed_form": {
              "2024-03-01": 20,
              "2024-04-01": 20,
              "2024-05-01": 20
            },
            "submits": {
              "2024-03-01": 2,
              "2024-04-01": 2,
              "2024-05-01": 2
            },
            "submit_rate": {
              "2024-03-01": 0.1,
              "2024-04-01": 0.1,
              "2024-05-01": 0.1
            }
          }
        }]
    }
}

Segments

A segment is represented by the following:

  • segment_id
    The unique alphanumeric value identifying a segment. Use the equals operator to return a single segment_id, or the any operator to return a list of matching segment_ids.

The supported attributes for filtering include: segment_id.

Segment values report

The Query Segments Values endpoint returns an array of objects that shows performance statistics for a single segment.

 curl --request POST \
 --url https://a.klaviyo.com/api/segment-values-reports/ \
 --header 'Authorization: Klaviyo-API-Key <API-KEY>' \
 --header 'accept: application/json' \
 --header 'content-type: application/json' \
 --header 'revision: 2024-07-15.pre' \
 --data '
 {
  "data": {
    "type": "segment-values-report",
    "attributes": {
      "statistics": [
        "total_members",
        "members_added",
        "members_removed",
        "net_members_changed"
      ],
      "timeframe": {
        "key": "last_7_days"
      },
      "filter": "equals(segment_id,"RpKvCF")"
    }
  }
}
{
  "data": {
    "type": "segment-values-report",
    "id": "b85c66bb-495d-479b-8425-3ffb7f298f60",
    "attributes": {
      "results": [
        {
          "groupings": {
            "segment_id": "RpKvCF"
          },
          "statistics": {
            "total_members": 79,
            "members_added": 79,
            "members_removed": 0,
            "net_members_changed": 79
          }
        }
      ]
    }
  },
  "links": {
    "self": "<https://a.klaviyo.com/api/segment-values-reports/">
  }
}

Segment series report

The Query Segments Series endpoint returns an array of objects that each show performance for a single segment over a given time series.

curl --request POST
     --url <https://a.klaviyo.com/api/segment-series-reports/>
     --header 'Authorization: Klaviyo-API-Key <API-KEY>'
    --header 'accept: application/json'
     --header 'content-type: application/json'
     --header 'revision: 2024-07-15.pre'
     --data '
{
  "data": {
    "type": "segment-series-report",
    "attributes": {
      "statistics": [
        "total_members",
        "members_added"
      ],
      "timeframe": {
        "key": "last_7_days"
      },
      "filter": "equals(segment_id,\"RpKvCF\")",
      "interval": "daily"
    }
  }
}
{
  "data": {
    "type": "segment-series-report",
    "id": "7bbe2230-3f89-42e7-af21-a31da4eb8b15",
    "attributes": {
      "results": \[
        {
          "groupings": {
            "segment_id": "RpKvCF"
          },
          "statistics": {
            "total_members": [
              0,
              0,
              79,
              79,
              79,
              79,
              79,
              79
            ],
            "members_added": [
              0,
              0,
              79,
              0,
              0,
              0,
              0,
              0
            ]
          }
        }
      ],
      "date_times": [
        "2024-07-30T00:00:00+00:00",
        "2024-07-31T00:00:00+00:00",
        "2024-08-01T00:00:00+00:00",
        "2024-08-02T00:00:00+00:00",
        "2024-08-03T00:00:00+00:00",
        "2024-08-04T00:00:00+00:00",
        "2024-08-05T00:00:00+00:00",
        "2024-08-06T00:00:00+00:00"
      ]
    }
  },
  "links": {
    "self": "<https://a.klaviyo.com/api/segment-series-reports/">
  }
}

Available statistics

📘

Conversion statistics are based on the conversion_metric_id provided in the request payload.

StatisticFormula
average_order_valueConversion value / Conversion
bounce_rate(Bounced emails + Bounced pushes) / (Received emails + Received pushes + Bounced emails + Bounced pushes)
bouncedEmail bounces + Push bounces
bounced_or_failedBounced emails + Failed SMS + Bounced pushes
bounced_or_failed_rate(Bounced emails + Failed SMS + Bounced pushes) / (Received emails + Received SMS + Received pushes + Bounced emails + Failed SMS + Bounced pushes)
click_rate(Unique email clicks + Unique SMS clicks) / (Received emails + Received SMS)
click_to_open_rateUnique email clicks / Unique email opens
clicksEmail clicks + SMS clicks
clicks_uniqueUnique email clicks + Unique SMS clicks
conversion_rateUnique conversions / (Received emails + Received SMS + Received pushes)
conversion_uniquesCount of unique conversions
conversion_valueSum of the value for the provided conversion metric (e.g., the sum of transaction totals from Placed Order events)
conversionsCount of events for the provided conversion metric (e.g., the count of Placed Order events)
deliveredReceived emails + Received SMS + Received pushes
delivery_rate(Received emails + Received SMS + Bounced pushes) / (Received emails + Received SMS + Received pushes + Bounced emails + Failed SMS + Bounced pushes)
failedFailed SMS
failed_rateFailed SMS / (Received SMS + Failed SMS)
open_rate(Unique email opens + Unique push opens) / (Received emails + Received push uniques)
opensEmail opens + Push opens
opens_uniqueUnique email opens + Unique push opens
recipientsReceived emails + Received SMS + Received pushes + Bounced emails + Failed SMS + Bounced pushes
revenue_per_recipientConversion value / (Received emails + Received SMS + Received pushes)
spam_complaint_rateEmail spam / Received emails
spam_complaintsCount of spam complaints
unsubscribe_rate(Unique email unsubscribes + Unique SMS unsubscribes) / (Received emails + Received SMS)
unsubscribe_uniquesCount of unique unsubscribes
unsubscribesCount of unsubscribes
viewed_formThe total number of times the form was viewed.
viewed_form_uniquesThe number of times a form was viewed by unique users.
submitsThe total number of form submissions.
submit_rateThe rate of form submissions over form views.
closed_formThe total number of times a form was closed.
closed_form_uniquesThe number of times a form was closed by unique users.
qualified_formThe total number of times a user qualified to view the form (such as in an A/B testing scenario).
qualified_form_uniquesThe number of times a unique user was qualified to view the form.
viewed_form_stepThe total number of times a form step is viewed by a user.
viewed_form_step_uniquesThe number of times a form step is viewed by unique users.
submitted_form_stepThe total number of times a form step is completed by a user.
submitted_form_step_uniquesThe number of times a form step is completed by unique users.
total_membersThe total number of profiles included in the segment.
members_addedProfiles added to the segment
members_removedProfiles removed from the segment.
net_members_changedNet number of profiles changed.

Available time frames

📘

The available time frames below are relative to the time the user makes the call.

Time frameDescription
todayReturns same day data. Will respect the timezone of the account.
yesterdayReturns data from the day before. Will respect the timezone of the account.
this_weekReturns data from the current calendar week (Monday to Sunday).
last_7_daysReturns data from the past 7 days (including the day the user makes the call).
last_weekReturns data from the previous calendar week (Monday to Sunday).
this_monthReturns data from the current month.
last_30_daysReturns data from the last 30 days regardless of month.
last_monthReturns data from the previous calendar month.
last_90_daysReturns data from the last 90 days regardless of month.
last_3_monthsReturns data from the 3 previous months, (including the month the user makes the call).
last_365_daysReturns data from the last 365 days regardless of year (including the month the request is made).
last_12_monthsReturns data from the 12 previous months (excluding the month the month the request is made).
this_yearReturns all data from the current calendar year.
last_yearReturns all data from the previous calendar year.

📘

If you're encountering a blank series report, we recommend using the last_365_days timeframe which will include statistics for the current month.

Common errors

4XX errors indicate a bad request, which can result from the following issues:

  • Missing fields for a timeframe, or including too many timeframe fields.
  • Filtering for more than 100 forms in a single request.
  • Passing in an invalid or unsupported statistic.
  • Requesting a timeframe that is too long. The maximum supported timeframe is 1 year, up to June 1, 2023.
  • Using an invalid filter or an unsupported operator.
  • Filtering for the same attribute more than once in a single request.
  • Grouping with group_by: ["form_version_id"] without including the form_id.

503 errors with Retry-After header specified are returned in response to temporary service outages. The Retry-After header indicates the number of seconds to wait before retrying the request.

Example error response

{
	"errors": [
		{
			"id": "51cd68be-29df-4229-ac1f-0f76c4ecb75e",
			"status": 400,
			"code": "invalid",
			"title": "Invalid input.",
			"detail": "Can group by form_version_id only if form_id are also passed in together",
			"source": {
				"pointer": "/data/attributes/group_bys"
			},
			"links": {},
			"meta": {}
		}
	]
}