Dual-brand SMTP routing. Calendar-slot attachments where appropriate. Tracked open and link click through /b/:shareId redirects on your own host. Per-domain throughput caps tuned to human cadence, not blast volume.
review.decision === "approve" — gateworkspace.brands[] — SMTP creds per brandpack.brand — which sender to route throughpack.sendCadence — per-domain throughput capworkspace.warmupState — domain warm-up phasedraft.calendarSlot — optional ICS attachmentemail_message.id, .messageId — RFC ids for IMAP threadingemail_message.brand, .fromAddressemail_message.sentAt, .deliveredAtemail_message.openedAt, .openCountemail_message.clickEvents[] — via /b/:shareIdemail_message.bouncedAt, .bounceCodeemail_message.email_prompt_id — back-link for funnel attributionSend is the action. Approved drafts queue against the brand the pack declares — typically the workspace ships under one or two sender brands, each with its own SMTP credentials, signature, and tracking domain. Routing picks the brand at draft time, not send time, so the recipient never sees a brand mismatch between the body voice and the From line. The send service holds the queue and releases messages at the per-domain cadence configured for that brand and warm-up state.
Throughput is human-shaped, not maximum. The cap is set per pack and per warm-up phase, with randomized intervals inside business hours for the recipient's timezone. We do not provide a "send 5,000/day" knob. The point of Paitho is per-lead quality, and quality breaks under blast cadence — domain reputation is the next thing to break after copy quality. Domain warm-up state (cold, warming, mature) is enforced server-side; a fresh domain throttles to a minimum daily volume regardless of queue length.
Tracking goes through your own domains. The open pixel and the click redirect (/b/:shareId) live on your tracking subdomain, not a shared service host — so your link previews are your URL, and every click and open is logged in your workspace alongside the send. ICS calendar-slot attachments are added when the draft includes a slot offer; when it doesn't, the message ships plain so it isn't flagged as transactional. Bounces feed back into the contact suppression list; subsequent sends to the same address are blocked workspace-wide.
--- brand routing --- function routeToBrand(pack, draft) { const brand = pack.brand; # declared at draft time const smtp = workspace.brands[brand]; if (!smtp) throw "brand_not_configured"; if (workspace.warmupState[brand] === "cold") enforceMinimumVolumeOnly(); return { host: smtp.host, port: smtp.port, user: smtp.user, # your creds fromAddress: smtp.fromAddress, signature: smtp.signature }; } --- throughput governor (per domain) --- { "perHourCap": {{pack.sendCadence.perHour}}, "jitterMs": "[8000, 24000]", "businessHoursOnly": true, "timezoneSource": "recipient | sender", "warmupOverride": true # cold domains throttle harder } --- tracking --- - open pixel: <img src="https://{{brand.trackDomain}}/o/{{message.id}}.gif"/> - link click: <a href="https://{{brand.trackDomain}}/b/{{shareId}}"> → 302 → original URL with ?utm tags --- attachments --- if (draft.calendarSlot) attach(generateICS(draft.calendarSlot)); # <!-- PLACEHOLDER — exact pacing figures per pack -->
A new domain ships a hundred messages on day one, ISPs flag and throttle.
Domain warm-up phase enforced server-side. Cold domains cap at a minimum daily volume regardless of queue. Warm-up phase advances on consecutive low-bounce days.
Body is written in brand A's voice, From line goes out under brand B.
Brand is locked at draft time on the email_draft row. Sender refuses to ship if brand at send-time doesn't match brand on draft.
Same invalid address is contacted again from a different lead pull.
Bounces auto-suppress the address workspace-wide. Suppression check happens at queue-time and at send-time.
Connect SMTP. Watch the queue release at human cadence with full event logs.