API v1

Verifica la sicurezza di un URL dalle tue applicazioni con una sola chiamata HTTP. Stesso motore del sito: fino a 8 fonti di intelligence aggregate in un punteggio 0–100.

A cosa serve

Casi d'uso tipici: un server di posta che controlla i link delle email in arrivo, un bot che verifica gli URL condivisi in chat, un'estensione browser, un sistema di ticketing che analizza gli allegati testuali.

Autenticazione

Ogni richiesta richiede una API key, passata in un header:

X-API-Key: sok_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

In alternativa è accettato Authorization: Bearer <key>.

La chiave si vede una volta sola. Al momento della creazione viene mostrata in chiaro e poi conservata solo come hash SHA-256: non è recuperabile. Se la perdi, va revocata e ricreata. Trattala come una password: mai nel codice client, mai in un repository pubblico.

Per ottenere una chiave scrivi a info@cybetower.swiss.

Endpoint

POST /api/v1/scan

Analizza un URL e restituisce il verdetto.

CampoTipoDescrizione
urlstringObbligatorio. URL da verificare.
forceRefreshbooleanOpzionale, default false. Ignora la cache e forza una scansione nuova (più lenta).
curl -X POST https://www.sito-ok.com/api/v1/scan \
     -H "X-API-Key: $SOK_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"url":"https://esempio-sospetto.test/login"}'

Risposta:

{
  "url": "https://esempio-sospetto.test/login",
  "score": 20,
  "classification": "dangerous",
  "safe": false,
  "message": "Sito pericoloso",
  "sources": ["URLScan.io", "Google Safe Browsing"],
  "cached": false,
  "scanId": "b8872e19-6d5f-4d83-a5d4-560437127cbc",
  "checkedAt": "2026-07-31T12:20:43.351Z",
  "redirects": { "count": 1, "finalUrl": "https://esempio-sospetto.test/step2.php" },
  "signals": [
    { "type": "provider_default_hostname", "severity": "critical",
      "description": "Hostname di default del provider (Contabo)" }
  ],
  "quota": { "remaining": 97, "limit": 100 }
}

Punteggio e classificazione

Il punteggio va letto così: 100 = massima sicurezza, 0 = massimo rischio. È l'opposto di molti sistemi di "risk score": qui un numero alto è una buona notizia.

PunteggioclassificationSignificato
80–100safeNessun segnale rilevante
50–79cautionQualche anomalia: procedere con attenzione
25–49suspiciousSegnali concreti di rischio
0–24dangerousPericoloso: sconsigliato l'accesso

Il campo booleano safe è vero quando il punteggio è ≥ 50. Per un filtro antiphishing aggressivo conviene però bloccare sotto 25 e segnalare tra 25 e 49.

GET /api/v1/quota

Consumo corrente della chiave. Non consuma quota.

curl https://www.sito-ok.com/api/v1/quota -H "X-API-Key: $SOK_API_KEY"

{ "plan": "free", "limit": 100, "used": 12, "remaining": 88,
  "resetsAt": "2026-08-01T00:00:00.000Z",
  "key": { "name": "Mail server", "prefix": "sok_live_1d760093" } }

GET /api/v1/status

Stato del servizio. Non richiede autenticazione.

Limiti e quote

LimiteValoreCosa succede
Quota giornalierasecondo il piano (free: 100/giorno)429 con codice QUOTA_EXCEEDED, azzeramento a mezzanotte UTC
Frequenza60 richieste/minuto per chiave429 con codice RATE_LIMIT_PER_MINUTE

Ogni risposta include gli header X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset (epoch UTC del reset).

La cache lavora a tuo favore. Un URL già analizzato nelle ultime 24 ore risponde in millisecondi con "cached": true. La quota viene comunque scalata, ma non consumi tempo né le nostre quote verso le fonti esterne. Le richieste con body non valido non vengono addebitate.

Codici di errore

HTTPcodeCausa
400URL_REQUIREDCampo url assente
400URL_INVALIDURL non riconosciuto come valido
401API_KEY_MISSINGHeader di autenticazione assente
401API_KEY_INVALIDChiave inesistente
403API_KEY_REVOKEDChiave revocata
429QUOTA_EXCEEDEDQuota giornaliera esaurita
429RATE_LIMIT_PER_MINUTETroppe richieste al minuto
503SCAN_UNAVAILABLEFonti esterne temporaneamente non raggiungibili

Esempio: filtrare i link delle email

Estratto da un filtro di posta che analizza i link in arrivo e decide cosa farne:

const res = await fetch('https://www.sito-ok.com/api/v1/scan', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.SOK_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: linkTrovatoNellaMail })
});

if (res.status === 429) return 'accetta';   // quota finita: non bloccare la posta
const v = await res.json();

if (v.score < 25) return 'quarantena';                   // pericoloso
if (v.score < 50) return 'accetta-con-avviso';           // sospetto
return 'accetta';
Progetta per il fallimento. Se l'API non risponde o la quota è esaurita, il filtro deve lasciar passare la posta (fail-open), non bloccarla. Un servizio di sicurezza che ferma le email legittime quando ha un disservizio fa più danni di quanti ne eviti.

Privacy

Gli URL analizzati vengono conservati insieme al verdetto per alimentare la cache condivisa. Gli indirizzi IP dei chiamanti sono salvati solo come hash SHA-256. Non inviare URL che contengano token di sessione, password o dati personali nella query string: finirebbero nel nostro archivio delle scansioni.