curl --request GET \
--url https://api.instantly.ai/api/v2/campaigns/analytics/steps \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.instantly.ai/api/v2/campaigns/analytics/steps"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.instantly.ai/api/v2/campaigns/analytics/steps', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.get("https://api.instantly.ai/api/v2/campaigns/analytics/steps")
.header("Authorization", "Bearer <token>")
.asString();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.instantly.ai/api/v2/campaigns/analytics/steps",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.instantly.ai/api/v2/campaigns/analytics/steps"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}[
{
"step": "1",
"variant": "0",
"sent": 5421,
"opened": 99,
"unique_opened": 60,
"replies": 60,
"unique_replies": 60,
"replies_automatic": 5,
"unique_replies_automatic": 4,
"clicks": 60,
"unique_clicks": 60,
"opportunities": 10,
"unique_opportunities": 8,
"meetings_booked": 2,
"won": 1
}
]{
"message": "Start Date must be earlier than End Date"
}{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing Authorization header"
}{
"statusCode": 402,
"error": "Payment Required",
"message": "Workspace does not have an active paid plan"
}{
"statusCode": 404,
"error": "Not Found",
"message": "Resource not found"
}{
"statusCode": 429,
"error": "Too Many Requests",
"message": "Rate limit exceeded"
}Get campaign steps analytics
Get campaign steps analytics
curl --request GET \
--url https://api.instantly.ai/api/v2/campaigns/analytics/steps \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.instantly.ai/api/v2/campaigns/analytics/steps"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.instantly.ai/api/v2/campaigns/analytics/steps', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.get("https://api.instantly.ai/api/v2/campaigns/analytics/steps")
.header("Authorization", "Bearer <token>")
.asString();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.instantly.ai/api/v2/campaigns/analytics/steps",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.instantly.ai/api/v2/campaigns/analytics/steps"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}[
{
"step": "1",
"variant": "0",
"sent": 5421,
"opened": 99,
"unique_opened": 60,
"replies": 60,
"unique_replies": 60,
"replies_automatic": 5,
"unique_replies_automatic": 4,
"clicks": 60,
"unique_clicks": 60,
"opportunities": 10,
"unique_opportunities": 8,
"meetings_booked": 2,
"won": 1
}
]{
"message": "Start Date must be earlier than End Date"
}{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing Authorization header"
}{
"statusCode": 402,
"error": "Payment Required",
"message": "Workspace does not have an active paid plan"
}{
"statusCode": 404,
"error": "Not Found",
"message": "Resource not found"
}{
"statusCode": 429,
"error": "Too Many Requests",
"message": "Rate limit exceeded"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
Campaign ID (optional). Leave this field empty to get the analytics for all campaigns
"01a082d0-8380-7a70-be9c-19040bc46e24"
Start of the analytics range. Accepts a date-only value (YYYY-MM-DD) or a full ISO 8601 timestamp. Date-only values are interpreted as UTC midnight — e.g. 2026-04-07 is treated as 2026-04-07T00:00:00.000Z.
"2024-01-01"
End of the analytics range. Accepts a date-only value (YYYY-MM-DD) or a full ISO 8601 timestamp. Date-only values are interpreted as UTC midnight — e.g. 2026-04-07 is treated as 2026-04-07T00:00:00.000Z.
"2024-01-01"
Whether to include the opportunities count per step. If this field is true then opportunities, unique_opportunities, meetings_booked, and won fields will be included in the response
true
Response
Default Response
The step number. When null it means we couldn't determine the step number for the event, for instance for list leads, which are not part of a campaign.
"1"
The variant number, starting from 0. 0 = A, 1 = B, 2 = C, etc. When null it means we couldn't determine the variant for the event.
"0"
The total number of sent emails
5421
The total number of opened emails
99
The total number of opened emails
60
The total number of replies
60
The total number of replies
60
The total number of automatic replies detected
5
The total number of unique automatic replies detected
4
The total number of links clicked
60
The total number of unique links clicked. Unique meaning from unique leads, not unique links. For instance, if a lead clicked a link 3 times, it will be counted as 1 unique click. If a lead clicked 3 different links, it will still be counted as 1 unique click
60
The total number of opportunities created from this step. Included only if include_opportunities_count is true
10
The total number of unique opportunities created from this step. Unique meaning unique per lead. If a lead has multiple opportunities, it will be counted as 1 unique opportunity. Included only if include_opportunities_count is true
8
The total number of opportunities from this step whose current CRM status is Meeting Booked. Included only if include_opportunities_count is true
2
The total number of opportunities from this step whose current CRM status is Won. Included only if include_opportunities_count is true
1