Your pipeline, built
from the replies you earn.
Contacts, pipelines, deals, tasks and notes in one workspace, wired to your campaigns. A positive reply opens a deal, attributes it to the campaign and mailbox that earned it, and the board stays live as your outbound runs.
A reply does not sit in an inbox.
Most CRMs start where the deal already exists. This one starts at the send. The same event that classifies a reply opens the deal, links the contact, and drops a follow-up on a named owner. You manage the pipeline, not the data entry.
Imported, deduped and categorised. Suppression-aware everywhere it appears.
A campaign step sends from a warmed mailbox under its per-mailbox cap.
The classifier reads the inbound reply, tags it positive, and pauses the sequence.
A deal opens on the pipeline, attributed to the campaign and mailbox that earned it.
A follow-up task lands on a named owner, and the board updates live.
Every deal remembers where it came from.
A deal carries the campaign and the sender mailbox that produced the reply it was opened from. Won revenue traces straight back to the outreach that created it, so you can tell which sequences and which mailboxes actually close.
- Both links are nullable and editable. It is a best guess at creation, not locked ground truth.
- ON DELETE SET NULL keeps won-revenue history when an old campaign or mailbox is cleaned up.
- Filter the whole pipeline by attributed campaign to see revenue per sequence.
Build the stages your deals actually move through.
A pipeline is a named flow of stages. Start from a template or build your own, rename and recolour stages inline, and reorder them as your motion changes. Each stage tracks its own deal count for an at-a-glance forecast.
Totals stay true past the first page.
Search, filter and sort run on the server, so the board works the same with twelve deals or twelve thousand. Every header total is a real SUM and COUNT over the whole matching set, never a reduce over the rows that happen to be loaded.
Nothing waiting on a reply slips.
Tasks attach to a contact or a deal and go to a person or a whole team. Group them by due date so overdue work surfaces first, set a type and a priority, and check them off inline. The counts above are a server-side summary, so overdue is overdue across the whole org.
One contact list, suppression-aware.
Contacts is where the spreadsheet usually wins. Not here. Import with a mapping wizard, dedup before rows land, and the moment a contact bounces, complains or opts out, they drop off every campaign in the workspace at once.
The recipient drops off every campaign in the workspace.
Suppressed, and the mailbox health score takes the hit.
Honoured per RFC 8058 before the confirmation page loads.
The reply classifier opts them out with nobody in the loop.
Six objects. Six tables. No magic.
The CRM is built around six real entities. Each maps to a Postgres table you can read through the public API. Categories reuse the existing group table, so tagging never drifts into a parallel system.
→ contacts People and companies, deduped and categorised, suppression-aware across every campaign.
→ pipelines Named stage flows you build per workflow. Each stage carries its own colour and order.
→ deals Value, close date, owner, status, and the campaign + mailbox that produced the reply.
→ crm_tasks Follow-ups tied to a contact or deal, assigned to a person or a team, due-date bucketed.
→ contact_notes Free-text notes on a contact. Plain, searchable, and stamped with who wrote them.
→ contact_activities A typed timeline: sends, opens, replies, stage moves, won and lost, all on one record.
Already on a CRM? Keep it.
Two-way sync with HubSpot, Salesforce and Pipedrive on contacts, deals, stage and owner. A stage moved over there is honoured here on the next pass. Webhooks are HMAC-signed and idempotent, so a retry never double-books a deal.
The questions we get a lot.
No. The CRM is built for one job: the cold-outbound workflow, contact to sequence to reply to deal. It is light on purpose. If you already run on Salesforce or HubSpot, two-way sync keeps contacts, deals, stages and owners in step rather than asking you to switch.
Two nullable foreign keys: the campaign and the source mailbox that produced the reply the deal was opened from. Both are ON DELETE SET NULL, so cleaning up an old campaign or mailbox never erases the won-revenue history that traces back to it.
Yes, it is the same workspace-wide list. A bounce, complaint, unsubscribe or STOP reply on a contact suppresses them everywhere at once. No campaign in the workspace queues to a suppressed contact again.
Yes. The board headers and task counts come from a server-side summary computed over the whole filtered set, a true SUM and COUNT, never a reduce over the first page of rows. Search, filter and sort all run on the server, and the list pages with "N of M loaded".
Yes. Each pipeline is its own board with its own stages and colours. A deal lives in one pipeline at a time. Common splits are an SDR pipeline, an AE pipeline, and a partner pipeline.
It is realtime by default. When a reply lands, a deal moves stage, or a task is completed, the board, the counts and the activity feed update live over the socket, with no manual refresh.
Open a pipeline next to your sending.
Connect a mailbox, start a campaign, and watch the first positive reply open a deal on its own.