# Common Error Codes and How to Fix Them

> Diagnose and fix the most common API errors you might encounter.

**Category:** troubleshooting | **Last updated:** March 13, 2026

---

When something goes wrong, the Fidro API returns a structured error response. This guide covers every error you might encounter and how to fix it.

## Error response format

All errors follow this structure:

```json
{
  "error": {
    "type": "invalid_request_error",
    "message": "Human-readable description of what went wrong.",
    "errors": {}
  }
}
```

## HTTP status codes

### 400 — Bad Request

**What:** Your request body is malformed or missing required fields.

**Common causes:**
- Sending `Content-Type: application/x-www-form-urlencoded` instead of `application/json`
- Empty request body
- Invalid JSON syntax

**Fix:** Ensure you're sending valid JSON with the `Content-Type: application/json` header.

### 401 — Unauthorized

**What:** Your API key is missing, invalid, or expired.

**Common causes:**
- Missing `Authorization` header
- Using `Bearer` with extra spaces or wrong format
- Deleted or expired API key
- Using a test key in production (or vice versa)

**Fix:** Check your `Authorization: Bearer YOUR_API_KEY` header. Verify the key exists and isn't expired in your [API Keys dashboard](/app/api-keys).

### 422 — Validation Error

**What:** Your request was understood but contained invalid data.

**Common causes:**
- Invalid email format (`"email": "not-an-email"`)
- Invalid IP format (`"ip": "999.999.999.999"`)
- Invalid country code (`"country_code": "XYZ"`)

**Fix:** Check the `errors` object in the response for specific field-level validation messages.

### 429 — Rate Limited

**What:** You've exceeded your rate limit or monthly quota.

**Two types:**
1. **Per-minute rate limit** (60 requests/minute per API key) — Wait and retry
2. **Monthly quota exceeded** — Upgrade your plan or wait for the next billing period

**Fix for per-minute:** Implement exponential backoff. Wait 1 second, then 2, then 4, etc.

**Fix for monthly quota:** The response includes your current usage and plan limits:
```json
{
  "error": {
    "type": "rate_limit_error",
    "limits": {
      "max_requests_per_month": 200,
      "current_usage": 200
    }
  }
}
```

Upgrade your plan from [Account Settings](/app/settings/account) to increase your limit.

### 403 — Forbidden (Feature Not Available)

**What:** Your plan doesn't include the feature you're trying to use.

**Common causes:**
- Using the Blocklist API on the Free plan (requires Starter+)
- Accessing chargeback prevention features on the Free or Starter plan (requires Pro)

**Fix:** Upgrade your plan from [Account Settings](/app/settings/account).

### 500 — Server Error

**What:** Something went wrong on Fidro's side.

**Fix:** These are rare. Retry the request after a short delay. If it persists, check our [status page](https://status.fidro.io) or contact support.

## Handling errors in code

```javascript
const response = await fetch('https://api.fidro.io/api/validate', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ email, ip }),
});

if (!response.ok) {
  const error = await response.json();

  if (response.status === 429) {
    // Rate limited — back off and retry
    await sleep(1000);
    return retry();
  }

  if (response.status === 401) {
    // Bad API key — log and alert
    console.error('Invalid Fidro API key');
    return;
  }

  // For other errors, fall back to allowing the request
  console.error('Fidro API error:', error);
  return { risk_score: 0, recommendation: 'allow' };
}
```

## Best practice: Always have a fallback

If the Fidro API is unreachable or returns a 500, **don't block your users**. Fall back to allowing the request and log the error for investigation. It's better to let one bad actor through than to block every customer because of an API timeout.