Compliance API
One request in, a verdict out. The same deterministic engine behind the Canva app and the public checker — 9 industry rulebooks, no model call, citations you can put in front of a regulator.
Endpoint
POST https://hub.danedigital.org/api/v1/check
Authorization: Bearer YOUR_KEY (or: X-API-Key: YOUR_KEY)
Content-Type: application/json
{ "text": "Guaranteed approval for every borrower.", "vertical": "mortgage" }The answer
{
"verdict": {
"findings": [
{ "claim": "Prohibited for this vertical: \"guaranteed approval\"",
"risk": "Needs Counsel",
"fix": { "kind": "delete", "why": "No lender can promise approval before underwriting." } }
],
"blocking": true,
"summary": { "tone": "block", "label": "Not publishable as written" }
},
"vertical": "mortgage",
"regime": "mortgage"
}The findings are nested under verdict. Reading body.findings returns undefined on every successful response. Our own Canva app shipped unable to display a single finding because of this.
An empty findings list is not automatically a pass. There are three answers — problems found, none found, and could not check — and only the first two carry a verdict. A non-2xx response, or a 200 carrying an error key, means nothing was scanned. Treat it as unknown, never as clean. A caller that renders “all clear” for a check that never ran has done the one thing this product exists to prevent.
Verticals
Send the id. An unrecognised value is refused outright rather than falling back to a weaker rulebook — a silent fallback would answer “clear” against rules that never applied.
| id | Rulebook |
|---|---|
mortgage | Mortgage |
real-estate | Real estate |
property | Property management |
investing | Investing |
wellness | Med spa / wellness |
clinical | Dental / medical practice |
tcpa | Texts / cold calls |
law | Law — common bar principles |
immigration | Immigration |
contracting | Contracting |
Errors
| Status | code | Means |
|---|---|---|
| 503 | api_disabled | The API is not switched on for this host. |
| 401 | unauthorized | Missing or unrecognised key. |
| 429 | rate_limited | Over 2,000 checks for this key today. |
| 400 | — | No text, text over the size cap, or an unknown vertical. |
The cap is 2,000 checks per key per day. It exists to stop a retry storm or a runaway automation, not to meter you — tell us if you need more and you will get more.
Your usage
GET https://hub.danedigital.org/api/v1/usage
Authorization: Bearer YOUR_KEY
{ "month": "2026-10", "scope": "this-key", "key": "210518d56658",
"calls": 412, "blocking": 37, "dailyLimit": 2000 }Your own calls for the current month, or any month with ?month=2026-09. You see the key you authenticated with and nothing else — there is no parameter for whose usage to read.
Two things worth knowing. It counts against the same daily allowance as a check, because it does more work than one — poll it hourly, not per request. And it never answers zero when it cannot tell: if usage is not being recorded it returns 503 usage_unavailable rather than calls: 0, so a number you reconcile against is always a real one.
Getting a key
Keys are issued by hand today. Email danedigitalmarketing@gmail.com and say what you are building.
Screening by Dane Digital. A screening tool, not legal advice — a compliance officer has the last word.