Documentation

API reference

Three endpoints: check that the service is up, scan one URL, or scan up to 100 at once.

Authentication

Send your API key in the X-API-Key header on every request. Keys are issued from your dashboard and are tied to your plan's monthly call allowance.

header
X-API-Key: 01234<api_key>56789

Base URL: https://smarty-pants.io

GET/healthNo key required

Reports the current health of the API and the version of the algorithm answering your scans. Use it for uptime monitors and to confirm which model version your traffic is hitting.

Call

bash
curl -X GET https://smarty-pants.io/health
  -H "X-API-Key: 01234<api_key>56789"
  -H "Content-Type: application/json"

Response

json
{
  "status": "ok",
  "version": "1.0.0"
}
status"ok" while the API is healthy
versionCurrent algorithm version serving results
POST/scanAPI key required

Scans a single URL. Returns the model's maliciousness probability, the same figure as a percentage, and a yes/no answer against the decision threshold.

Call

bash
curl -X POST https://smarty-pants.io/scan
  -H "X-API-Key: 01234<api_key>56789"
  -H "Content-Type: application/json"
  -d '{"url": "http://evil.co/1"}'

Response

json
{
  "url": "http://evil.co/1",
  "probability": 0.987787,
  "malicious_percent": 98.78,
  "is_malicious": true,
  "threshold": 0.6,
  "source": "model"
}
urlThe URL you submitted
probabilityMaliciousness score from 0 to 1
malicious_percentThe same score expressed as a percentage
is_malicioustrue when probability meets or exceeds threshold
thresholdDecision cut-off used for this scan
sourceWhich system answered: the model or a list rule
POST/batchAPI key required

Scans a batch of up to 100 URLs in one request. Results come back in the order the URLs were sent, so you can match them to your own records by index.

Call

bash
curl -X POST https://smarty-pants.io/batch
  -H "X-API-Key: 01234<api_key>56789"
  -H "Content-Type: application/json"
  -d '{"urls": ["https://apple.com", "http://evil.gq/1"]}'

Response

json
{
  "count": 2,
  "threshold": 0.6,
  "results": [
    {
      "url": "https://apple.com",
      "probability": 0.0,
      "malicious_percent": 0.0,
      "is_malicious": false,
      "threshold": 0.6,
      "source": "whitelist",
      "matched_rule": "apple.com"
    },
    {
      "url": "http://evil.co/1",
      "probability": 0.987787,
      "malicious_percent": 98.78,
      "is_malicious": true,
      "threshold": 0.6,
      "source": "model"
    }
  ]
}
countNumber of URLs scanned in this response
thresholdDecision cut-off applied to every result
resultsOne scan object per URL, in the order submitted
matched_rulePresent when a whitelist or blacklist entry decided the result
POST/sandboxAPI key required · Level 2

Level 2 verification. Each URL is opened in an isolated sandbox and its live behavior is checked before a verdict is returned. Sandbox scans are slower than /scan, as expected, so use them for links you want verified in depth — for example, ones /scan marks as borderline. Billed at $0.05 per sandbox scan on all plans except Docker.

Call

bash
curl -X POST https://smarty-pants.io/sandbox
  -H "X-API-Key: 01234<api_key>56789"
  -H "Content-Type: application/json"
  -d '{"url": "http://evil.co/1"}'

Response

json
{
  "url": "http://evil.co/1",
  "probability": 0.994120,
  "malicious_percent": 99.41,
  "is_malicious": true,
  "threshold": 0.6,
  "source": "sandbox"
}
urlThe URL you submitted
probabilityMaliciousness score from 0 to 1 after sandbox verification
is_malicioustrue when probability meets or exceeds threshold
source"sandbox" — the URL was opened and verified in isolation

Response fields

Every scan result carries the same fields, whether it came from /scan or inside /batch. Treat is_malicious as the actionable flag and probability as the raw confidence behind it.

probability0.0 safe to 1.0 certainly malicious
malicious_percentprobability × 100, rounded to two decimals
is_maliciousprobability >= threshold
thresholdDefault 0.6; the cut-off that produced is_malicious
sourcemodel, whitelist or blacklist
matched_ruleThe domain rule that matched, when one did

Errors

Failed calls return a standard HTTP status with a JSON body describing the problem.

401Missing or invalid X-API-Key
422Malformed or unsupported URL
429Rate limited or monthly allowance reached — retry with backoff
5xxServer side failure — retry with exponential backoff