# ToolMint Distress Signal Score

> Send the property distress signals you already hold; get a transparent 0-100 score, tier, confidence and reasons. Pure compute: ToolMint brings no data, stores nothing, contacts no one.

- Status: Coming soon
- Price: $0.01 / call (x402 exact, USDC on Base eip155:8453, payTo 0xfbF7413bcB3a604936775C96FDbe0b0C9c9E37F5)
- Planned URL: https://toolmint-distress-signal-score.toolmint.workers.dev
- OpenAPI: https://toolmint.toolmint.workers.dev/tools/distress-signal-score-json/openapi.json

## Routes

- `GET /score` $0.01: Score one property's distress signals → 0-100 + reasons

## What question it answers

"Given these property signals I already hold, how many distress indicators does this property show, and which ones?" You send up to 13 signals; you get a 0 to 100 score, a tier (`minimal`, `low`, `medium`, `high`), a confidence level, and a list of the reasons with their points.

This is arithmetic on what you send. ToolMint supplies no property data, looks nothing up, stores nothing, and contacts no one.

## When to use it

- Ranking a list of properties you already have data on, for research or prioritizing your own review.
- You want a score you can explain: the full point table is free at `GET /model`.

## When not to

- Not an appraisal, credit decision, or advice. The score is research and prioritization only.
- Not predictive. The weights are a judgment call and have not been fitted to outcomes. Do not claim the score predicts sale, default or seller motivation.
- Not for choosing people. The tool refuses protected-class fields, area-demographic or ZIP/tract proxies, and contact or identity fields. Do not use scores to steer or exclude anyone by a protected class.
- It does not find owners, give contact details, or reach out. Any calls or texts you make afterward are your responsibility under TCPA and the Do Not Call Registry.

## Example

```bash
curl -i "https://toolmint-distress-signal-score.toolmint.workers.dev/score?ref=lead-42&taxDelinquentYears=2&codeViolationsOpen=1&vacant=true&ownerOutOfState=true&equityPct=60"
```
Unpaid, this returns HTTP 402. Trimmed 200 response (the score of 44 is what the code computes for these inputs):
```json
{
  "tool": "distress-signal-score-json",
  "version": "0.1.0",
  "model": "dss-2026-10-31.1",
  "ref": "lead-42",
  "score": 44,
  "rawPoints": 44,
  "tier": "medium",
  "confidence": "medium",
  "signalsSent": 5,
  "missingSignals": ["taxSaleScheduled", "preForeclosureNotice", "lisPendens", "probateOpen",
                     "codeViolations24mo", "absenteeOwner", "yearsOwned", "floodZoneSFHA"],
  "reasons": [
    { "signal": "taxDelinquentYears", "value": 2, "points": 12, "why": "2 year(s) of delinquent tax" },
    { "signal": "vacant", "value": true, "points": 12, "why": "vacant" },
    { "signal": "ownerOutOfState", "value": true, "points": 8, "why": "owner out of state" },
    { "signal": "equityPct", "value": 60, "points": 8, "why": "about 60% equity" },
    { "signal": "codeViolationsOpen", "value": 1, "points": 4, "why": "1 open code case(s)" }
  ],
  "equityNote": null,
  "scoredAt": "2026-10-31T...Z",
  "compliance": { "use": "Research and prioritization only. ...", "fairHousing": "...", "noOutreach": "...", "tcpaDnc": "...", "dataResponsibility": "..." },
  "payment": { "x402": true, "scheme": "exact", "price": "$0.01", "asset": "USDC", "network": "eip155:8453" }
}
```

Accepted signals: `taxDelinquentYears` (0 to 30), `taxSaleScheduled`, `preForeclosureNotice`, `lisPendens`, `probateOpen`, `vacant`, `absenteeOwner`, `ownerOutOfState`, `floodZoneSFHA` (true/false), `codeViolationsOpen` (0 to 500), `codeViolations24mo` (0 to 1000), `yearsOwned` (0 to 150), `equityPct` (-100 to 100). At least 2 are needed. `ref` is optional: your own opaque id (up to 64 characters of letters, digits and `. _ : -`), echoed back. Do not put names or addresses in it.

Confidence reflects how many signals you sent (8 or more high, 4 to 7 medium, 2 to 3 low). It says nothing about whether the signals are correct.

## Data source and licence

None. There is no upstream data. The score comes from the weights published at `GET /model`. You are responsible for having the signals you send lawfully.

## Freshness and limits

- Computed on every call; nothing is cached or stored.
- Signals are sent in the URL query string, so keep personal data out of them. The tool accepts no names, addresses, contact fields, ZIP codes or demographic fields.
- Refusal is by field name, using substring patterns, so an unusual key that happens to contain a protected-class or contact word is also refused.
