Seven-stage pipeline
Per-stage rot days and required fields, stage moves recorded as append-only history, per-stage counts and open value. Single and bulk moves share one gate.
Works todayAvailable now
In build
The whole team
Nineteen specialists, each with a defined job and an honest status label.
See all nineteenEvery free CRM tier that converts in this category gates something — a seat, a lead cap, a send limit — because sending is where consent and abuse risk live. Every call or email Jeet can place stays gated on your own consent record and your own connected provider, never on Jeet's pricing tier, so there is no seat cap or send cap to work around. What it does instead is enforce a required-field gate on every single stage move, including bulk moves and the API, which the two market leaders in this category document their own products as unable to promise.
Why this exists
Every sales pipeline tool in this category eventually has to answer a question it would rather not: who is allowed to send, to how many people, and what stops a rep from working around the limit. The answer is usually a seat cap, a monthly send cap, or a lead cap dressed up as a pricing tier — because the moment a product can dial a number or send an email, it has taken on consent risk, delivery risk and the cost of the infrastructure that manages both. Jeet's specification draws a different line: outreach reads consent from Wavy's own record rather than keeping a second, weaker copy of it, and a call or an email stays blocked until a workspace connects its own telephony or email provider — never on Jeet's say-so, and never metered by a pricing tier. A task, meanwhile, cannot become a message at all: there is no route anywhere in this module that lets a task address a customer directly.
That is not a corner cut to ship faster. It is what lets Jeet be generous everywhere else: no seat cap worth enforcing, because nothing here can be misused to spam without a workspace first connecting its own provider; no lead cap tied to a paid tier, because storing a lead costs nothing risky. What Jeet spends its effort on instead is the part every pipeline tool claims and few actually enforce — a required field that cannot be walked around by a bulk edit, an import, or a direct API call. Losing a deal without saying why is refused. Moving two hundred leads at once still runs every one of them through the identical gate a single move uses. Eleven of the seventeen capabilities built today need no dialer, email provider or calendar at all; the other six are built the same way, just waiting on a workspace's own connection before they can act.

