Skip to content
Dokeo

Docs

Quickstart

Score a draft, read the verdict, and stop a failing one before it ships.
What is a content quality gate?
dokeo.co/blog/what-is-a-content-quality-gate
WARNING
76overall
77SEO
86AEO
66GEO
Fix before it ships12 of 19 checks pass
internal_linkingNo contextual links found (internal or external)
Fix
slopquestion-then-answer pattern found 2 time(s)
Fix

We gate our own blog. Scored 17 October 2026 with the same engine you get, glossary rules, balanced strictness.

Five minutes, one key, no SDK. Everything below also works from the CLI, the MCP server and the REST API. To try it with no account, paste a draft into the homepage scanner.

1Create an API key

Sign up, then create a key at /account/api-keys. Keys start with dk_. Keep it in an environment variable called DOKEO_API_KEY; do not commit it.

2Score a draft

Send the text to POST /api/v1/scan. content_type is optional and is detected when omitted. To score a published page instead, use POST /api/v1/scan/url with {"url": "https://..."}.

bash
curl https://api.dokeo.co/api/v1/scan \
  -H "Authorization: Bearer $DOKEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Most B2B event teams outgrow their first registration tool...",
    "content_type": "blog",
    "primary_keyword": "event software"
  }'

3Read the verdict

The top-level verdict is the worst severity any check returned. Each failing check carries its reasons, and action_items says what to change first.

json
{
  "verdict": "FAIL",
  "report": {
    "scores": { "overall": 54, "seo": 65, "aeo": 60, "geo": 38 },
    "checks_detail": [
      { "check": "structure", "severity": "FAIL",
        "reasons": ["152 words is below hard floor 800"] }
    ],
    "action_items": [
      { "priority": "critical", "action": "Add 650 more words to clear the structure hard floor" }
    ]
  }
}
BLOCKERDo not publish. Fix before anything else.
FAILDo not publish. A hard rule failed.
WARNINGPublishable, but a check wants a person to look.
OPTIMIZATIONPasses. There is a cheap improvement on the table.
PASSEvery check cleared.

The checks are deterministic: the same text and settings return the same verdict. The full list is on The Dokeo Checks.

4Run it from your terminal

bash
pip install dokeo
export DOKEO_API_KEY="dk_..."

dokeo scan --file post.md --content-type blog

dokeo scan prints the verdict. Add --fail-on fail or use dokeo pre-commit when a FAIL or BLOCKER should stop something.

5Stop a failing draft in CI

bash
# Stop the commit when a staged file comes back FAIL or BLOCKER
dokeo pre-commit

# Or in CI: exits 1 on FAIL or BLOCKER for the files you pass
dokeo pre-commit content/*.md

The public GitHub Action wraps the same gate with a PR comment. Add rasulshaikh/dokeo-action@v1 to your workflow with your Dokeo API key. Automated scans use the CI allowance on Growth and above. See GitHub Action.

6When it goes wrong

401The key is missing or wrong. Send it as Authorization: Bearer dk_...
402Out of credits. A scan costs 1 credit, a URL costs 1.
422The body failed validation, for example empty content or an unknown content_type.
429Rate limit hit. Wait until the time in the X-RateLimit-Reset header.

The full error table and every endpoint are in the REST API reference.

Next