# Build spec: outreach queue Turns the lead database into a working queue: who to contact next, what is true about them, and what to say in the first line. Build this when the user is actually emailing these leads and the bottleneck is deciding what to write. **Before you build:** ask. See https://lyreleads.com/build for the four rules that apply to every build on this API. **This spec does not send email.** It prepares. Sending belongs in whatever tool the user already uses, and their deliverability is not something to put at risk with a homemade sender. --- ## The idea The enrichment data is a list of specific, checkable facts about each business. A first line built from one of those facts is a different object from a first line built from a template. We know the site loads in 6.2 seconds. We know there is no CRM. We know they run WooCommerce with no email marketing. We know they have 340 reviews and a 3.6 rating. We know they block GPTBot. The queue's job is to put the fact and the person on the same screen, in priority order, and let the user write. --- ## What it does 1. Builds a queue from a filter, ordered by how good the fit is. 2. Shows one lead at a time: the business, the person, the evidence. 3. Drafts an opener from the strongest signal, for the user to edit. 4. Records the outcome and moves on. --- ## Queue construction Source from the local store (see the [lead dashboard](https://lyreleads.com/build/lead-dashboard.md)) or straight from `/api/v1/results`. **Contactability first.** A lead with no address is not queue-ready. Rank: 1. `decision_maker_email` present and `verified` — a named person, SMTP-confirmed. 2. `decision_maker_email` present and `published` — a named person, address from the company's own site, on a catch-all domain so unconfirmable. Sendable. Label it. 3. Business `email` `verified` — a real mailbox, probably generic. 4. Business `email` `published` or `catch_all` — send if the user accepts the risk, and show them the state so they are choosing it. 5. No address — not in the queue. Offer `find_decision_makers` on this segment instead. Never silently mix tiers. The user should be able to see at a glance that today's 40 sends are 12 verified-personal, 18 verified-generic, 10 unconfirmable. **Then fit.** Within a contactability tier, sort by AI score if they have one, or by whatever signal they are selling against. --- ## The lead screen Everything needed to write one email, on one screen, without scrolling: - Business name, category, city, website (clickable) - Person: name, title, LinkedIn if known - The address, with its state as a badge - **The evidence block**: the 3–5 facts that make this a lead. Not all 50 fields. The ones that matter for what the user sells. - Google rating and review count - Draft opener, editable - Actions: copy, mark sent, skip, disqualify Show the evidence with its provenance where it matters. "No CRM detected (site enriched 2026-08-02)" is honest. "No CRM" is a claim that ages badly. --- ## Drafting the opener Pick the **strongest single signal** and write one specific sentence. Not five signals. One. Rough priority, best first: | Signal | Why it works | |---|---| | Slow page load, measured | Specific, verifiable, and they can feel it | | High reviews, mediocre rating | A real business problem with real volume behind it | | E-commerce with no email marketing | Money on the table, obviously | | No analytics at all | They are flying blind and usually know it | | No CRM, with a contact form | Leads arriving nowhere | | Blocked to AI crawlers | Nobody has told them, and it is becoming expensive | | Ancient copyright year / stale site | Soft; use only if nothing better | Rules for the draft: - Name the fact, do not editorialise. "Your site takes 6.2 seconds to load on mobile" beats "I noticed some performance issues". - One sentence of observation, one of relevance. Not a paragraph. - No merge-field tells. If it reads like a template with a hole, it is worse than plain. - **Never invent a fact.** If the field is `NULL`, you do not know it. An opener built on a hallucinated observation is the fastest way to burn a domain and a reputation. - Leave it editable and expect it to be edited. The draft is a starting point, not an output. If the user has told you what they sell, use it to pick which signal to lead with. A web designer wants the slow site; an agency wants the missing pixels; a CRM vendor wants the contact form with nothing behind it. --- ## Outcome tracking Local, minimal: ```sql CREATE TABLE outreach ( lead_id INTEGER PRIMARY KEY, status TEXT, -- queued | sent | replied | disqualified | skipped channel TEXT, sent_at TEXT, signal_used TEXT, -- which fact led the opener notes TEXT ); ``` `signal_used` is the one non-obvious column and the most valuable. After a few hundred sends the user can see which signal actually produces replies, which is a thing almost nobody measures and everybody guesses at. Report reply rate by signal, and by email tier. If `published` addresses reply at the same rate as `verified` ones, that is worth knowing. If they bounce far more, that is worth knowing sooner. --- ## Traps specific to this build **Sending from the app.** Do not. Deliverability is a specialist problem and a homemade sender on a real domain is a bad trade. **Tracking pixels and links in a first email.** They hurt deliverability, and open rates are a poor proxy for anything. Reply rate is the only number worth optimising here. If the user wants tracking, tell them the cost. **Presenting `catch_all` as verified.** It is not a confirmation. Show the state, every time. **Writing an opener from a `heuristic` field.** Blog, careers page, case studies and demo CTA are keyword guesses and can be wrong. Do not build a cold opener on one. Check `enrichment_provenance` if you are unsure. **Stale facts.** A tech-stack observation from four months ago may be wrong: 1.9% of readable sites switched a core platform within a median 106 days. If the enrichment is old and the opener depends on it, re-enrich that lead first. It costs 0.2 tokens. **Queueing leads with no address.** Wasted screens. Filter them out and offer decision-maker discovery on that segment instead.