Error Codes
The Diffy API returns structured error responses with specific error codes. This page documents all error codes and how to handle them.
Error Response Format
All errors follow this structure:
{
"error": "Human-readable error message",
"code": "ERROR_CODE",
"details": {
// Additional context (varies by error type)
}
}
Authentication Errors
UNAUTHORIZED (401)
Missing or invalid authentication credentials.
{
"error": "Authentication required",
"code": "UNAUTHORIZED"
}
Resolution: Include a valid API key in the Authorization: Bearer YOUR_API_KEY header.
INVALID_API_KEY (401)
The provided API key is invalid or has been revoked.
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}
Resolution: Generate a new API key from the dashboard settings.
Validation Errors
VALIDATION_ERROR (400)
The request body contains invalid data.
{
"error": "Invalid domain format",
"code": "VALIDATION_ERROR",
"details": {
"field": "domain",
"value": "not-a-valid-domain"
}
}
Resolution: Check the request body matches the expected schema.
Resource Errors
NOT_FOUND (404)
The requested resource doesn't exist or you don't have access to it.
{
"error": "Domain with id 'abc123' not found",
"code": "NOT_FOUND",
"details": {
"resource": "Domain",
"id": "abc123"
}
}
Resolution: Verify the resource ID is correct and belongs to your organization.
Rate Limit Errors
RATE_LIMIT_ERROR (429)
You've exceeded the rate limit for this endpoint.
{
"error": "Rate limit exceeded",
"code": "RATE_LIMIT_ERROR",
"details": {
"retryAfter": 60
}
}
Resolution: Wait the specified number of seconds before retrying. Check the Retry-After header.
Quota and Limit Errors (402)
These errors indicate you've exceeded your plan's limits. All 402 errors include an upgradeUrl or renewUrl to resolve the issue.
DOMAIN_LIMIT_EXCEEDED
You've reached the maximum number of domains for your plan.
{
"error": "Domain limit exceeded. Upgrade your plan to add more domains.",
"code": "DOMAIN_LIMIT_EXCEEDED",
"details": {
"current": 2,
"limit": 2,
"upgradeUrl": "/dashboard/settings#upgrade"
}
}
Plan Limits:
| Plan | Max Domains |
|---|---|
| Trial | 25 |
| Starter | 5 |
| Pro | 25 |
| Enterprise | Unlimited |
PAGE_LIMIT_EXCEEDED
You've reached the maximum number of pages for your billing period.
{
"error": "Page limit exceeded for this billing period.",
"code": "PAGE_LIMIT_EXCEEDED",
"details": {
"current": 20,
"limit": 20,
"upgradeUrl": "/dashboard/settings#upgrade"
}
}
Plan Limits:
| Plan | Pages/Domain |
|---|---|
| Trial | 500 |
| Starter | 50 |
| Pro | 500 |
| Enterprise | Unlimited |
MANUAL_RECHECK_NOT_AVAILABLE
Manual rechecks are not available on your current plan (trial).
{
"error": "Manual rechecks are not available on the trial plan. Upgrade to Starter for 2 rechecks/month.",
"code": "MANUAL_RECHECK_NOT_AVAILABLE",
"details": {
"current": 0,
"limit": 0,
"upgradeUrl": "/dashboard/settings#upgrade"
}
}
MANUAL_RECHECK_LIMIT_EXCEEDED
You've used all manual rechecks for this billing period.
{
"error": "You've used all 2 manual rechecks this period.",
"code": "MANUAL_RECHECK_LIMIT_EXCEEDED",
"details": {
"current": 2,
"limit": 2,
"resetsAt": "2026-03-01T00:00:00Z"
}
}
Plan Limits:
| Plan | Manual Rechecks/Month |
|---|---|
| Trial | 10 |
| Starter | 5 |
| Pro | 10 |
| Enterprise | Unlimited |
TRIAL_EXPIRED
Your 14-day trial period has ended.
{
"error": "Your 14-day trial has expired. Upgrade to continue.",
"code": "TRIAL_EXPIRED",
"details": {
"expiredAt": "2026-02-19T17:30:00Z",
"billingCycle": "trial",
"upgradeUrl": "/dashboard/settings#upgrade"
}
}
Resolution: Upgrade to a paid plan to continue using Diffy.
SUBSCRIPTION_EXPIRED
Your paid subscription has expired (failed payment or cancellation).
{
"error": "Your subscription has expired. Please renew to continue.",
"code": "SUBSCRIPTION_EXPIRED",
"details": {
"expiredAt": "2026-02-01T00:00:00Z",
"billingCycle": "monthly",
"renewUrl": "/dashboard/settings#billing"
}
}
Resolution: Update your payment method or renew your subscription.
Server Errors
INTERNAL_ERROR (500)
An unexpected server error occurred.
{
"error": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}
Resolution: Retry the request. If the issue persists, contact support with the X-Trace-Id header value.
SERVICE_UNAVAILABLE (503)
A required service (database, queue) is temporarily unavailable.
{
"error": "Service temporarily unavailable",
"code": "SERVICE_UNAVAILABLE"
}
Resolution: Wait a few minutes and retry.
Handling Errors in Code
JavaScript/TypeScript
try {
const response = await fetch('https://api.trydiffy.com/api/domains', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ domain: 'example.com' }),
})
if (!response.ok) {
const error = await response.json()
switch (error.code) {
case 'DOMAIN_LIMIT_EXCEEDED':
console.log(`Domain limit reached (${error.details.current}/${error.details.limit})`)
console.log(`Upgrade at: ${error.details.upgradeUrl}`)
break
case 'TRIAL_EXPIRED':
console.log('Trial expired. Please upgrade.')
break
case 'RATE_LIMIT_ERROR':
const retryAfter = error.details.retryAfter || 60
console.log(`Rate limited. Retrying in ${retryAfter}s...`)
await sleep(retryAfter * 1000)
// Retry request
break
default:
console.error(`Error: ${error.message}`)
}
}
} catch (error) {
console.error('Network error:', error)
}
Python
import requests
response = requests.post(
'https://api.trydiffy.com/api/domains',
headers={'Authorization': f'Bearer {api_key}'},
json={'domain': 'example.com'}
)
if response.status_code == 402:
error = response.json()
if error['code'] == 'DOMAIN_LIMIT_EXCEEDED':
print(f"Domain limit: {error['details']['current']}/{error['details']['limit']}")
elif error['code'] == 'TRIAL_EXPIRED':
print("Trial expired. Please upgrade.")
elif response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Retry after {retry_after}s")