Docs

REST API

Every endpoint for scan, batch, billing, and more.

01 · Draft

Human or LLM

Paste, PR, webhook, or CLI. The gate does not care who wrote it.

REST API

Base URL: https://dokeo-api.fly.dev. Every endpoint is a JSON POST or GET. Bearer-token auth, HMAC-verified, rate-limited.

Authentication

Pass your tenant API key as a Bearer token. Get a key from your admin or by calling POST /api/v1/admin/keys.

bash
# All requests need an Authorization header with a Bearer token
curl https://dokeo-api.fly.dev/api/v1/scan \
  -H "Authorization: Bearer dk_your_tenant_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Your blog post here...",
    "content_type": "blog"
  }'

Response shape

Every scan returns the same envelope. verdict is the worst of five severities, most to least severe: BLOCKER (ships never), FAIL, WARNING, OPTIMIZATION (a suggestion, never blocks), or PASS. scores.overall is 0-100. checks_detail[] has one row per check with its own severity, reasons, and metrics.

json
{
  "slug": "my-post",
  "verdict": "WARNING",
  "content_type": "blog",
  "word_count": 1245,
  "report": {
    "scores": {
      "overall": 87,
      "seo": 92,
      "aeo": 81,
      "geo": 88
    },
    "meta": {
      "pass_count": 6, "blocker_count": 0, "fail_count": 0,
      "warning_count": 1, "optimization_count": 0
    },
    "checks_detail": [
      {
        "check": "structure",
        "status": "PASS",
        "severity": "PASS",
        "reasons": ["1245 words, in target band"],
        "metrics": { "word_count": 1245, "h2_count": 6 }
      }
    ],
    "action_items": [
      { "priority": "recommended", "action": "Add an FAQ section for AEO" }
    ],
    "inline_issues": []
  }
}

Endpoints

POST/api/v1/scan

Score inline content. 1 credit per call.

FieldTypeNotes
contentstringRequired The post body
content_typestringDefault: blog One of 17 types
titlestringOptional Post title
slugstringOptional Post slug
primary_keywordstringOptional Main SEO keyword
strictnessstringDefault: balanced strict | balanced | permissive
POST/api/v1/scan/url

Fetch + score a URL. SSRF-guarded (blocks private/loopback IPs).

FieldTypeNotes
urlstringRequired https URL
content_typestringDefault: blog
strictnessstringDefault: balanced
POST/api/v1/scan/blog

Score every post on a blog (discovered via RSS/sitemap).

FieldTypeNotes
urlstringRequired Blog index / RSS / sitemap URL
limitintDefault: 10 Max posts to scan
content_typestringDefault: blog
POST/api/v1/builder/research

Gate 1: research keyword + N tools. LLM does web search + per-tool lookup.

FieldTypeNotes
primary_keywordstringRequired
audiencestringRequired e.g. 'B2B event teams'
tool_countintDefault: 6 2-15
house_productstringRequired Your brand to lead with
llm_providerstringDefault: auto auto | claude | gpt | mock
mockboolDefault: false Use fixtures, no LLM
POST/api/v1/builder/generate

Gate 2: write the draft. Returns draft_md + QA report + editorial score.

FieldTypeNotes
research_bundleobjectRequired Output of /builder/research
formatstringDefault: listicle listicle | comparison | alternatives | buyers_guide
llm_providerstringDefault: auto
mockboolDefault: false
GET/api/v1/billing/entitlement

Current tenant + tier + credit balance + usage this period.

POST/api/v1/checkout/create-session

Create a Razorpay (or Stripe) checkout session for a paid tier. Requires a signed-in session (Bearer JWT).

FieldTypeNotes
tierstringRequired growth | pro | scale
cyclestringDefault: monthly monthly | annual
GET/api/v1/catalog/engines

List the supported engines (SEO/AEO/GEO) and their check names.

POST/api/v1/admin_ext/auto_fix

One-click AI rewrite for a failed check (GLM 5.2). Requires a Growth+ plan; consumes from the rewrite allowance, never from scans.

FieldTypeNotes
contentstringRequired The post body
check_namestringRequired The failing check
reasonsstring[]Optional From check.reasons[]
metricsobjectOptional From check.metrics{}
GET/openapi.json

Full OpenAPI 3.1 spec. Use `dokeo openapi --out spec.json` to dump.

Errors

CodeMeaning
401Missing or invalid Bearer token
402Out of credits. Upgrade or wait for refill.
404Path or scan result not found.
422Validation error (missing field, wrong content type).
429Rate limit exceeded. Check X-RateLimit-Reset header.
502Upstream (Razorpay, search providers) unavailable.
503Server missing required configuration.

Related