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)
Loading the interactive reference…
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/domainand/v1/scanuse a call; 4xx and 500 are free.X-Quota-Limit/X-Quota-Remainingshow 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/domainandGET /v1/usageonly, 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.
| Status | type | When |
|---|---|---|
| 400 | bad_request | Invalid domain / missing url |
| 401 | unauthorized · key_revoked · key_suspended | Missing, unknown, revoked or suspended key |
| 403 | ip_not_allowed · demo_key_restricted · forbidden | IP not in the key's allowlist · demo key on a POST endpoint · domain excluded from scanning |
| 404 | not_found | No report yet (free) · unknown endpoint |
| 405 | method_not_allowed | Wrong HTTP method (see Allow) |
| 429 | rate_limited · quota_exhausted · demo_limit_reached | Too many requests per minute · calls used up · demo daily limit |
| 500 | server_error | Our 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.