API
Use the standard from anything.
cai.canine.dev is the authority for the rubric catalogs and the scoring fold, served over a small JSON API. The catalogs are the open standard, so the read endpoints are public — the Watchdog surveyor and anyone else call these instead of carrying their own copy.
Rate limits
To keep the standard free and available, anonymous requests to /api are
rate-limited per client IP:
- 1 request / second
- 3 requests / minute
- 15 requests / day
The limits chain — a request must satisfy all three. Over the limit returns 429 Too Many Requests
with a Retry-After header. The rubric catalog is immutable per version, so cache the rubric
you use — you should never need to fetch a given version more than once. The client-side
WASM calculator runs entirely in your browser and is not rate-limited.
Two surfaces carry their own, more generous budgets instead: authenticated registry calls
(a valid bearer token is the abuse control — a per-principal allowance far above any real delivery loop) and
the registry's public probes /api/registry/keys and
/api/registry/health (per-IP, sized so offline verification and monitoring never trip it).
The Watchdog surveyor (watchdog.canine.dev) calls these same public endpoints, exempt from the limit as a co-located partner.
Rubric catalog
GET /api/rubrics
The published rubric versions, newest first.
curl https://cai.canine.dev/api/rubrics
{ "latest": "rubric-2026.08.17", "versions": ["rubric-2026.08.17", "rubric-2026.08.16", "rubric-2026.08.15", "rubric-2026.08.14", "rubric-2026.08.12"] }
GET /api/rubrics/{version}/catalog
A version's full catalog — every lens and dimension it defines (latest resolves to the
newest). This is the versioned, archived definition of the standard.
curl https://cai.canine.dev/api/rubrics/latest/catalog
{
"rubricVersion": "rubric-2026.08.17",
"lenses": [ { "key": "codeHealth", "label": "Code Health" }, … ],
"dimensions": [
{ "id": "D1", "name": "Cyclomatic Complexity", "lens": "codeHealth",
"evaluator": "tool", "whatItMeasures": "…", "family": "dimension", "ceilingRung": "Prevented" },
… (127 dimensions)
]
}Scoring
POST /api/score
Fold an evidence bundle (measured dimensions) into the CAI + per-lens roll-up. The body is the bundle JSON.
curl -X POST https://cai.canine.dev/api/score \
-H 'Content-Type: application/json' \
--data @evidence.json
{
"cai": 69.56,
"band": "Adequate",
"rubricVersion": "rubric-2026.08.15",
"lenses": [ { "lens": "maturity", "score": 65.1, "weight": 0.457, "contribution": 29.77 }, … ]
}
POST /api/verify
Reproduce a published headline from its evidence (the bundle carries headlineScore).
curl -X POST https://cai.canine.dev/api/verify -H 'Content-Type: application/json' --data @survey.json
{ "reproduced": true, "computed": 69.56, "claimed": 69.6, "delta": 0.04, "tolerance": 0.5 }
The fold is open and deterministic — see the spec for the algorithm, or the reference implementation to run it offline.