Public REST API
Programmatic access to the same grader that powers /grade. Free, no auth, IP-rate-limited. Output is stable JSON.
For full page audits, site audits and the schema verifier, see the audit API.
The contract
- Endpoint
- GET /api/v1/grade
- Auth
- None. IP-rate-limited only.
- CORS
- Open. Use from any origin.
- Cache
- 24h per-domain at the CDN edge. Stale-while-revalidate 7d.
- Rate limit
- 2 requests per minute per IP, and 60 a day per IP across the free tools and this API. A 429 carries Retry-After.
- Cost
- Free.
Request and response
Pass a domain. You get back the letter grade, the 0–100 score, each check with its status, and links to the report, the badge and a full audit. A check’s scored is true when it counts toward the score and false when it is informational only.
curl https://vectorcite.digiocular.com/api/v1/grade?domain=stripe.com{
"version": "v1",
"grade": {
"domain": "stripe.com",
"fetchedAt": "2026-06-01T10:42:00.000Z",
"httpStatus": 200,
"score": 92,
"letter": "A",
"checks": [
{
"key": "https",
"label": "HTTPS",
"status": "pass",
"detail": "TLS responds correctly…",
"scored": true
},
…
],
"summary": "stripe.com is well-positioned for AI citation…"
},
"links": {
"report": "https://vectorcite.digiocular.com/grade/stripe.com",
"badge": "https://vectorcite.digiocular.com/badge/stripe.com",
"fullAudit": "https://vectorcite.digiocular.com/audit?url=https://stripe.com"
}
}Code samples
The same call from Node and from Python.
// Node 18+
const res = await fetch("https://vectorcite.digiocular.com/api/v1/grade?domain=stripe.com");
if (!res.ok) throw new Error(`API returned ${res.status}`);
const { grade } = await res.json();
console.log(`${grade.domain}: ${grade.letter} (${grade.score}/100)`);
console.log(`Failing: ${grade.checks.filter(c => c.status === "fail").map(c => c.label).join(", ")}`);import requests
res = requests.get(
"https://vectorcite.digiocular.com/api/v1/grade",
params={"domain": "stripe.com"},
)
res.raise_for_status()
grade = res.json()["grade"]
print(f"{grade['domain']}: {grade['letter']} ({grade['score']}/100)")Errors and versioning
Errors come back as one JSON envelope with a 4xx or 5xx status. The v1 response shape is stable: new optional fields may be added, and existing fields keep their key and type. Breaking changes ship at /api/v2/. One exception: each check’s weight field was removed on 15 October 2026.
{
"error": "rate_limited" | "missing_parameter" | "unreachable",
"message": "Human-readable reason",
"retryAfterMs": 41000 // only on 429: milliseconds until you may retry
}Try it now
One request, a real grade: /api/v1/grade?domain=stripe.com
