Per-lead enrichment and history
From the Campaigns API reference. Requests use the base URL https://app.warmerly.com/api/v1 and an API key, see Authentication.
GET /campaigns/{id}/leads/{leadId}/emails
POST /campaigns/{id}/leads/{leadId}/retry-enrichment
POST /campaigns/{id}/leads/researchemails returns { "emails": [...] }: every message scheduled for that lead in this campaign, ordered by scheduled time, the audit trail for "what did we actually say to this person". Each has id, stepId, status, subject, bodyText, bodyHtml, scheduledAt, sentAt, openedAt, clickedAt, repliedAt, bouncedAt and error.
retry-enrichment re-runs enrichment (contact-info check, then the paid email-finder fallback) for one lead whose earlier attempt failed or found nothing. Automatic enrichment fires only once per lead, so this is the only way to give a failed lookup another go. It needs a lead that has a LinkedIn profile URL (404 otherwise), uses the email lookup allowance and returns 402 with code quota_exhausted when that is exhausted. It returns { "started": true } straight away and the lookup continues on the server.
research generates website research summaries, which feed personalisation, for up to 20 leads per call: pass { "leadIds": ["…"], "force": false } (1 to 20 UUIDs). It is idempotent per lead: leads that already have a fresh summary are skipped unless force is true. The response is { "results": [{ "leadId", "ok", "summary", "reason" }], "generated", "total" }, so a partial failure is visible rather than silent. It spends AI credits (Usage & limits).