Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions fern/apis/api/definition/domains.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,10 @@ types:
on its own — usually resolves without changes), `ses_dkim_failed` /
`ses_mail_from_failed` (a terminal verdict; re-verify after fixing),
`ses_dkim_not_started` / `ses_mail_from_not_started` (the attribute was never
configured on the identity — re-verify to push it), and
`ses_not_verified_for_sending`. Absent when VERIFIED.
configured on the identity — re-verify to push it),
`ses_not_verified_for_sending`, and `tracking_certificate_failed` (the certificate
for the open tracking `link.` subdomain was refused; fix CAA or DNS, then turn
tracking off and back on). Absent when VERIFIED.
feedback_enabled: FeedbackEnabled
inbound_enabled:
type: optional<InboundEnabled>
Expand Down
1 change: 0 additions & 1 deletion fern/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,6 @@ navigation:
path: pages/knowledge-base/labels-track-state.mdx
- page: Knowing when an email is opened
icon: fa-solid fa-envelope-open
hidden: true
path: pages/knowledge-base/open-tracking.mdx
- section: Domains & Deliverability
contents:
Expand Down
1 change: 1 addition & 0 deletions fern/pages/knowledge-base/domain-not-verifying.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ for (const record of domain.records) {
| `ses_dkim_failed`, `ses_mail_from_failed` | A final failure for DKIM or for the MAIL FROM records | Confirm the DKIM record (or the `mail` MX and SPF records) are correct, then click **Verify Domain** |
| `ses_dkim_not_started`, `ses_mail_from_not_started` | That part of verification was never started | Click **Verify Domain** |
| `ses_not_verified_for_sending` | DKIM and MAIL FROM both pass, but the domain is not yet enabled for sending | Click **Verify Domain**; contact support if it persists |
| `tracking_certificate_failed` | The certificate for the open tracking `link` subdomain was refused | Set the `link` record to DNS only and allow Amazon in any CAA records, then turn open tracking off and back on. See [open tracking setup](/knowledge-base/open-tracking#setup) |

**Record reasons:**

Expand Down
2 changes: 1 addition & 1 deletion fern/pages/knowledge-base/inbox-capabilities.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Features marked **Labs** are in AgentMail Labs. An organization admin joins Labs
- **Drafts.** Create a draft, let a person or another process review and edit it, then send it. Drafts can also be replies and forwards. See [Drafts](https://docs.agentmail.to/drafts).
- **Scheduled send.** Set `send_at` on a draft and AgentMail sends it at that time, with no cron job on your side. Update `send_at` to reschedule, or set it to `null` to keep the draft unsent. Scheduling is a draft feature: Send Message always sends immediately. See [Scheduled sending](https://docs.agentmail.to/drafts#scheduled-sending).
- **Safe retries.** Send an `Idempotency-Key` header so a retried send request does not send the email twice. See [Idempotency](https://docs.agentmail.to/idempotency).
- **Open tracking (private beta).** Find out when a message is first opened. It requires a custom domain with tracking enabled and the Developer plan or above, and is turned on by request. See [How do I know when an email is opened?](https://docs.agentmail.to/knowledge-base/open-tracking).
- **Open tracking.** Find out when a message is first opened. It is included on every plan and needs a custom domain with tracking turned on, in the console or through the API. See [How do I know when an email is opened?](https://docs.agentmail.to/knowledge-base/open-tracking).

## Receiving

Expand Down
44 changes: 32 additions & 12 deletions fern/pages/knowledge-base/open-tracking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@ subtitle: Track opens on the emails your agent sends, and react when a recipient
slug: knowledge-base/open-tracking
---

<Warning>
Open tracking is in **private beta**. It requires the **Developer plan or above** and must be enabled on your organization by our team. Email [support@agentmail.cc](mailto:support@agentmail.cc) to request access.
</Warning>

When you send with `track_opens`, AgentMail adds an invisible 1x1 pixel to your HTML body, served from your own domain. The first time a recipient's mail client loads that pixel, the message is marked as opened.

You can see opens two ways: the `opened` label on the message, which you can poll or filter on, and the `message.opened` event, which is pushed to your webhook the moment it happens.

Open tracking is included on every plan at no extra cost. You turn it on per domain, in the console or through the API.

## Setup

Open tracking is only available on a custom domain, because the pixel is served from your domain and carries your sender reputation rather than a shared one. See [Custom domain setup](/knowledge-base/custom-domain-setup) if you do not have one yet.

### Turn it on in the console

In the [AgentMail Console](https://console.agentmail.to), go to **Domains**:

- **New domain:** click **Add Domain** and check **Open tracking**.
- **Existing domain:** open the domain's actions menu, choose **Edit**, and check **Open tracking**.

The console then shows the domain's records, including the new `link.<domain>` CNAME.

### Turn it on with the API

Enable tracking when you create the domain:

<CodeBlocks>
Expand Down Expand Up @@ -68,7 +77,11 @@ const domain = await client.domains.update("mail.yourcompany.com", {
```
</CodeBlocks>

Until open tracking is enabled on your organization, either call returns `403` with code `forbidden`. Once it is enabled, either call adds a `link.<domain>` CNAME to the domain's `records`. Publish every record at your DNS provider, then wait for the domain to report `VERIFIED`:
Either call adds a `link.<domain>` CNAME to the domain's `records`.

### Publish the CNAME record

Publish every record at your DNS provider, then wait for the domain to report `VERIFIED`:

<CodeBlocks>
```python title="Python"
Expand All @@ -86,11 +99,22 @@ console.log(domain.trackingEnabled); // true
```
</CodeBlocks>

Certificate issuance for the `link.` subdomain usually takes a few minutes after the CNAME resolves.
Once the CNAME resolves, AgentMail requests a TLS certificate for `link.<domain>`. Issuance usually takes a few minutes.

<Warning>
Turning on tracking for a domain that is already `VERIFIED` moves it back to `PENDING`. It returns to `VERIFIED` once the CNAME resolves and the certificate is issued. Until then, you cannot create new inboxes on the domain, and sends with `track_opens` are rejected. Sending without `track_opens` is not affected.
</Warning>

Two DNS settings commonly block the certificate:

- **Proxied records.** If your DNS provider can proxy traffic, such as Cloudflare's orange cloud, set the `link` record to **DNS only**. A proxied record does not resolve to the CNAME target, so the domain cannot verify.
- **CAA records.** If your domain or a parent domain has CAA records, they must allow Amazon to issue the certificate. Add `0 issue "amazon.com"` next to your existing CAA records. If you have no CAA records, there is nothing to change.

If the certificate is refused, the domain moves to `FAILED` with the reason `tracking_certificate_failed`. Fix the DNS, then turn tracking off and back on to request a new certificate.

## Sending a tracked message

Set `track_opens` on any send, reply, or reply-all:
Set `track_opens` on any send, reply, reply-all, or forward:

<CodeBlocks>
```python title="Python"
Expand Down Expand Up @@ -269,10 +293,6 @@ If your agent takes action on an open, such as sending a follow-up, design it to

- **First open only.** The label and the event fire once per message. Repeat opens are not counted.
- **One pixel per message, not per recipient.** A message sent to several recipients fires once when any of them opens it, and the event does not say which one. Send separate messages if you need per-recipient attribution.
- **Immediate sends only.** `track_opens` is honored on send, reply, and reply-all. It is not yet supported on drafts or scheduled sends.
- **Immediate sends only.** `track_opens` is honored on send, reply, reply-all, and forward. It is not yet supported on drafts or scheduled sends.
- **Custom domains only.** Tracking is not available on shared AgentMail domains.
- **No click tracking** yet.

## Getting access

Open tracking is in private beta on the Developer plan and above. Email [support@agentmail.cc](mailto:support@agentmail.cc) with your organization and we will enable it. We are actively collecting feedback on this feature, so tell us what is missing.
Loading