Lead Scoring Rules API
Create custom lead-scoring rules that adjust the default AI/heuristic score by weighted criteria — api.misar.io/reach.
Every lead gets a default score from 0–100 (an AI model with a heuristic fallback) reflecting likelihood to respond to cold outreach. Custom scoring rules let you tune that baseline for your own ideal-customer profile: each rule is a set of { field, operator, value, weight } criteria, and every matched criterion adds its signed weight to the lead's score. The total is re-clamped to 0–100.
Base URL: https://api.misar.io/reach — pass Authorization: Bearer msr_your_key_here on every request.
How rules adjust the score
- The default score (AI, or the heuristic fallback when AI is unavailable) is the baseline.
- On top of it, every enabled rule is evaluated against the lead. For each rule, the weights of its matched criteria are summed into a rule delta.
- A rule only contributes when at least one of its criteria matches and its net delta is non-zero.
- All contributing rule deltas are summed, added to the baseline, and the result is rounded and clamped back into
0–100. - A user with no enabled rules is a pure no-op — the default score is returned unchanged. Rules apply to freshly computed scores (via
POST /api/lead-finder/scoreor during a search with scoring); already-cached scores are left untouched until rescored.
Score bands used across the product: 80–100 high intent (send first), 50–79 medium (second batch), 0–49 low (deprioritise).
Criterion shape
Prop
Type
Operators
| Operator | Matches when the field… |
|---|---|
contains | contains value |
not_contains | does not contain value |
equals | equals value exactly |
not_equals | differs from value |
starts_with | starts with value |
ends_with | ends with value |
is_empty | is blank / not present |
is_not_empty | has any value |
All string comparisons are lower-cased and trimmed on both sides. contains, not_contains, equals, starts_with, and ends_with require a non-empty value; is_empty and is_not_empty ignore value entirely.
List scoring rules
/api/lead-finder/scoring-rulesReturns the caller's custom scoring rules, newest first (up to 100). Scoped to the active workspace. Requires the leads:read scope.
Response fields
rules[].idstringRule UUID.
rules[].namestringHuman-readable rule name.
rules[].enabledbooleanOnly enabled rules affect scoring.
rules[].criteriaCriterion[]Array of { field, operator, value, weight } clauses.
curl "https://api.misar.io/reach/api/lead-finder/scoring-rules" \
-H "Authorization: Bearer msr_your_key_here"{
"rules": [
{
"id": "b1e0…",
"name": "Prioritise SaaS decision-makers",
"enabled": true,
"criteria": [
{ "field": "role", "operator": "contains", "value": "founder", "weight": 20 },
{ "field": "industry", "operator": "contains", "value": "saas", "weight": 15 },
{ "field": "email", "operator": "is_empty", "value": "", "weight": -30 }
],
"workspace_id": "ws_…",
"created_at": "2026-07-10T09:00:00Z",
"updated_at": "2026-07-10T09:00:00Z"
}
]
}Create a scoring rule
/api/lead-finder/scoring-rulesCreates a custom scoring rule. Returns HTTP 201. Requires the leads:write scope.
Request body
namestringbodyrequiredRule name (1–120 characters, trimmed).
enabledbooleanbodydefault: trueWhether the rule is active. Disabled rules are stored but do not affect scoring.
criteriaCriterion[]bodydefault: []Up to 50 { field, operator, value, weight } clauses (see Criterion shape).
curl -X POST "https://api.misar.io/reach/api/lead-finder/scoring-rules" \
-H "Authorization: Bearer msr_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Prioritise SaaS decision-makers",
"enabled": true,
"criteria": [
{ "field": "role", "operator": "contains", "value": "founder", "weight": 20 },
{ "field": "industry", "operator": "contains", "value": "saas", "weight": 15 },
{ "field": "email", "operator": "is_empty", "value": "", "weight": -30 }
]
}'{
"rule": {
"id": "b1e0…",
"name": "Prioritise SaaS decision-makers",
"enabled": true,
"criteria": [ { "field": "role", "operator": "contains", "value": "founder", "weight": 20 } ],
"workspace_id": "ws_…",
"created_at": "2026-07-10T09:00:00Z",
"updated_at": "2026-07-10T09:00:00Z"
}
}{ "error": { "fieldErrors": { "criteria": ["…"] }, "formErrors": [] } }Update a scoring rule
/api/lead-finder/scoring-rules/:idUpdates a rule's name, enabled state, and/or criteria. Send only the fields you want to change — at least one is required. Requires the leads:write scope.
Path parameters
idstringpathrequiredUUID of the rule to update.
Request body (at least one)
namestringbodyNew rule name (1–120 characters).
enabledbooleanbodyEnable or disable the rule.
criteriaCriterion[]bodyReplaces the full criteria array (up to 50 clauses).
curl -X PATCH "https://api.misar.io/reach/api/lead-finder/scoring-rules/b1e0…" \
-H "Authorization: Bearer msr_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'{ "rule": { "id": "b1e0…", "name": "Prioritise SaaS decision-makers", "enabled": false, "criteria": [], "updated_at": "2026-07-12T12:00:00Z" } }{ "error": "Rule not found" }Delete a scoring rule
/api/lead-finder/scoring-rules/:idPermanently removes a scoring rule. Requires the leads:write scope.
Path parameters
idstringpathrequiredUUID of the rule to delete.
curl -X DELETE "https://api.misar.io/reach/api/lead-finder/scoring-rules/b1e0…" \
-H "Authorization: Bearer msr_your_key_here"{ "ok": true }Status codes
200— rule(s) returned, updated, or deleted.201— rule created.404— rule not found (wrong id, or not owned by the caller's workspace).422— validation error (badfield/operator,weightout of range, emptyname, or no fields to update on PATCH).