package main
import (
"context"
"fmt"
"log"
"os"
"github.com/AhaSend/ahasend-go/api"
"github.com/google/uuid"
)
func main() {
client := api.NewAPIClient(api.WithAPIKey(os.Getenv("AHASEND_API_KEY")))
accountID := uuid.MustParse(os.Getenv("AHASEND_ACCOUNT_ID"))
ctx := context.Background()
campaignID := uuid.MustParse("11111111-1111-4111-8111-111111111111")
response, _, err := client.CampaignsAPI.GetCampaignStats(ctx, accountID, campaignID)
if err != nil {
log.Fatalf("Error getting campaign stats: %v", err)
}
fmt.Printf("Delivered %d of %d\n", response.Delivered, response.Recipients)
// A rate is nil until the report is counted and its base is not zero.
if response.Rates.OpenRate != nil {
fmt.Printf("Open rate: %.2f%%\n", *response.Rates.OpenRate)
}
if response.Report != nil {
for status, count := range response.Report.ByStatus {
fmt.Printf("%s: %d\n", status, count)
}
}
}
import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
const campaignId = "00000000-0000-4000-8000-000000000014";
const stats = await client.campaigns.getStats(campaignId);
console.log("Campaign stats loaded.", { delivered: stats.delivered, rates: stats.rates });
curl --request GET \
--url https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats",
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;
}HttpResponse<String> response = Unirest.get("https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"object": "campaign_stats",
"campaign_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"recipients": 123,
"delivered": 123,
"opens": 123,
"clicks": 123,
"unsubscribes": 123,
"complaints": 123,
"report": {
"computed_at": "2023-11-07T05:31:56Z",
"recipients": 123,
"openers": 123,
"clickers": 123,
"bounces": 123,
"deferrals": 123,
"by_status": {},
"by_bounce_classification": {}
},
"rates": {
"open_rate": 123,
"click_rate": 123,
"bounce_rate": 123,
"deferral_rate": 123
},
"recount_failed": true
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}Get Campaign Stats via the API
Read the results of an AhaSend marketing campaign: delivered messages, opens, clicks, unsubscribes, complaints, bounces and rates, as the report shows them.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/AhaSend/ahasend-go/api"
"github.com/google/uuid"
)
func main() {
client := api.NewAPIClient(api.WithAPIKey(os.Getenv("AHASEND_API_KEY")))
accountID := uuid.MustParse(os.Getenv("AHASEND_ACCOUNT_ID"))
ctx := context.Background()
campaignID := uuid.MustParse("11111111-1111-4111-8111-111111111111")
response, _, err := client.CampaignsAPI.GetCampaignStats(ctx, accountID, campaignID)
if err != nil {
log.Fatalf("Error getting campaign stats: %v", err)
}
fmt.Printf("Delivered %d of %d\n", response.Delivered, response.Recipients)
// A rate is nil until the report is counted and its base is not zero.
if response.Rates.OpenRate != nil {
fmt.Printf("Open rate: %.2f%%\n", *response.Rates.OpenRate)
}
if response.Report != nil {
for status, count := range response.Report.ByStatus {
fmt.Printf("%s: %d\n", status, count)
}
}
}
import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
const campaignId = "00000000-0000-4000-8000-000000000014";
const stats = await client.campaigns.getStats(campaignId);
console.log("Campaign stats loaded.", { delivered: stats.delivered, rates: stats.rates });
curl --request GET \
--url https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats",
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;
}HttpResponse<String> response = Unirest.get("https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ahasend.com/v2/accounts/{account_id}/campaigns/{campaign_id}/stats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"object": "campaign_stats",
"campaign_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"recipients": 123,
"delivered": 123,
"opens": 123,
"clicks": 123,
"unsubscribes": 123,
"complaints": 123,
"report": {
"computed_at": "2023-11-07T05:31:56Z",
"recipients": 123,
"openers": 123,
"clickers": 123,
"bounces": 123,
"deferrals": 123,
"by_status": {},
"by_bounce_classification": {}
},
"rates": {
"open_rate": 123,
"click_rate": 123,
"bounce_rate": 123,
"deferral_rate": 123
},
"recount_failed": true
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}campaigns:read.
Live counters:
recipients, delivered, opens, clicks, unsubscribes and complaints are live. Opens and clicks do not include bots.
Stored report:
reportholds the numbers counted from the recipients of the campaign: openers, clickers, bounces, deferrals, recipients by status and bounces by bounce classification.report.computed_atis the time of the count.- The report is counted again from time to time. When a request finds the report missing or old, it asks for a new count and answers the stored report. Read the stats again later to get the new numbers.
reportisnulluntil the first count.recount_failedistruewhile the last count failed, soreportcan be old.
rates gives percentages from 0 to 100 with two decimals. open_rate and click_rate use delivered as the base. bounce_rate and deferral_rate use report.recipients as the base. A rate is null while report is null or its base is zero.
To list the recipients behind a number in report.by_status or report.by_bounce_classification, use List Campaign Recipients.
Related Guides
Authorizations
API key for authentication. Non-empty Security Requirement values are AhaSend API-key roles. Roles listed within one requirement object are jointly required; separate requirement objects are alternatives.
Response
Campaign stats
The numbers of a campaign. The counters are live; report is the
stored report, which is recounted from time to time. A request
never counts: when the report is missing or old, it asks for a
recount and answers what is stored, so read again later for the
new numbers.
Object type identifier
campaign_stats Campaign ID
Recipients the campaign sends to
Messages delivered
Opens, without bots
Clicks, without bots
Recipients who unsubscribed
Recipients who marked the message as spam
The stored report. Null until the campaign's first recount.
Show child attributes
Show child attributes
Percentages from 0 to 100 with two decimals. Each is null while report is null or its base is zero.
Show child attributes
Show child attributes
True while the last recount of the report failed, so report may be old.

