# Managing emails

> The email lifecycle, every delivery status, previewing HTML/text, and reading the per-email event log.

Every email you send through SendPing is recorded as an **email** object with a stable `id`, the content you sent, and a `status` that advances as SendPing reports what happened to the message. You can [retrieve an email](https://www.sendping.co/docs/api/emails-get) at any time to read its current status and the full event log.

Status changes are driven by real delivery notifications (delivery, bounce, complaint) plus SendPing's own open/click tracking engine. Each transition is recorded once and (if you have webhooks configured) forwarded as an `email.<event>` webhook.

## Lifecycle

An email starts in one of two states depending on whether you scheduled it, then advances through delivery and engagement states as events arrive:

1. **Created** — A `POST /emails` with no `scheduled_at` is queued for delivery immediately and starts as `sent`. A `POST /emails` with a future `scheduled_at` is stored as `scheduled` and held until its run time.
2. **Sent** — The message has been accepted for delivery and is on its way. Scheduled emails enter `sent` when the scheduler dispatches them at `scheduled_at`.
3. **Delivered** — The receiving mail server accepted the message. Some messages may instead report `delivery_delayed`, `bounced`, or `complained`.
4. **Engaged** — If open/click tracking is enabled on the sending domain, the email advances to `opened` and then `clicked` as the recipient interacts with it.

## Statuses

The `status` field (and `last_event`) takes one of the following values:

| Status | Meaning |
| --- | --- |
| `queued` | Transient initial state — accepted by SendPing and about to be handed to the sender. Sends move through this state in milliseconds, so you will normally observe `sent` (or `scheduled`) rather than `queued`. |
| `scheduled` | Held for future delivery — `scheduled_at` is in the future. The email has not been sent yet and can still be rescheduled or canceled. |
| `sent` | Queued for delivery. This is the initial state for an immediate (non-scheduled) send. |
| `delivered` | The receiving server accepted the message. |
| `delivery_delayed` | Delivery was temporarily delayed (e.g. a transient soft bounce or a throttling/grey-listing receiver). SendPing may still deliver it. |
| `bounced` | The message bounced. A permanent (hard) bounce also auto-suppresses the recipient — see [Email bounces](https://www.sendping.co/docs/emails/bounces). |
| `complained` | The recipient marked the message as spam. The recipient is auto-suppressed — see [Email suppressions](https://www.sendping.co/docs/emails/suppressions). |
| `opened` | The recipient opened the email (open tracking must be enabled on the sending domain). |
| `clicked` | The recipient clicked a tracked link (click tracking must be enabled on the sending domain). |
| `canceled` | A scheduled email was canceled via [POST /emails/:id/cancel](https://www.sendping.co/docs/api/emails-cancel) before it was sent. |
| `failed` | The message was rejected outright (for example, the content was rejected) and it was never sent. |
| `suppressed` | The recipient was on the account suppression list, so the send to that recipient was skipped — see [Email suppressions](https://www.sendping.co/docs/emails/suppressions). |

> **Note:** Open and click statuses are driven by SendPing's own tracking engine, not by delivery notifications, so they appear only when open/click tracking is enabled for the sending domain.

## Previewing content

The retrieved email includes the exact `html` and `text` bodies you submitted, so you can preview what was sent. If you send only `text`, SendPing generates an HTML alternative from it; if you send only `html`, that HTML is delivered as-is. Tracking pixels and rewritten links (when tracking is enabled) are applied to the outbound message at send time and are not reflected back in the stored body.

## How links are tracked

You write ordinary links. When the sending domain has click tracking enabled, SendPing replaces each destination with a tracked redirect **at send time**, in the copy handed to the recipient only.

Everything a link can look like is covered, in **both** the `html` and the `text` body: `<a href="…">` targets, markdown-style `[label](url)` links, and bare URLs or domains written in running text (`https://acme.com/sale`, `www.acme.com`, `acme.com/sale`). Link text is preserved — a recipient still sees `acme.com/sale`, or your anchor text, and only the underlying destination changes. In the plain-text part, where there is no separate label, the URL itself is replaced so no untracked copy of the destination is left for the recipient to click.

Content already inside an `<a>` tag, attribute values, `<pre>`/`<code>` blocks, non-`http(s)` schemes (`mailto:`, `tel:`), and every unsubscribe or preference-centre link are left exactly as written. Opting out is never recorded as engagement.

| Property | Behaviour |
| --- | --- |
| Your stored content | Never modified. [GET /emails/:id](https://www.sendping.co/docs/api/emails-get), the dashboard, and your campaign and template editors keep showing the link you wrote, permanently. |
| One link per recipient | Every recipient of a campaign or multi-recipient send gets their own signed URL, so a click identifies exactly who clicked. The `html` and `text` parts of one message also carry separate link ids. |
| Repeat clicks | Always redirect. The recipient can click a link any number of times and always lands on your URL; only the *first* click per recipient per destination advances the click count, so re-reads never inflate your click rate. |
| Link lifetime | Permanent. A tracked link keeps resolving to your destination long after the email leaves your log-retention window — delivered mail is forever, so the redirect has to be. Once the email ages out of retention the click still redirects, it simply stops recording engagement. |
| Custom tracking domain | If the sending domain has a verified tracking subdomain, links use it (`https://t.yourdomain.com/t/c?…`); otherwise they use SendPing's shared host. Changing or switching off the subdomain later never breaks links already in delivered mail. |

> **Note:** Links in the **subject line** cannot be tracked — mail clients do not make subject text clickable, so there is nothing to rewrite. Put the link in the body.

## The event log

Each email carries an ordered `events` array — every recorded transition (`sent`, `delivered`, `delivery_delayed`, `bounced`, `complained`, `opened`, `clicked`, `failed`) with the time it occurred. Events are de-duplicated: a redelivered notification will not record the same event twice. Fetch the log with [GET /emails/:id](https://www.sendping.co/docs/api/emails-get).

```json
{
  "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794",
  "object": "email",
  "status": "delivered",
  "last_event": "delivered",
  "events": [
    { "type": "sent", "created_at": "2026-06-23T10:00:00.000Z" },
    { "type": "delivered", "created_at": "2026-06-23T10:00:04.512Z" }
  ]
}
```

> **Note:** Want events pushed to you instead of polled? Configure [webhooks](https://www.sendping.co/docs/webhooks/overview) to receive an `email.delivered`, `email.bounced`, `email.opened`, etc. callback as each event is recorded.
