Domain Intelligence API · v1

API reference

Base URL https://websurely.com · auth header x-api-key · JSON everywhere · OpenAPI 3.1

Try requests with the demo key wsk_demo_0000000000000000000000000000000000000000 (GET endpoints only, 25 lookups/day)

This is the plain summary of the API. The interactive reference (with “try it” requests) needs JavaScript; everything that matters is also here and in openapi.yaml.

Authentication

Send your key in the x-api-key header (apikey works too). Keys look like wsk_live_…, are shown once when issued and stored hashed on our side. A key can be restricted to a list of server IPs.

curl -s https://websurely.com/v1/usage -H "x-api-key: wsk_live_…"

Endpoints

GET /v1/domain/{domain}

The stored report of a domain. Input is normalised like on the website (https://www.Example.com/shop → example.com, IDN → punycode).

  • 200 — the report (1 call): domain, display, score (0–100, BETA), risk_level (low · uncertain · suspicious · high), risk_label, category, verdict, recommendation, about, signals (threat, popularity, domain_age, country, registrar — each {value, label}), details, ssl, network, dns, tech, verified, verified_business, manually_reviewed, confirmed_scam, last_scanned_at, report_url.
  • 404 — never scanned (free). Queue it with POST /v1/scan.
  • 400 — not a valid domain (free).
{
  "domain": "example.org",
  "score": 0,
  "risk_level": "low",
  "risk_label": "Low Risk",
  "verdict": "example.org looks legitimate based on our checks.",
  "signals": {
    "threat":     { "value": "none",  "label": "None detected" },
    "domain_age": { "value": 11382,   "label": "31 years" },
    "registrar":  { "value": "ICANN", "label": "ICANN" }
  },
  "ssl": { "valid": true, "type": "DV", "issuer": "…", "expires": "2026-11-28" },
  "verified": false,
  "manually_reviewed": false,
  "last_scanned_at": "2026-10-29T14:44:41+00:00",
  "report_url": "https://websurely.com/analysis/example.org"
}

POST /v1/scan

Body {"url":"example.com"} (JSON). Scans run asynchronously, usually within a minute.

  • 202 {"scan_status":"initiated"} — a new scan was queued (1 call).
  • 202 {"scan_status":"in_progress"} — a scan is already queued or running (1 call).
  • 200 {"scan_status":"fresh","result":{…}} — the stored report is younger than 30 days, no new scan; the report is included (1 call).
  • 400 missing/invalid url · 403 domain excluded from scanning (free).

Then poll GET /v1/domain/{domain} (the check_url in the answer) until it returns 200 or last_scanned_at changes.

curl -s -X POST https://websurely.com/v1/scan \
  -H "x-api-key: wsk_live_…" -H "Content-Type: application/json" \
  -d '{"url":"example.com"}'

{"url":"example.com","domain":"example.com","scan_status":"initiated","check_url":"https://websurely.com/v1/domain/example.com"}

GET /v1/usage

Plan, calls used and calls left. Always free.

{"plan":{"id":2,"name":"Growth"},"demo":false,"period":"lifetime","calls_total":10000,"calls_used":1234,"calls_left":8766,"rate_limit_per_minute":60,"key_prefix":"wsk_live_3f9…a1c2"}

Limits & billing

  • Rate limit: 60 requests per minute per key (token bucket). Headers on every authenticated response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (seconds until full). Over the limit: 429, type: rate_limited, Retry-After.
  • Quota: only successful (2xx) answers of /v1/domain and /v1/scan use a call; 4xx and 500 are free. X-Quota-Limit / X-Quota-Remaining show the balance. Used up: 429, type: quota_exhausted.
  • Call packs (never expire): Starter 2,000 calls / 10 € · Growth 10,000 calls / 25 € · Scale 30,000 calls / 50 €.
  • Demo key wsk_demo_0000000000000000000000000000000000000000: GET /v1/domain and GET /v1/usage only, 25 lookups per IP per day, never billed.

Errors

Every error uses the same body. type is stable and machine-readable; message is for humans.

StatustypeWhen
400bad_requestInvalid domain / missing url
401unauthorized · key_revoked · key_suspendedMissing, unknown, revoked or suspended key
403ip_not_allowed · demo_key_restricted · forbiddenIP not in the key's allowlist · demo key on a POST endpoint · domain excluded from scanning
404not_foundNo report yet (free) · unknown endpoint
405method_not_allowedWrong HTTP method (see Allow)
429rate_limited · quota_exhausted · demo_limit_reachedToo many requests per minute · calls used up · demo daily limit
500server_errorOur fault — never charged, retry later
{"error":{"code":429,"type":"rate_limited","message":"Rate limit exceeded: 60 requests per minute. Retry in 2 s."}}

Scam scores are automated estimates and opinions based on public data, not statements of fact. Verification in the Verified Business program never changes the score.