API Reference
Build powerful integrations with the Dr Urls REST API. Manage projects, trigger scans, and access SEO data programmatically.
Authentication
Secure API access with Bearer tokens
Every request must carry a valid API key in the Authorization header, using the Bearer scheme. Keys look like drseo_sk_… and are created from Settings → API Keys in the dashboard. The full key is shown once, at creation— we only ever store a hash of it, so it cannot be recovered later. If you lose it, revoke the key and create a new one.
Authorization: Bearer drseo_sk_your_key_herecurl https://drurls.com/api/v1/projects \
-H "Authorization: Bearer drseo_sk_your_key_here"Scope of a key
- A key is bound to the organization it was created in and can only ever read and write that organization’s data.
- Keys authenticate
/api/v1/*data endpoints only. They are not accepted on the dashboard, on sign-in flows, or on internal platform-administration endpoints. - A key acts with your organization’s owner-level permissions, so treat it as a full-access credential: store it in a secret manager, never commit it, and revoke it immediately if it leaks.
- Keys can be given an expiry at creation. Expired and revoked keys stop working immediately.
Base URL
All requests use HTTPS
https://drurls.com/api/v1Endpoints
Available API endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /check | Audit any URL. Public, no key required. Add {"format":"markdown"} (or Accept: text/markdown) for an agent-ready brief. |
| GET | /projects | List all projects |
| POST | /projects | Create a new project |
| GET | /scans | List scans for a project |
| POST | /scans | Start a new scan |
| GET | /scans/:id | Get scan details |
| GET | /scans/:id/issues | Get issues found in a scan |
Rate Limits
Fair usage limits for all plans
Authenticated requests are metered per API key, not per IP address, so your traffic is never affected by other customers sharing an egress address. A separate, wider network-level limit applies per source IP.
How limits are reported. Exceeding the per-IP limit returns 429 RATE_LIMIT_EXCEEDED with a Retry-After: 60 header. Exceeding the per-key limit currently causes the key to stop authenticating for the remainder of the 60-second window, so those requests return 401 UNAUTHORIZED rather than 429. If a key that worked a moment ago starts returning 401 under heavy load, back off for a minute before assuming it is invalid.
Error Responses
What the API returns when a request fails
| Status | Code | When it happens |
|---|---|---|
401 | UNAUTHORIZED | Missing, malformed, unknown, expired or revoked API key — or the per-key rate limit was exceeded. |
403 | FORBIDDEN | The key is valid but not permitted to perform this action, or the endpoint does not accept API keys at all. |
404 | NOT_FOUND | The resource does not exist, or belongs to a different organization than the key. |
422 | VALIDATION_ERROR | The request body failed validation. A details field describes the offending fields. |
429 | RATE_LIMIT_EXCEEDED | Too many requests from your IP address. Retry after the Retry-After interval. |
500 | INTERNAL_ERROR | Something went wrong on our side. Retry with backoff and quote the X-Request-Id header if it persists. |
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required"
}
}Every response — success or error — carries an X-Request-Id header. Include it when contacting support so we can trace the exact request.
Response Format
All responses are returned in JSON format with a consistent structure. Successful responses include a data field. Error responses include an error field with a message and code.
{
"data": {
"id": "scan_abc123",
"status": "completed",
"pagesScanned": 142,
"issuesFound": 23,
"score": 87,
"createdAt": "2026-03-15T10:30:00Z"
},
"meta": {
"requestId": "req_xyz789"
}
}SDKs & Libraries
Node.js SDK
Coming soonOfficial Node.js client for the Dr Urls API with TypeScript support.
npm install @drurls/sdkPython SDK
Coming soonOfficial Python client for the Dr Urls API with async support.
pip install drurls