Skip to content
Preview. The endpoints on this page are illustrative and are likely to change as they move toward general availability. Documentation is published in advance so you can start shaping your integration; treat request and response details as subject to revision.

Buyer Signals

Read aggregated engagement data from tracked emails your organization has sent — opens, clicks, replies, and their timing.

buyer-signals:read covers every endpoint on this page. Reply data (which recipient replied, when, and on which email) is surfaced inline — reply signals are one of the four tracked event types alongside sends, opens, and clicks.

What is a "buyer signal"?

A buyer signal is one instance of a tracked engagement event on a sent email. Cirrus recognizes four types:

SignalMeaning
sendsCirrus dispatched the message (baseline denominator).
opensRecipient rendered the tracking pixel.
clicksRecipient clicked a tracked link.
repliesRecipient responded to the message. Attribution runs through Cirrus's reply-detection heuristics; auto-responders are filtered out.

The endpoints below expose these signals at three grains: aggregate (/summary), daily timeseries (/activity), and per-sent-email (/sent-emails).

Endpoints on this page

MethodEndpointDescription
GET/api/v1alpha1/buyer-signals/summaryUnique-recipient stats across a period. Details ↓
GET/api/v1alpha1/buyer-signals/activityDaily timeseries of send / open / click / reply counts. Details ↓
GET/api/v1alpha1/buyer-signals/sent-emailsPer-email table with engagement stats. Details ↓
GET/api/v1alpha1/buyer-signals/sent-emails/{sentEmailId}One sent email with full engagement detail. Details ↓
GET/api/v1alpha1/buyer-signals/sent-emails/{sentEmailId}/signalsPer-recipient signal drill-down — the "who opened / replied?" view. Details ↓

Get summary stats

GET /api/v1alpha1/buyer-signals/summary

Aggregate unique-recipient stats across a period. One object, no pagination.

Query parameters

ParameterTypeDescription
periodDaysnumber7, 14, or 30. Default 7.

Response

  • had* counts are unique-recipient — a recipient who opened three times contributes 1 to hadOpened, not 3. For raw event counts use /activity.
  • Percentages are computed off totalSent and are float-typed with one decimal.

bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/summary?periodDays=30" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/summary",
    headers={"X-Cirrus-Api-Key": token},
    params={"periodDays": 30},
)
response.raise_for_status()
summary = response.json()
csharp
using System.Net.Http;
using System.Web;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var query = HttpUtility.ParseQueryString(string.Empty);
query["periodDays"] = "30";

var uri = new UriBuilder("https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/summary")
{
    Query = query.ToString()
}.Uri;

var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
var summary = await response.Content.ReadAsStringAsync();
json
{
  "periodDays": 30,
  "totalSent": 1247,
  "hadOpened": 812,
  "hadClicked": 168,
  "hadReplied": 94,
  "openedPercentage": 65.1,
  "clickedPercentage": 13.5,
  "repliedPercentage": 7.5
}

Get daily activity

GET /api/v1alpha1/buyer-signals/activity

Daily timeseries suitable for a chart. Returns one row per (date, action) combination for the requested period.

Query parameters

ParameterTypeDescription
periodDaysnumber7, 14, or 30. Default 7.
actionstring(optional) sends, opens, clicks, replies. Repeatable. Omitted returns all four.

Response

  • count is raw event count, not unique-recipient — a recipient who opens the same email three times contributes 3 opens to that day's total. Use /summary for the unique-recipient view.
  • Days with zero activity are omitted. A caller expecting a dense series should hydrate missing days as zero on their end.

bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/activity?periodDays=30" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/activity",
    headers={"X-Cirrus-Api-Key": token},
    params={"periodDays": 30},
)
response.raise_for_status()
chart = response.json()
csharp
using System.Net.Http;
using System.Web;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var query = HttpUtility.ParseQueryString(string.Empty);
query["periodDays"] = "30";

var uri = new UriBuilder("https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/activity")
{
    Query = query.ToString()
}.Uri;

var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
var chart = await response.Content.ReadAsStringAsync();
json
{
  "periodDays": 30,
  "items": [
    { "date": "2026-08-11", "action": "sends",   "count": 42 },
    { "date": "2026-08-11", "action": "opens",   "count": 28 },
    { "date": "2026-08-11", "action": "clicks",  "count":  6 },
    { "date": "2026-08-11", "action": "replies", "count":  4 }
  ]
}

List sent emails

GET /api/v1alpha1/buyer-signals/sent-emails

Per-email table with per-recipient engagement rolled up per row. Combines standard sends and blast sends in one list — use emailType to filter to one.

Query parameters

