GET /api/v1/products/{id}/communication
Returns a single offering's outreach activity: summaries of blast campaigns targeting it, plus a merged timeline of 1:1 communications (emails, calls, meetings, notes) tied to it, both sorted newest-first. Useful for building an "activity" view for a product/service/subscription/contract without querying campaigns and communications separately.
Requires the read:offerings scope (or * for full access). See Scopes.
Request
GET /api/v1/products/cmq1abc2def3ghi4jkl5/communication HTTP/1.1
Host: agentlyleads.com
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxPath parameters
| Parameter | Description |
|---|---|
id | ID of the offering (product/service/subscription/contract) to fetch activity for |
Response — 200
{
"offeringId": "cmq1abc2def3ghi4jkl5",
"campaigns": [
{
"id": "cmq2xyz9abc1def2ghi3",
"name": "Promo",
"subject": "Introducing our new plan",
"status": "SENT",
"scheduledAt": "2026-06-01T12:00:00.000Z",
"recipientCount": 120,
"sentCount": 118,
"openCount": 42
}
],
"timeline": [
{
"id": "cmq3lmn4opq5rst6uvw7",
"kind": "email",
"subject": "Following up on the demo",
"snippet": "Hi Pat, just wanted to follow up on...",
"direction": "OUTBOUND",
"contact": { "id": "cmq4pat0000abc1def2g", "name": "Pat" },
"occurredAt": "2026-06-02T09:15:00.000Z"
}
]
}campaigns[]
Blast campaigns that target this offering.
| Field | Type | Description |
|---|---|---|
id | string | Campaign ID |
name | string | Campaign name |
subject | string | Email subject line used by the campaign |
status | string | Campaign lifecycle status (e.g. DRAFT, SCHEDULED, SENDING, SENT) |
scheduledAt | string | null | ISO 8601 date-time the campaign is/was scheduled to send, or null |
recipientCount | integer | Total recipients targeted |
sentCount | integer | Recipients the campaign actually sent to |
openCount | integer | Distinct recipients who opened at least one email from the campaign — one recipient opening the same email multiple times still counts once. Counts opens by a person only; automated opens are excluded (see below) |
How opens are counted
Opens are measured with a one-pixel tracking image in each sent email, so an open is recorded only when the recipient's mail client loads images. Each load is classified as a person open or an automated one from the requesting client: image prefetches by Apple Mail Privacy Protection and the link checks run by corporate security scanners are recorded as automated, shown separately in the CRM, and never counted in openCount or in a campaign's open rate. Gmail fetches images through a caching proxy, so repeat opens by the same Gmail reader can be hidden behind the first one. No location is recorded for any open.
timeline[]
A merged, newest-first list of 1:1 communications tied to this offering. Blast campaign sends are not included here — they're summarized under campaigns instead.
| Field | Type | Description |
|---|---|---|
id | string | ID of the underlying record (email message or communication log entry) |
kind | string | One of email, call, meeting, note, other (see below) |
subject | string | null | Subject line, if applicable |
snippet | string | Plain-text preview, truncated to 140 characters |
direction | string | null | INBOUND / OUTBOUND (or null if not applicable) |
contact | object | null | { "id": string, "name": string } for the associated contact, or null |
occurredAt | string | ISO 8601 date-time the communication occurred |
kind values
| Value | Source |
|---|---|
email | A 1:1 EmailMessage sent to/from a contact (not part of a blast campaign) |
call | A logged call |
meeting | A logged meeting |
note | A logged note |
other | Any other logged communication type |
Errors
| Status | Meaning |
|---|---|
401 Unauthorized | Missing, invalid, or expired API key |
403 Forbidden | API key lacks the read:offerings scope |
404 Not Found | No offering with this id exists in the workspace (also returned for a foreign workspace's offering, to avoid leaking existence) |
429 Too Many Requests | Rate limit exceeded |
See the Products API errors page for the shared error response shape.