# Deliverability testing — relay reach, creative placement, marker tuning

> **TL;DR for agents:** Run in order: 1) `probe/relay-reach` — can this relay reach each provider with neutral content? 2) `probe/creative-through-relay` — does *this* creative inbox through a qualified relay? 3) `probe/creative-tune` — strip markers (links/images/words) until it inboxes. `probe/full-pipeline` chains all three. Poll `probe/:jobId`, read the grid at `matrix`. Over MCP these are the `ldm_DeliverabilityController_*` tools.

## Why three phases

A low inbox rate has two independent causes — the **relay** (sending reputation) or the **creative** (content). Testing them together hides which is at fault. The funnel isolates them: Phase 1 establishes the relay baseline, Phase 2 attributes a placement to the creative, Phase 3 finds the exact content marker. Each phase is an async probe — the `POST` returns `202 {jobId}`; poll `probe/:jobId` for results.

## Phase 1 — relay reach (qualify the channel)

Scope: `deliverability:write`. Send neutral, harmless baseline content from a **new relay** to each provider. Where it inboxes, the (relay, provider) pair is reachable; where it bounces or spams, a block-rule is written with category `cannot_deliver` (reason `not_delivered` / `smtp_reject` / `baseline_spam`). This is a per-channel reputation baseline, independent of any creative. MCP: `ldm_DeliverabilityController_startRelayReach`.

```bash
curl -s -X POST "https://api.live-direct-marketing.online/api/deliverability/probe/relay-reach" \
  -H "Authorization: Bearer $LDM_KEY" -H "Content-Type: application/json" \
  -d '{"relayAccountId":"<relay-account-id>","providers":["gmail.com","outlook.com"]}'
```

## Phase 2 — creative placement (test the message)

Scope: `deliverability:write`. Send the creative through an **already-qualified** relay and see which providers inbox it and which spam it. A fresh Phase-1 baseline must exist for each (relay, provider), otherwise the call returns `400 layer1_baseline_missing` — so a bad relay can never be mistaken for a bad creative. MCP: `ldm_DeliverabilityController_startCreativeThroughRelay`.

```bash
curl -s -X POST "https://api.live-direct-marketing.online/api/deliverability/probe/creative-through-relay" \
  -H "Authorization: Bearer $LDM_KEY" -H "Content-Type: application/json" \
  -d '{"relayAccountId":"<relay-account-id>","creativeId":"<creative-id>","providers":["outlook.com"]}'
```

## Phase 3 — marker tuning (find the spam trigger)

Scope: `deliverability:write`. For a (relay, provider) where the creative spams, tuning strips one marker at a time and re-tests until placement is inbox — isolating the element that trips the filter. Tunable markers: `link`, `image`, `third_party_email`, `spam_phrases`, `external_domain`, `utm_params`, `all_caps_subject`, `excessive_punctuation`. MCP: `ldm_DeliverabilityController_startCreativeTune`.

```bash
curl -s -X POST "https://api.live-direct-marketing.online/api/deliverability/probe/creative-tune" \
  -H "Authorization: Bearer $LDM_KEY" -H "Content-Type: application/json" \
  -d '{"creativeId":"<creative-id>","relayAccountId":"<relay-account-id>","provider":"outlook.com","maxAttempts":5}'
```

A winning variant is saved as a new clean Creative (the original is untouched) via `POST /deliverability/tuned-variants/:id/promote` — MCP `ldm_DeliverabilityController_promoteTunedVariant`. List candidates with `tuned-variants`.

## Run the whole funnel

Scope: `deliverability:write`. `probe/full-pipeline` runs Phase 1 across every (relay × provider), auto-chains Phase 2 where the baseline inboxes, then Phase 3 on the creative culprit. Pass `confirm:true` when the estimated send count exceeds 50 (cost gate). MCP: `ldm_DeliverabilityController_startFullPipeline`.

```bash
curl -s -X POST "https://api.live-direct-marketing.online/api/deliverability/probe/full-pipeline" \
  -H "Authorization: Bearer $LDM_KEY" -H "Content-Type: application/json" \
  -d '{"creativeId":"<creative-id>","confirm":true}'
```

## Read results

Scope: `deliverability:read`. `probe/:jobId` returns the aggregate batch status plus the Phase-3 diagnosis (MCP `getJobStatus`). `matrix` is the dashboard — a relay × provider grid of baseline / creative / block-rule (MCP `getMatrix`). `probes` is the raw audit log; `block-rules` lists the marks (`listBlockRules`). Probe results cache for 24h — pass `forceRefresh:true` to a probe to bypass.

```bash
curl -s "https://api.live-direct-marketing.online/api/deliverability/matrix?creativeId=<creative-id>" \
  -H "Authorization: Bearer $LDM_KEY"
```

Lifting a block needs the narrower `deliverability:block:delete` scope (`DELETE /deliverability/block-rules/:id`): an agent can place blocks with `deliverability:write` but not silently lift them.
