> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autosend.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Campaign Analytics

> Get delivery and engagement counts plus open, click, and bounce rates for a campaign using the AutoSend API.

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics' \
    --header 'Authorization: Bearer <token>'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics"
  headers = {"Authorization": "Bearer <token>"}

  response = requests.get(url, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics',
    {
      method: 'GET',
      headers: {
        Authorization: 'Bearer <token>',
      },
    }
  );
  const data = await response.json();
  console.log(data);
  ```

  ```php PHP theme={null}
  <?php
  $curl = curl_init();
  curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
      'Authorization: Bearer <token>',
    ],
  ]);
  $response = curl_exec($curl);
  curl_close($curl);
  echo $response;
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"io"
  	"net/http"
  )

  func main() {
  	req, _ := http.NewRequest("GET", "https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics", nil)
  	req.Header.Set("Authorization", "Bearer <token>")

  	client := &http.Client{}
  	resp, _ := client.Do(req)
  	defer resp.Body.Close()
  	body, _ := io.ReadAll(resp.Body)
  	fmt.Println(string(body))
  }
  ```

  ```java Java theme={null}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;

  public class Main {
      public static void main(String[] args) throws Exception {
          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics"))
              .header("Authorization", "Bearer <token>")
              .GET()
              .build();
          HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
          System.out.println(response.body());
      }
  }
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'uri'
  require 'json'

  uri = URI('https://api.autosend.com/v1/campaigns/60d5ec49f1b2c72d9c8b4567/analytics')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = 'Bearer <token>'

  response = http.request(request)
  puts JSON.parse(response.body)
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "campaignId": "69d348dd0351e0c32be90342",
      "name": "Spring Sale Newsletter",
      "status": "sent",
      "sentAt": "2026-04-06T05:54:51.190Z",
      "counts": {
        "totalContacts": 200,
        "suppressed": 2,
        "failed": 0,
        "attempted": 198,
        "sent": 198,
        "delivered": 196,
        "opened": 120,
        "humanOpened": 88,
        "clicked": 34,
        "bounced": 2,
        "unsubscribed": 1,
        "spamReported": 0
      },
      "rates": {
        "openRate": 61.22,
        "clickRate": 17.35,
        "bounceRate": 1.01,
        "unsubscribedRate": 0.51,
        "complaintRate": 0,
        "successRate": 100,
        "deliveryRate": 98.99,
        "trueOpenRate": 44.9
      },
      "tracking": {
        "open": true,
        "click": true
      },
      "refreshedAt": "2026-04-06T07:26:09.190Z"
    },
    "message": "Campaign analytics retrieved successfully"
  }
  ```

  ```json 404 theme={null}
  {
    "success": false,
    "error": {
      "message": "Campaign not found",
      "code": "CAMPAIGN_NOT_FOUND",
      "details": "No campaign matching the provided ID was found in this project."
    }
  }
  ```
</ResponseExample>

### Authorizations

<ParamField path="Authorizations" type="string | header" required>
  Bearer authentication header of the form Bearer `<token>`, where `<token>` is your auth token.
</ParamField>

### Path Parameters

<ParamField path="campaignId" type="string" required>
  The id of the campaign to get analytics for. Returns `404` if the campaign does not exist, was deleted, or belongs to another project.
</ParamField>

### Response

<span className="text-sm">Returns delivery and engagement counts for the campaign, plus rates calculated by AutoSend.</span>

<Note>
  Metrics are refreshed in the background, at most every 10 minutes, while a campaign is sending and for about 20 days after it's sent. The response returns the latest stored numbers right away. `refreshedAt` shows when they were last updated.
</Note>

<ResponseField name="success" type="boolean">
  Indicates whether the request was successful.
</ResponseField>

<ResponseField name="data" type="object">
  The campaign analytics object.

  <Expandable title="data">
    <ResponseField name="campaignId" type="string">
      Unique identifier of the campaign.
    </ResponseField>

    <ResponseField name="name" type="string">
      Display name of the campaign.
    </ResponseField>

    <ResponseField name="status" type="string">
      Current status of the campaign. One of: `draft`, `scheduled`, `sending`, `sending_gradual`, `paused`, `sent`, `failed`, `aborted`.
    </ResponseField>

    <ResponseField name="sentAt" type="string | null">
      ISO 8601 timestamp when the campaign was sent. Null if the campaign has not been sent yet, including gradual campaigns that are still sending.
    </ResponseField>

    <ResponseField name="counts" type="object">
      Raw delivery and engagement counts.

      <Expandable title="counts">
        <ResponseField name="totalContacts" type="number">
          Total number of contacts the campaign targets.
        </ResponseField>

        <ResponseField name="suppressed" type="number">
          Number of contacts skipped because they are suppressed.
        </ResponseField>

        <ResponseField name="failed" type="number">
          Number of emails that failed to send.
        </ResponseField>

        <ResponseField name="attempted" type="number">
          Number of emails AutoSend tried to send. Equal to `totalContacts` minus `suppressed` and `failed`, and never below `0`. For a campaign in `sending_gradual` status, only contacts processed so far are counted.
        </ResponseField>

        <ResponseField name="sent" type="number">
          Number of emails sent.
        </ResponseField>

        <ResponseField name="delivered" type="number">
          Number of emails delivered.
        </ResponseField>

        <ResponseField name="opened" type="number">
          Number of unique recipients who opened the email, including automated opens.
        </ResponseField>

        <ResponseField name="humanOpened" type="number">
          Number of unique recipients with at least one open from a real person. Opens that happen within a few seconds of delivery are treated as automated (for example, Apple Mail Privacy Protection, image proxies, or security scanners) and left out.
        </ResponseField>

        <ResponseField name="clicked" type="number">
          Number of unique recipients who clicked a link.
        </ResponseField>

        <ResponseField name="bounced" type="number">
          Number of emails that bounced.
        </ResponseField>

        <ResponseField name="unsubscribed" type="number">
          Number of recipients who unsubscribed.
        </ResponseField>

        <ResponseField name="spamReported" type="number">
          Number of recipients who marked the email as spam.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="rates" type="object">
      Rates as percentages from `0` to `100`, rounded to 2 decimal places. A rate is `0` when its base count is `0`.

      <Expandable title="rates">
        <ResponseField name="openRate" type="number">
          `opened` divided by `delivered`. Includes automated opens.
        </ResponseField>

        <ResponseField name="clickRate" type="number">
          `clicked` divided by `delivered`.
        </ResponseField>

        <ResponseField name="bounceRate" type="number">
          `bounced` divided by `sent`.
        </ResponseField>

        <ResponseField name="unsubscribedRate" type="number">
          `unsubscribed` divided by `delivered`.
        </ResponseField>

        <ResponseField name="complaintRate" type="number">
          `spamReported` divided by `delivered`.
        </ResponseField>

        <ResponseField name="successRate" type="number">
          `sent` divided by `attempted`.
        </ResponseField>

        <ResponseField name="deliveryRate" type="number">
          `delivered` divided by `sent`.
        </ResponseField>

        <ResponseField name="trueOpenRate" type="number">
          `humanOpened` divided by `delivered`. Gives a more accurate open rate than `openRate` because automated opens are left out.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="tracking" type="object">
      Tracking settings for the campaign.

      <Expandable title="tracking">
        <ResponseField name="open" type="boolean">
          Whether open tracking is enabled. When `false`, open counts and rates stay at `0`.
        </ResponseField>

        <ResponseField name="click" type="boolean">
          Whether click tracking is enabled. When `false`, click counts and rates stay at `0`.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="refreshedAt" type="string | null">
      ISO 8601 timestamp when the metrics were last refreshed. Null if the campaign has never been refreshed.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="message" type="string">
  A human-readable message describing the result.
</ResponseField>


## OpenAPI

````yaml GET /campaigns/{campaignId}/analytics
openapi: 3.1.0
info:
  title: Autosend Campaigns API
  version: 1.0.0
  description: API endpoints for managing marketing campaigns in Autosend.
servers:
  - url: https://api.autosend.com/v1
    description: Production
security:
  - bearerAuth: []
paths:
  /campaigns/{campaignId}/analytics:
    get:
      summary: Get Campaign Analytics
      description: >-
        Retrieves delivery and engagement counts and computed rates for a
        campaign.
components: {}

````