---
title: "Preview Emails"
method: GET
path: "/api/app-auto-gtm/segments/{segment_id}/preview-emails"
tags: ["AppAutoGtm"]
---

# Preview Emails

`GET /api/app-auto-gtm/segments/{segment_id}/preview-emails`

Return (or generate+cache) preview emails for ONE lead.

Single-lead flow: the UI asks for a specific `lead_id` (typically whichever
lead is currently selected in the "Preview as" dropdown). Backend generates
only for that lead — avoids spending tokens on leads the user never opens
and keeps `GenerationThinking` overlay short.

``touch`` scopes the request to ONE touch so a cache-miss request is a
single generation that fits the worker budget (issue #1338: both touches
in one request blew past the gunicorn timeout and surfaced as connection
resets). The client requests touch-1, then touch-2 as a dependent query —
each touch commits its cache row immediately, so a retry never re-pays
for an already-generated touch. An unconfigured ``touch`` returns ``[]``
(200): "no follow-up set up" is a normal state, not an error. Without
``touch`` the legacy walk over all configured touches is kept for
old clients during the rolling deploy.

Idempotent: `generated_email` is the cache keyed by
(lead_id, touch_number, email_templates_version). Switching leads in the
UI is a fresh queryKey on the client; revisiting a previously-selected
lead within the same session is a cache hit (react-query), and even
across sessions the backend returns the cached DB rows without another
LLM call. Touch-2 self-heals a missing touch-1 row via
``get_or_generate_email``'s internal recursion.

Generation failures return structured details the client can render:
400 ``{code: 'no_template'|'leak_detected', touch, message}`` for user-
fixable states, 502 ``{code: 'generation_failed', touch, message}`` for
upstream LLM failures (kept distinct from our own 500s in monitoring).

`language_used` and `highlights` come out of the JSONB `snapshot` on
each row — no new DB column, old rows default to empty values.

## Path parameters

- `segment_id` integer, required

## Query parameters

- `lead_id` string, required
- `touch` integer, nullable

## Cookies

- `ex_access` string, nullable
- `ex_org` string, nullable

## Response `200`

Successful Response

- GeneratedEmailPayload[]
  - `id` string, required
  - `segment_id` integer, required
  - `lead_id` string, required
  - `touch_number` integer, required
  - `email_templates_version` integer, required
  - `subject` string, required
  - `body` string, required
  - `lead_first_name` string
  - `lead_last_name` string
  - `lead_company_name` string
  - `language_used` string
  - `language_reason` string
  - `highlights` EmailHighlight[]
    - `text` string, required
    - `kind` 'research' | 'ab_test' | 'instructions' | 'playbook', required
    - `title` string, required
    - `explanation` string, required
    - `sources` string[]
  - `cache_hit` boolean

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/explee/apis/explee-api.md) · [All operations](https://skmtc.dev/explee/apis/explee-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/explee/explee-api/revisions/f169bc6e9447/schema)
