Developer
REST API
Updated 2026-05-18
The Crawlmind REST API lives at https://api.crawlmind.ai/api/v1/*. Authenticate with an API key (Pro+) or a JWT bearer (web app). All responses are JSON. All times are ISO 8601. All IDs are CUIDs. Swagger reference: api.crawlmind.ai/api/docs.
Authentication
Two flavours:
API keys (recommended for automation):
Authorization: Bearer cm_live_AAAA...
Generate from /orgs/<id>/api-keys. Each key is scoped to one organization. Revoke any time. Pro+ only.
JWT bearer (used by the web app itself):
Authorization: Bearer eyJhbGciOi...
Issued by POST /auth/login, expires in 15 minutes, refreshed by the cookie-bound POST /auth/refresh.
Rate limits
Anonymous endpoints (/public/*): 30 req/IP/min. Authenticated endpoints: 600 req/key/min on Pro, scaling with plan. Every response carries the standard headers:
X-RateLimit-Limit: 600 X-RateLimit-Remaining: 547 X-RateLimit-Reset: 1779087847
Exceed and you get 429 with a Retry-After header.
Quick start: run a crawl
# Get your website id
curl -H "Authorization: Bearer $CRAWLMIND_KEY" \
https://api.crawlmind.ai/api/v1/organizations/$ORG/websites
# Start a crawl
curl -H "Authorization: Bearer $CRAWLMIND_KEY" \
-X POST https://api.crawlmind.ai/api/v1/organizations/$ORG/crawls \
-d '{"websiteId":"WBS_xxx","maxPages":25,"renderMode":"STATIC"}'
# Poll the job
curl -H "Authorization: Bearer $CRAWLMIND_KEY" \
https://api.crawlmind.ai/api/v1/organizations/$ORG/crawls/$JOB_ID
# Fetch the report
curl -H "Authorization: Bearer $CRAWLMIND_KEY" \
https://api.crawlmind.ai/api/v1/organizations/$ORG/crawls/$JOB_ID/issuesPublic (no-auth) endpoints
POST /api/v1/public/scorecard— start a public scorecard runGET /api/v1/public/scorecard/by-domain/:host— most-recent scorecard for a hostGET /api/v1/public/scorecard/recent/index— recent scorecards (powers our sitemap)GET /api/v1/public/scorecard/public-stats— aggregate counters (sites audited, issues found)POST /api/v1/public/pv— page-view ingest (used by our own client plugin)
These are rate-limited per IP and intentionally narrow in scope.
Error envelope
Every 4xx/5xx response follows the same shape:
{
"statusCode": 400,
"error": "VALIDATION_FAILED",
"message": "Field 'maxPages' exceeds plan limit (200)",
"details": { "limit": 200, "current": 500 }
}
5xx responses always include a requestId you can quote when contacting support.
Related docs
Ready to try it?
Free tier: 5 crawls / month, no credit card.