ParameterTypeDescription
cursorstringStandard keyset cursor.
limitnumberClamped 1–100, default 25.
sortstringsentAt, lastReplyAt, lastOpenAt, lastClickAt, replies, opens, clicks. Prefix - for descending. Default -sentAt.
periodDaysnumber7, 14, or 30. Default 7. Filter to emails sent within the window.
searchstring(optional) Substring match on subject or recipient email. Case-insensitive.
emailTypestring(optional) standard (one-off from Sidebar/Gmail), email-blast (bulk campaign), all. Default all.

Response

See the SentEmailmodel for the full field reference.

  • recipientEmails is the full to-list on the send. A single sent email can have multiple recipients when the sender used cc/bcc or when a blast batched a small group into one message; per-recipient signals are on the /signals drill-down.
  • emailType=email-blast rows carry a populated blastId linking back to the EmailBlast resource.
  • lastOpenLocation is a coarse city-level geolocation of the IP that fired the most recent tracking-pixel open. Omitted (null) when the recipient's mail client suppressed the pixel or geolocation isn't confident.

bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails?periodDays=30&limit=25" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails",
    headers={"X-Cirrus-Api-Key": token},
    params={"periodDays": 30, "limit": 25},
)
response.raise_for_status()
page = response.json()
csharp
using System.Net.Http;
using System.Web;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var query = HttpUtility.ParseQueryString(string.Empty);
query["periodDays"] = "30";
query["limit"] = "25";

var uri = new UriBuilder("https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails")
{
    Query = query.ToString()
}.Uri;

var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
var page = await response.Content.ReadAsStringAsync();
json
{
  "items": [
    {
      "id": "semail_...",
      "subject": "Following up on Q3 pipeline forecasting",
      "sender": {
        "userId": "usr_...",
        "displayName": "Alex Rivera"
      },
      "recipientEmails": ["guest@example.com"],
      "sentAt": "2026-08-11T14:30:00Z",
      "opens": 5,
      "clicks": 1,
      "replies": 1,
      "lastOpenAt":  "2026-08-12T09:22:03Z",
      "lastClickAt": "2026-08-12T09:22:41Z",
      "lastReplyAt": "2026-08-12T10:14:07Z",
      "lastOpenLocation": "New York, NY",
      "emailType": "standard",
      "blastId": null
    }
  ],
  "nextCursor": null
}

Get a sent email

GET /api/v1alpha1/buyer-signals/sent-emails/{sentEmailId}

Response

Same shape as the list row. For per-recipient breakdown of the same email, hit /signals.

Errors

  • 404 sent-email-not-found — no sent email with that id in your org.

bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails/semail_..." \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    f"https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails/{sent_email_id}",
    headers={"X-Cirrus-Api-Key": token},
)
response.raise_for_status()
sent_email = response.json()
csharp
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var response = await client.GetAsync(
    $"https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails/{sentEmailId}");
response.EnsureSuccessStatusCode();
var sentEmail = await response.Content.ReadAsStringAsync();

List recipient signals

GET /api/v1alpha1/buyer-signals/sent-emails/{sentEmailId}/signals

Per-recipient signal breakdown for one sent email — one row per recipient with their opens, clicks, replies, and last-event timestamps.

Query parameters

ParameterTypeDescription
cursorstringStandard keyset cursor.
limitnumberClamped 1–100, default 25.
sortstringlastReplyAt, lastOpenAt, replies, opens. Prefix - for descending. Default -lastReplyAt.
hasRepliedboolean(optional) When true, restrict to recipients whose reply was tracked.

Response

  • contactId is populated when the recipient email matches a Cirrus contact. null when the recipient isn't in the contact model (e.g., a fresh outbound to a new address).

Errors

  • 404 sent-email-not-found — no sent email with that id.
bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails/semail_.../signals" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    f"https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails/{sent_email_id}/signals",
    headers={"X-Cirrus-Api-Key": token},
)
response.raise_for_status()
page = response.json()
csharp
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var response = await client.GetAsync(
    $"https://altus.cirrusinsight.com/api/v1alpha1/buyer-signals/sent-emails/{sentEmailId}/signals");
response.EnsureSuccessStatusCode();
var page = await response.Content.ReadAsStringAsync();
json
{
  "items": [
    {
      "recipientEmail": "guest@example.com",
      "contactId": "cont_...",
      "opens":   5,
      "clicks":  1,
      "replies": 1,
      "lastOpenAt":  "2026-08-12T09:22:03Z",
      "lastClickAt": "2026-08-12T09:22:41Z",
      "lastReplyAt": "2026-08-12T10:14:07Z"
    }
  ],
  "nextCursor": null
}

Raleigh, NC — a Cirruspath, Inc. company