Market Intelligence: Multi-Agent Sales Platform
A live multi-agent platform that continuously tracks Swedish public sector orgs, their procurements, decision-makers, and LinkedIn activity, and drops ready-to-send outreach drafts straight into the team's inbox every morning.
TL;DR
Two AI agents, Maja and Lina, that do the work of a small sales-intelligence team for a consulting business. Maja scans 89 target organisations every morning for procurements, news, leadership changes, and LinkedIn signals; Lina turns those signals into prioritised, ready-to-send outreach drafts that land in the team's inbox by 08:00. Live and always on, running unattended on a single server, with a quality floor that skips thin drafts rather than writing them.
Maja and Lina are two AI agents that together replace what a small sales-intelligence team would normally do at a consulting business. The platform is live and always on. It runs unattended on a single Hetzner VPS, shares one SQLite database between the agents, and posts each morning's summary to two separate Telegram bots so it's always clear which agent is talking.
What it continuously tracks for every org in the target list: new procurements (upphandlingar) on central portals and on the org's own procurement page; key decision-makers and their LinkedIn profiles; the org's own LinkedIn activity; press releases and news; and changes in leadership. New signals show up in the team's dashboard the same morning they appear in the wild.

Maja is the research agent. Every morning at 06:00 Stockholm time she does a smart scan across all 89 target organisations, deep-dives only the ones where a new signal appeared overnight, and writes news, decision-maker profiles, and procurement events back to the database. Late evening she runs two more passes: one against the central procurement portals (TED, e-avrop, tendsign, kommersannons) and one against each org's own procurement page when one exists. Coverage on those direct pages is 39 of 89, the rest fall back to portal scanning plus Google search. A weekly LinkedIn scan picks up org-page posts via the Voyager API on a burner cookie, and a monthly Brave Search pass discovers new decision-maker profile URLs as the team fills out.
Lina is the sales assistant. She runs in two parts: an analyst at 07:30 that reviews Maja's overnight signals and inserts prioritised sales suggestions (max three at priority ≥9 per day, scored against a strict rubric), and a drafter at 08:00 that writes outreach emails for the suggestions the analyst flagged as outreach-ready. A second drafter pass at 16:00 catches anything the morning run did not finish. Each draft has to clear a specificity floor (≥2 named entities) and a length cap (≤1100 character body); anything that does not meet the floor is skipped with draft_status='thin_signal' rather than written thin.
The favourite feature. Drafts don't sit in a queue waiting to be copy-pasted, they land directly in the user's email inbox as a real draft email, fully customised to the recipient, the org, and the signal that triggered it. The team opens their inbox in the morning and all that's left is to read, optionally tweak a sentence, and press send. That last-mile detail is what made the platform actually used rather than admired.

Coverage right now. All 89 active organisations have a research report, none empty. 75 of those reports are substantial at 5,000 characters or more; 54 are deep dives at 8,000+. The 13 still thin are mostly universities the team has explicitly deprioritised to focus on agencies. On the outreach side: every org has at least one analysed sales suggestion, 86 of 89 have email drafts queued, and 3 were deliberately skipped by Lina's quality floor rather than written thin. Plus 770 mapped decision-makers including 98 with verified LinkedIn URLs, 619 news items, 784 LinkedIn posts pulled by the weekly company scan, 361 sales suggestions, and 115 outreach drafts ready for human review.
The dashboard is where the human work happens. Four tabs, Feed, Organisations, Upphandlingar, Sales, and a kanban workflow layer added in April: every suggestion and every draft has a new → in_progress → done | parked workflow column independent of Lina's pipeline state, with done_action (email sent, meeting booked, reply received) and parked_reason captured at transition. Three teammates log in through nginx basic auth and the backend reads X-Remote-User to attribute every action to the right person. An item_actions audit log captures every move and review toggle so the team can see who did what.

Why two agents and not one. The split is on ownership. Maja owns research columns; Lina owns outreach columns. Neither overwrites the other. After a near-incident where a kitchen-sink UPDATE in Maja's deep-report routine wiped LinkedIn URLs that the scan pipeline had populated, the prompt was hardened to forbid combining columns in a single statement. That fix is enforced in the prompt template, not in glue code, the agent is the one that has to know.
Why Codex 5.5 and not Claude or GPT-4o. The platform runs on OpenAI Codex via ChatGPT Team OAuth tokens, two profiles installed, each with its own 5-hour rolling quota and weekly ceiling, and a per-agent priority order so deep-research batches can lock onto the freshest seat. Cost per draft sits in the order of fractions of a cent; cost per deep report under twenty cents. That economics depends on the seat-rotation pattern; without it, throughput collapses on the weekly cap.
Failure modes the platform was hardened against. OpenClaw's CLI returns nothing without a TTY, so every batch wraps in script -qc. Maja's main session accumulates context across runs and silently aborts at 30 minutes, so a session-clearing helper runs before every batch step. DuckDuckGo started bot-blocking the VPS IP, so Brave Search was wired in at roughly $8/month. LinkedIn's Voyager REST endpoints went 410 for personal profiles, so person-post fetching is parked pending a Playwright or Proxycurl decision while the company-page scan still runs weekly. The 2026.4.24 OpenClaw upgrade introduced a Bonjour plugin crash that took the gateway into a restart loop until the plugin was disabled. None of this is in the marketing, it's in the code.

Where it's headed. The current build is the foundation. The roadmap turns this into a full lightweight CRM, the team keeps adding new target organisations as their focus shifts, every new org plugs into the same Maja-research → Lina-suggestion → Lina-draft → inbox pipeline with no extra setup, and the workflow layer in the dashboard grows to cover the rest of the sales cycle (replies, meetings, won/lost, account history). Same architecture, broader surface.
What you see when you log in is calm. What's underneath is a system that survives upgrades, rate limits, search-engine churn, and LinkedIn API drift, and still drafts outreach the next morning.
Questions about this work, or something like it?
Ask the agent