---
title: Tracking Endpoints Reference
path: reference/tracking-endpoints
status: published
---

# Tracking Endpoints Reference

Public endpoints invoked by recipients' email clients — tracking pixels, click redirects, unsubscribe pages, and the image proxy. These are not called by your application directly; they're referenced from the HTML of emails ScaiSend sends out.

**Base paths:** `/t/*` (tracking), `/i/*` (image proxy)
**Auth:** none. Every endpoint is public.

## GET /t/o/{token}.gif

Open tracking pixel. Returns a 1×1 transparent GIF.

**Token:** opaque per-message-recipient value. Tokens cannot be enumerated.

**Response:**

| Header | Value |
|--------|-------|
| `Content-Type` | `image/gif` |
| `Cache-Control` | `private, no-cache, no-store, must-revalidate` |
| `Pragma` | `no-cache` |

**Side effect:** records an `open` event on the associated message. The GIF is always 42 bytes; the response is identical whether or not the event was recorded.

## GET /t/c/{token}

Click redirect. Records a `click` event and redirects to the original URL.

**Query parameters:**

| Parameter | Notes |
|-----------|-------|
| `u` | URL-encoded original destination (present in rewritten links) |

**Response:** `302 Found` with `Location: <original-url>`.

If the token is invalid, returns `404`. If the `u` parameter is missing or the URL fails validation, returns `400`.

## GET /t/u/{token}

Unsubscribe landing page. Shows a confirmation UI where the recipient can choose to unsubscribe, pick groups to opt out of, or resubscribe.

**Response:** `200 OK` with HTML body. The page styling comes from the tenant's `subscription_tracking_landing_html` setting if set, or a default ScaiSend template otherwise.

## POST /t/u/{token}

Process an unsubscribe form submission. Called when the recipient clicks "confirm" on the landing page.

**Request body:** form-encoded. Fields:

| Field | Notes |
|-------|-------|
| `action` | `unsubscribe_all`, `unsubscribe_group`, or `resubscribe_group` |
| `group_id` | Required when action is group-scoped |

**Response:** HTML confirmation page.

**Side effect:** adds the recipient to the appropriate suppression list and emits an `unsubscribe`, `group_unsubscribe`, or `group_resubscribe` event.

## GET /t/u/{token}/one-click

RFC 8058 one-click unsubscribe landing. Renders a minimal HTML body confirming the action.

## POST /t/u/{token}/one-click

RFC 8058 one-click unsubscribe. Called by mail clients honoring the `List-Unsubscribe-Post: List-Unsubscribe=One-Click` header.

**Request:** typically `Content-Type: application/x-www-form-urlencoded` with body `List-Unsubscribe=One-Click` (the RFC 8058 canonical form).

**Response:** `200 OK` on success; `400` if the token is invalid or the request doesn't match the RFC 8058 envelope.

**Side effect:** adds the recipient to the global unsubscribe list (or the ASM group list, if the message was tagged with an `asm.group_id`), and emits the corresponding event.

## GET /i/{image_id}

Image proxy. Serves images uploaded to the tenant image library (`/v3/images`).

**Response:**

| Header | Value |
|--------|-------|
| `Content-Type` | Original MIME type |
| `Content-Length` | Byte size |
| `Cache-Control` | `public, max-age=31536000, immutable` |
| `ETag` | Content hash |

**Query parameters:**

| Parameter | Notes |
|-----------|-------|
| `variant` | `thumbnail` for a smaller preview variant |

**Side effect:** when the message's tenant has `image_embed_mode: proxy`, each load is recorded as a possible-open signal (fallback for when the tracking pixel is blocked).

**Errors:** `404` if the image doesn't exist; `410 Gone` if it was deleted after being sent.

### HEAD /i/{image_id}

Same headers as `GET /i/{image_id}`, no body. Useful for preflight and link-checking tooling.

## Inbound SMTP

Not an HTTP endpoint, but worth mentioning here: the SMTP service exposes port 25 for inbound DSN (bounce) and ARF (feedback loop) reports. It accepts mail from the internet and processes the envelope for bounce attribution and spam-complaint handling. No customer-callable API.

See [Bounce Handling](../concepts/bounce-handling) and [Feedback Loops](../concepts/feedback-loops).

## Health

### GET /health

Simple liveness check.

**Response (200):** `{"status": "healthy"}`.

### GET /ready

Readiness check. Verifies database connectivity.

**Response (200):** `{"status": "ready"}` if DB reachable; `503` otherwise.

## Related

- [Tracking](../concepts/tracking) — what's instrumented and why.
- [Suppressions](../concepts/suppressions) — what unsubscribes do.
- [Attachments and Images](../tutorials/attachments-and-images) — using `/i/{image_id}` in HTML.