What it refuses to do
The task boundary is the headline. These are the smaller refusals that hold the pipeline itself honest.
The one channel that can never reach a customer, structurally, is a task: JeetTask carries a title, a due date and an assignee inside your own workspace — no phone, no channel, no template — so there is no schema change that turns it into a message someone outside your team receives. Calling and emailing a lead do have real, working routes of their own, but both are gated on your own consent record and a provider connection this deployment hasn't made: a call reports dialed:false and an email records blocked_no_provider rather than pretending to send. WhatsApp is never sent by Jeet at all — a sequence step just creates a task naming what to say, and a rep sends it themselves through Wavy's inbox. Every gated send reads consent from Wavy's own record rather than keeping a second copy, and stays blocked until a workspace connects its own provider — never on Jeet's say-so alone.
Moving a lead to lost without a lost_reason is refused with a 400, and that check runs ahead of any per-stage rule a workspace configures. 'Why did we lose it' is the one question that cannot be reconstructed later, and no stage-rule edit can turn the check off.
Single moves and bulk moves of up to 200 leads both call the identical function to change a lead's stage, so a workspace's required-field rule is checked once, for every path — more than the two market leaders manage, both of whom document their own required-field gates as unenforced on import, bulk edit and the API.
Every scoring input is something the customer did — a reply, a stage a human moved them to, days of silence. There is no field for messages your business sent, on purpose: a score that rose with outbound volume would reward exactly the behaviour that gets a WhatsApp number banned.
A lead that fails its stage's requirements is reported and left where it was; the rest still move. Nothing commits until every lead in the request has been considered, and the response separates what moved from what was refused and why.
The one channel that can never reach a customer, structurally, is a task: JeetTask carries a title, a due date and an assignee inside your own workspace — no phone, no channel, no template — so there is no schema change that turns it into a message someone outside your team receives. Calling and emailing a lead do have real, working routes of their own, but both are gated on your own consent record and a provider connection this deployment hasn't made: a call reports dialed:false and an email records blocked_no_provider rather than pretending to send. WhatsApp is never sent by Jeet at all — a sequence step just creates a task naming what to say, and a rep sends it themselves through Wavy's inbox.
How it works
Three steps. The first one is the one worth spending time on — it is what makes every later stage move honest.
For any of the seven stages, decide which fields must be filled in before a lead may enter it — title, value, owner, phone, source — and how many days of no activity make it rot. Both are optional per stage; leave rot_days unset and that stage simply never rots.
Open a lead from a contact you already have, straight from the conversation someone is looking at in Wavy's inbox, or from a webhook a lead source posts to with its own per-source token. Then have Wavy's inbound message path call the activity route for each message, which is what gives the score something real to read.
The pipeline groups open leads by stage, best score first within each column. Check what has gone stale separately — a rotting lead is not the same list as a low-scoring one, and a lead can be both, either, or neither.
Seven stages, one gate
new, contacted, qualified, proposal, negotiation, won, lost — fixed, so a stored automation or report can never reference a stage that later changes meaning. Every move, whether it is one lead or two hundred at once, runs through the same function that assigns a lead's stage. There is no bulk-edit shortcut and no API path that skips the check, which is the specific thing the two market leaders in this category admit their own products cannot promise.
Who to call first
0 to 100, built from what the customer did: replies (12 points each, capped at 48), the stage a human moved them to (0-40), whether a value is set (+10), and a staleness penalty for silence (down to -32). Not a model — there is not enough won or lost history yet to train one responsibly, and arithmetic is the one kind of score a salesperson who disagrees with it can actually argue with. A workspace can add its own rules in three fixed weight buckets, and a preview endpoint runs a candidate rule set against a real lead before it is saved.
Follow-up
A task carries a title, a due date, and an assignee inside your workspace — and nothing else. There is no phone column, no channel column, no template column, which a reviewer can confirm by reading the model rather than trusting a promise: there is no schema change, present or future, that turns a task into a message a customer receives. Completing one logs it to the lead's history and resets the rot clock, and delivery is Jeet's own in-app bell notification — no phone number or messaging provider needed. An overdue task escalates to the assignee's team manager automatically, looked up from real team membership rather than guessed.
What it does
Each card carries its own limit, and the label is derived from the backend's capability module rather than written here.
Per-stage rot days and required fields, stage moves recorded as append-only history, per-stage counts and open value. Single and bulk moves share one gate.
Works todayScored 0-100 from what the customer did, plus rules a workspace writes itself in three fixed weight buckets and a preview that runs a candidate set against a real lead.
Works todayLoss reasons grouped and counted, win rate by source, owner and stage of exit. Complete because a lost transition is refused without a reason.
Works todayA lead opens from a contact, from the conversation someone's looking at in Wavy's inbox, or from a webhook a lead source posts to with its own token — none of that needs any credential of ours. Reading a business's own email inbox for enquiries is built the same dedupe-safe way, but needs a mailbox credential this deployment hasn't configured.
Needs a connectionEnforced by a partial unique index in the schema, not application logic a bug could route around: a second open lead for the same contact is refused with a 409 naming the existing one.
Works todayA rule triggers when a task completes, a lead replies, or a lead's stage age, score or quiet-days crosses a threshold you set. Rules run in creation order, at most one moves a lead per pass, and none can ever target 'lost' — that transition always needs a person's own reason.
Works todayAssigned to a person in this workspace, listed by today, overdue and open, logged to the lead's history on completion. Delivered as an in-app bell notification — no field can address a customer, and no provider to connect.
Works todayA call or WhatsApp step, when due, creates a task naming exactly what to say — a rep sends it themselves. An email step can send directly through the shared email integration, gated on the contact's own marketing consent. A reply pauses and cancels every scheduled step for that lead the instant it's recorded, not on a later sweep.
Works todayWeighted, best-case and committed value computed live from open leads against per-stage probabilities you can override. A mixed-currency pipeline reports null with a per-currency breakdown rather than a blended number, and confidence is labelled low or medium below 5 or 20 closed deals rather than shown with false certainty.
Works todayVerified activity — stage moves, logged calls — is reported separately from self-reported activity like a task marked done, because a rep can mark a task complete without having made the call. A rep sees only their own numbers; a manager sees their team's.
Works todayRound-robin, fixed-rep or least-open-leads, all checked against each rep's own capacity. A rep at capacity is skipped; if every matching rep is full, the lead is left unassigned with a stated reason rather than dumped on whoever's first.
Works todayEvery imported row goes through the same lead-creation gate a manual or webhook lead uses, so a thousand-row CSV can't mass-create duplicate contacts — a row whose contact already has an open lead is counted skipped, not an error. Exports are served through an unguessable, 24-hour link, never a bare file.
Works todayThe call log, a per-call webhook token, and consent-gated recording linkage all work locally, and a click always writes an attempt row even with no provider connected — it's never silently lost. Actually placing the call needs Exotel, Knowlarity or Ozonetel; until one is connected, a click reports dialed:false and names what to configure.
Needs a connectionConsent-gated recording linkage, transcript storage and a real LLM-generated summary all work today — a workspace with its own manual process can paste a transcript in directly. Producing the transcript from an actual recording needs a speech-to-text service this deployment hasn't connected.
Needs a connectionTemplates, the consent gate shared with Wavy, and a self-hosted open/click tracking pixel all work locally with no network call — tracking works regardless of what eventually sends the message. Actual delivery goes through the shared email integration and needs it configured; until then, a send is recorded blocked_no_provider rather than pretended.
Needs a connectionBooking links, per-rule timezone-aware availability, and conflict prevention against every meeting Jeet itself knows about all work locally, including the public booking page a prospect uses. What it can't do yet is see a rep's real Google or Outlook calendar, so a meeting booked anywhere else stays invisible here until one is connected.
Needs a connectionLine-item totals are recomputed server-side from the live catalogue on every write — a client-sent price is always ignored. Editing a sent quote never mutates it: the old version is superseded and a new share link is issued. What's missing is a PDF: this deployment has no PDF-rendering service, so the share link (a real, sendable page) is what a quote is today, not a stand-in for a file.
Needs a connectionStill needed
Each is built end to end in code — a dialer, an email provider, a calendar, a mailbox credential or a PDF renderer is the one piece this deployment hasn't supplied. Named plainly, not hidden.
The call log, consent gate and recording linkage all work without one. Actually placing a call needs Exotel, Knowlarity or Ozonetel connected; producing a transcript from a real recording (rather than one pasted in by hand) needs a speech-to-text service on top of that. Neither is configured on this deployment.
Templates and open/click tracking work with no network call at all. Actually sending — a direct email, or the email step inside a sequence — goes through the shared ZeptoMail integration, which this deployment hasn't configured; until it is, a send is recorded blocked_no_provider rather than pretended. Multi-channel sequences themselves are fully available — an unconfigured email step simply degrades to a task instead of blocking, so the follow-up still happens on schedule as a human action.
Booking links, availability rules and conflict prevention against meetings Jeet already knows about all work today. A rep's real Google or Outlook calendar isn't wired in, so a meeting booked anywhere else stays invisible here until it is.
Opening a lead from a contact, from a Wavy conversation, or from a webhook a lead source posts to all work with nothing of ours to configure. Reading a business's own email inbox for enquiries is built the same dedupe-safe way, but needs a mailbox credential (host/port/username/password) this deployment hasn't supplied.
Quotes, live-recomputed totals and an unguessable share link all work today — a quote is a real, sendable page. What's missing is a downloadable PDF: this deployment has no PDF-rendering library or service connected.
Before you switch
Tell us how your leads arrive today and we will show you exactly where the stage gate and the score sit in your own pipeline.
Questions
The one channel that can never reach a customer, structurally, is a task: JeetTask carries a title, a due date and an assignee inside your own workspace — no phone, no channel, no template — so there is no schema change that turns it into a message someone outside your team receives. Calling and emailing a lead do have real, working routes of their own, but both are gated on your own consent record and a provider connection this deployment hasn't made: a call reports dialed:false and an email records blocked_no_provider rather than pretending to send. WhatsApp is never sent by Jeet at all — a sequence step just creates a task naming what to say, and a rep sends it themselves through Wavy's inbox. A task's reminder arrives as an in-app bell notification — Jeet's own infrastructure, needing no phone number or provider.
Not for eleven of its seventeen capabilities — the pipeline, scoring, tasks, duplicate detection, win/loss reporting, the stage-rule gate, sequences (a call or WhatsApp step becomes a task; only the email step needs a provider), forecasting, rep performance, lead routing and CSV import/export all work against Jeet's own database with nothing configured. Six more are built but wait on a specific connection — a telephony provider, an email provider, a calendar, a mailbox credential, or a PDF renderer — named plainly, not hidden.
The move is refused with a 400 naming exactly which fields are missing, whether you moved one lead or two hundred at once. There is no bulk-edit or API shortcut that skips the check — the single route and the bulk route call the identical function that assigns a lead's stage.
No. Moving a lead to lost without a lost_reason is refused regardless of what your stage rules require, because win/loss reporting is the one question that cannot be reconstructed after the fact. A deal-stage automation rule can never target 'lost' either, for the same reason.
Arithmetic, not a model: replies (up to 48 points), the stage a human moved the lead to (up to 40), whether it has a value set (+10), and a staleness penalty for silence (down to -32), each with a plain-English reason. A workspace can add its own rules, and a preview endpoint shows exactly what a candidate rule set would do to a real lead before saving it.
Because the task table has no column that could address a customer — no phone, no channel, no template — and that is deliberate. Calling and emailing a lead do have their own gated routes elsewhere in Jeet, each reading consent from Wavy's own record rather than a second copy; a task specifically stays incapable of it.