Cactus
API JSON
Exécutez les mêmes analyses d'URL et de courriels de façon programmatique. Publique, à débit limité, aucune clé d'API requise.
Points de terminaison
GET /api/check-url
Analyze a single URL. Use this for quick lookups, bookmarks, and command-line use.
Query parameters:
u— the URL to analyze (max 2048 chars). Required.lang— response language:en-CA(default) orfr-CA. Optional.
Example:
curl "https://your-safecheck-host/api/check-url?u=https://example.com"
curl "https://your-safecheck-host/api/check-url?u=https://example.com&lang=fr-CA"
POST /api/check-url
Same analysis, but accepts a JSON body. Use this when the URL might contain characters awkward in a query string.
curl -X POST "https://your-safecheck-host/api/check-url?lang=fr-CA" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'
POST /api/check-email
Analyze an email body, with optional raw headers.
JSON body:
emailBody— the email body text (max 20000 chars). Required.rawHeaders— raw email headers (max 20000 chars). Optional.
curl -X POST https://your-safecheck-host/api/check-email \
-H "Content-Type: application/json" \
-d '{
"emailBody": "Dear customer, your account has been suspended...",
"rawHeaders": "From: PayPal \nReply-To: hacker@evil.example"
}'
GET /api/check-tls
Scan a host's TLS/SSL configuration: negotiated protocol and cipher, certificate details and chain, HSTS, revocation, and an overall A+–F grade. Only public hosts on port 443 are scanned.
Query parameters:
host— the domain or host to scan (max 255 chars). Required.
curl "https://your-safecheck-host/api/check-tls?host=example.com"
GET /api/check-email-auth
Check a domain's email authentication posture — SPF, DKIM, and DMARC — with an overall A–F grade. Accepts a domain or an email address.
Query parameters:
domain— the domain or email address to check (max 255 chars). Required.
curl "https://your-safecheck-host/api/check-email-auth?domain=example.com"
The grade field (e.g. "A+", "F") is the headline result. The /api/check-tls and /api/check-email-auth responses return localization keys (gradeNoteKeys, noteKeys, errorKey) rather than localized prose; resolve them client-side if you need display text.
Essayez
Enter any URL to call GET /api/check-url live and see the full JSON response.
Forme de la réponse
La réponse est le même objet d'analyse que celui rendu par l'interface Web. Les énumérations (niveaux de gravité, etc.) sont retournées sous forme de chaînes, non d'entiers. Exemple de forme pour /api/check-url :
{
"input": "https://example.com",
"normalizedUrl": "https://example.com",
"analyzedHost": "example.com",
"confidenceScore": 95,
"verdict": "Likely low risk",
"verdictKey": "verdict.lowRisk",
"summary": "This link does not show obvious warning signs from the available checks.",
"summaryKey": "summary.url.lowRisk",
"isInconclusive": false,
"recommendedAction": "This link does not show obvious warning signs, but stay cautious...",
"findings": [
{
"title": "Uses HTTPS",
"titleKey": "finding.usesHttps.title",
"description": "The link uses HTTPS. This is good, but HTTPS alone does not prove a site is safe.",
"descriptionKey": "finding.usesHttps.description",
"severity": "Info",
"scoreImpact": 0,
"parameters": null,
"sourceHintKey": null
}
],
"redirects": {
"wasAttempted": true,
"wasSuccessful": true,
"wasBlockedByPolicy": false,
"hops": [],
"finalUrl": "https://example.com",
"finalHost": "example.com",
"hitMaxHops": false,
"unresolvable": false,
"containsHttpsToHttpDowngrade": false,
"errorMessage": null,
"skipReason": null
},
"domainAge": {
"wasAttempted": true,
"wasSuccessful": true,
"lookedUpDomain": "example.com",
"registeredAt": "1995-08-14T04:00:00+00:00",
"ageInDays": 10878,
"ageBand": "established",
"humanReadableAge": "Registered about 29 years ago",
"errorMessage": null,
"skipReason": null
}
}
Codes d'état
200— analysis returned. The response body always contains a result; checkverdict,confidenceScore, andisInconclusive.400— missing required field or input exceeded length cap. Response body is{ "error": "..." }.429— rate limit exceeded. Response body is plain text.
Limites de débit
Par IP client, partagées avec le formulaire HTML :
- 10 / minute for
/api/check-url(GET and POST share the same partition). - 5 / minute for
/api/check-email. - 5 / minute each for
/api/check-tlsand/api/check-email-auth(they open outbound connections per request).
Language / localization
The URL and email endpoints support bilingual responses (English and French Canadian). Two ways to request French:
- Query parameter: append
?lang=fr-CA(or just?lang=fr) to the request URL. - Header: send
Accept-Language: fr-CA. The query parameter takes priority if both are present.
When a language is requested, the string fields in the response (verdict, summary, recommendedAction, and each finding's title and description) are returned in that language. The *Key fields (e.g. verdictKey, titleKey) are always returned and can be used to look up or re-render translations on the client side.
Remarques
- No authentication or API key for now. Plan accordingly if you embed the host URL anywhere public.
- No CORS headers are emitted, so the API is intended for server-to-server use, scripts, or browser-extension manifests — not direct calls from a SPA in a different origin.
- The same caching as the HTML pages applies (results memoized in-process for up to 6 hours), so identical requests cost nothing after the first. Caching is language-neutral — the localization step runs at response time without hitting the cache again.
- See Privacy for what each analysis sends to third parties (Google Web Risk, rdap.org).