Decide

One call at the signup form decides who gets in

Verify the address, enrich the person only if a rule needs to, score the fit, and apply the rule you wrote in plain English. You get one decision back, with the rule that made it and the reasons in words.

Where your signup rules live today

In a Zapier filter, an if in the signup handler, a spreadsheet of blocked domains and a thread in Slack. None of it is versioned, none of it is measured, and nobody can say what happened to paid conversion when you started blocking Gmail. Decide puts the rules in one place, as data, with a history and a receipt on every request.

You write it in English

Don't allow temp emails or role accounts. Only business emails, and review anyone outside fintech or insurance. Anyone on the partners list is always allowed. Let AI agents in through the API-key flow.

The compiler turns that into typed rules, once, when you click compile — and shows them back to you before anything is saved.

It compiles to rules you can read

First match wins, top to bottom. Anything that matches no rule is allowed.

RuleWhenThenWhy it is here
r_partnersemail.domain is on list partnersallowChecked first, so it overrides everything below.
r_no_disposableverification.email_type is disposabledenyTemp-mail domains.
r_no_roleverification.email_type is roledenyinfo@, sales@ and the like.
r_agentsverification.actor_class is agent_mailboxallow_with_flow: agentAgents go to your API-key flow instead of the signup form.
r_business_onlyverification.email_type is not businessdenyGmail, Outlook.com, Yahoo, Apple and other free (social) mailboxes, relay aliases, and addresses Sortance cannot place.
r_industry_fitenrichment.company.industry not in fintech, insurancereviewReview, not deny: enrichment is missing on some corporate domains, and missing data should not become a lost signup.

Every field, operator and value comes from a closed vocabulary. The compiler cannot invent company.vibe, and anything it produces goes through the same validator as a rule you write by hand. When your English is ambiguous — does “business emails only” mean deny consumer mailboxes, or review them? — it asks instead of guessing.

For the common case there is a switch instead of a sentence: the Email types card on the Policy screen sets free (social) email, role accounts, relay aliases and disposable addresses to Allow, Review or Block, as rules in the same policy. See email types.

Replay it before it touches a signup

Before you activate a version, Sortance runs it over your own recent decisions and shows what would have changed: the decision mix, how many each rule caught, which decisions flipped, a sample of them with the address masked, and what the change does to enrichment spend per 1,000 decisions.

// Illustrative. The shape of a replay response, not anyone's traffic.
{
  "evaluated": 500,
  "decisions": { "allow": 318, "allow_with_flow": 4, "review": 121, "challenge": 0, "deny": 57 },
  "by_rule": [ { "rule_id": "r_no_disposable", "matched": 23 }, { "rule_id": "r_industry_fit", "matched": 121 } ],
  "changed_vs_active": { "allow_to_deny": 41, "allow_to_review": 97 },
  "estimated_cost_delta_usd_per_1k": 31.4,
  "warnings": ["38 of 500 traces had no enrichment stored; those were evaluated with enrichment: null."]
}

Then you choose: enforce now, or shadow first — evaluate the new version on every request and record what it would have done, while the current version keeps answering. See experiments.

What comes back

curl -X POST https://api.sortance.com/v1/decide \
  -H "Authorization: Bearer $SORTANCE_KEY" \
  -d '{"email":"mia@acme.com","context":{"purpose":"signup"}}'

{
  "decision": "review",
  "rule_id": "r_industry_fit",
  "policy": { "slug": "default", "version": 14 },
  "reasons": ["company.industry is 'logistics', not one of 'fintech', 'insurance'"],
  "verification": { /* the full /v1/verify response */ },
  "enrichment": { /* the profile, because r_industry_fit needed it */ },
  ...
}

The full field list is in the decide reference.

You only pay for enrichment a rule actually needs

Rules are walked in order and a profile is bought only when evaluation reaches a rule that reads one. A disposable address denied by rule two never makes rule six pay to look up its company. A policy that reads only verification signals costs exactly what a bare verification costs.

Three things Decide will not do

  • Put a model on the request path. A model helps write the policy, once. Every decision is a pure function of typed inputs — replayable, explainable, and fast.
  • Deny anyone on its own authority. Sortance classifies; your policy decides. A deny only ever comes from a rule you confirmed, and the response names it. The compiler leans to review where data may be missing, recommendations propose review, and the default is allow.
  • Fail closed. An enrichment outage, a slow vendor or a missing policy still returns 200 with a decision, and a degraded: reason says what was missing.

Not a lead scorer, not a CRM, not a bouncer

No model emits a score: the ICP score is a rubric you wrote, computed by arithmetic, with its coverage next to it. Nothing is written to your CRM and nothing is sent to anyone. There is no visitor tracking of Sortance’s own; a website-visitor signal appears only if you connect a vendor that sends one. And your app still owns sign-in, sessions and the form — Decide answers “should this email proceed”, nothing more.