MisarMisar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisarSEOMisar PlatformMisar SSO
API Reference

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/score or 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

OperatorMatches when the field…
containscontains value
not_containsdoes not contain value
equalsequals value exactly
not_equalsdiffers from value
starts_withstarts with value
ends_withends with value
is_emptyis blank / not present
is_not_emptyhas 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

GET/api/lead-finder/scoring-rules

Returns the caller's custom scoring rules, newest first (up to 100). Scoped to the active workspace. Requires the leads:read scope.

Response fields

rules[].idstring

Rule UUID.

rules[].namestring

Human-readable rule name.

rules[].enabledboolean

Only 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

POST/api/lead-finder/scoring-rules

Creates a custom scoring rule. Returns HTTP 201. Requires the leads:write scope.

Request body

namestringbodyrequired

Rule name (1–120 characters, trimmed).

enabledbooleanbodydefault: true

Whether 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

PATCH/api/lead-finder/scoring-rules/:id

Updates 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

idstringpathrequired

UUID of the rule to update.

Request body (at least one)

namestringbody

New rule name (1–120 characters).

enabledbooleanbody

Enable or disable the rule.

criteriaCriterion[]body

Replaces 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

DELETE/api/lead-finder/scoring-rules/:id

Permanently removes a scoring rule. Requires the leads:write scope.

Path parameters

idstringpathrequired

UUID 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 (bad field/operator, weight out of range, empty name, or no fields to update on PATCH).