Troubleshooting Common API Errors

400 - Bad Request

Your request is malformed or contains invalid data.

Common causes:

  • Missing required fields in request body
  • Invalid JSON syntax
  • Wrong data types (string instead of integer)
  • Sending body with GET request
  • Invalid query parameters
Example
**Error Response**
{
  "error": "Bad Request",
  "message": "The issue_id field is required.",
  "status": 400
}
```</div>
</div>

<div class="do-dont">
<div class="do">

</div>
<div class="dont">

</div>
</div>

---

## 401 - Unauthorized

You are not authenticated, or your token is invalid/expired.

**Common causes:**
- Missing `Authorization` header
- Invalid or expired token
- Token was revoked
- Typo in Bearer token

<div class="callout callout-example">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
<span class="callout-title">Example</span>
</div>
<div class="callout-body">**Error Response**

```json
{
  "error": "Unauthorized",
  "message": "Unauthenticated.",
  "status": 401
}
```</div>
</div>

**How to fix:**
```javascript
// Good: Proper authentication
fetch('https://versedb.com/api/user/collection', {
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN_HERE'
  }
})
Tip
**Troubleshooting Steps**
  1. Verify token exists and is copied correctly
  2. Check for extra spaces or characters in token
  3. Ensure using Bearer prefix (not Token or Basic)
  4. Generate new token at: versedb.com/user/api-tokens
  5. Test token with GET /api/user first

402 - Payment Required

You're trying to access a PRO-only feature without a PRO subscription.

Common causes:

  • Accessing relationship endpoints (/api/series/{id}/issues)
  • Accessing market data endpoints
  • PRO-only features with free account
Example
**Error Response**
{
  "error": "Payment Required",
  "message": "This endpoint requires a PRO subscription.",
  "status": 402
}
```</div>
</div>

<div class="callout callout-tip">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path d="M11 3a1 1 0 10-2 0v1a1 1 0 102 0V3zM15.657 5.757a1 1 0 00-1.414-1.414l-.707.707a1 1 0 001.414 1.414l.707-.707zM18 10a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM5.05 6.464A1 1 0 106.464 5.05l-.707-.707a1 1 0 00-1.414 1.414l.707.707zM5 10a1 1 0 01-1 1H3a1 1 0 110-2h1a1 1 0 011 1zM8 16v-1h4v1a2 2 0 11-4 0zM12 14c.015-.34.208-.646.477-.859a4 4 0 10-4.954 0c.27.213.462.519.476.859h4.002z"/></svg>
<span class="callout-title">Tip</span>
</div>
<div class="callout-body">**How to Fix**

Upgrade to PRO at versedb.com/subscription, or use alternative endpoints available to free users.</div>
</div>

---

## 403 - Forbidden

You are authenticated but lack permission to perform this action.

**Common causes:**
- Token lacks required scope/permission
- Attempting to access another user's private data
- Attempting admin operations without admin role
- Resource privacy settings prevent access

<div class="callout callout-example">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
<span class="callout-title">Example</span>
</div>
<div class="callout-body">**Error Response**

```json
{
  "error": "Forbidden",
  "message": "This action is unauthorized.",
  "status": 403
}
```</div>
</div>

**Token abilities:**
- `read:public` - Read public comic data
- `read:user` - Read your personal data
- `write:lists` - Manage collections, wishlists, pull lists
- `write:reviews` - Write reviews
- `write:favorites` - Manage favorites

---

## 404 - Not Found

The requested resource doesn't exist.

**Common causes:**
- Incorrect or non-existent ID
- Typo in endpoint path
- Using slug instead of numeric ID
- Resource was deleted

<div class="callout callout-example">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
<span class="callout-title">Example</span>
</div>
<div class="callout-body">**Error Response**

```json
{
  "error": "Not Found",
  "message": "No query results for model [Series] 99999",
  "status": 404
}
```</div>
</div>

<div class="callout callout-warning">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/></svg>
<span class="callout-title">Warning</span>
</div>
<div class="callout-body">**Use Numeric IDs**

The API uses numeric IDs, not slugs:
- Good: `GET /api/series/123`
- Bad: `GET /api/series/amazing-spider-man-2018`</div>
</div>

---

## 405 - Method Not Allowed

You're using the wrong HTTP method for this endpoint.

**HTTP method reference:**
- **GET** - Read/retrieve data
- **POST** - Create new resources
- **PUT/PATCH** - Update existing resources
- **DELETE** - Remove resources

<div class="callout callout-example">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
<span class="callout-title">Example</span>
</div>
<div class="callout-body">**Error Response**

```json
{
  "error": "Method Not Allowed",
  "message": "The GET method is not supported for this route.",
  "status": 405
}
```</div>
</div>

---

## 422 - Unprocessable Entity

Request is well-formed but contains semantic errors or validation failures.

**Common causes:**
- Validation rules failed
- Invalid data values
- Foreign key constraints violated
- Business logic rules not met

<div class="callout callout-example">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
<span class="callout-title">Example</span>
</div>
<div class="callout-body">**Error Response**

```json
{
  "error": "Unprocessable Entity",
  "message": "The given data was invalid.",
  "errors": {
    "issue_id": ["The selected issue id is invalid."],
    "condition": ["The condition must be one of: M, NM, VF, F, VG, G, FR, PR"]
  },
  "status": 422
}
```</div>
</div>

<div class="callout callout-tip">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path d="M11 3a1 1 0 10-2 0v1a1 1 0 102 0V3zM15.657 5.757a1 1 0 00-1.414-1.414l-.707.707a1 1 0 001.414 1.414l.707-.707zM18 10a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM5.05 6.464A1 1 0 106.464 5.05l-.707-.707a1 1 0 00-1.414 1.414l.707.707zM5 10a1 1 0 01-1 1H3a1 1 0 110-2h1a1 1 0 011 1zM8 16v-1h4v1a2 2 0 11-4 0zM12 14c.015-.34.208-.646.477-.859a4 4 0 10-4.954 0c.27.213.462.519.476.859h4.002z"/></svg>
<span class="callout-title">Tip</span>
</div>
<div class="callout-body">**How to Fix**

Read the `errors` object for specific field issues. Validate data before sending and check allowed values for enum fields.</div>
</div>

---

## 429 - Too Many Requests

You've exceeded your rate limit.

<div class="callout callout-example">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
<span class="callout-title">Example</span>
</div>
<div class="callout-body">**Error Response**

```json
{
  "error": "Too Many Requests",
  "message": "API rate limit exceeded. Please try again later.",
  "retry_after": 3600,
  "status": 429
}
```</div>
</div>

**Response headers:**
```http
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712869200
Retry-After: 3600
Warning
**Handle 429 Properly**

Don't keep retrying immediately. Check the Retry-After header and wait before making more requests.

How to handle:

if (response.status === 429) {
  const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
  console.log(`Rate limited. Waiting ${retryAfter}s...`);
  await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
}

500 - Internal Server Error

Something went wrong on the VerseDB server.

Example
**Error Response**
{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred.",
  "status": 500
}
```</div>
</div>

**What to do:**
1. Retry with exponential backoff (wait 1s, 2s, 4s between retries)
2. If error persists, check VerseDB status page
3. Report issue to support with request details and timestamp

<div class="callout callout-note">
<div class="callout-header">
<svg class="callout-icon" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/></svg>
<span class="callout-title">Note</span>
</div>
<div class="callout-body">500 errors are usually temporary. If consistent, contact support.</div>
</div>

---

## 503 - Service Unavailable

The server is temporarily unavailable (maintenance, overload, etc.)

**What to do:**
- Wait a few minutes and retry
- Check for scheduled maintenance announcements
- Implement graceful degradation in your app

---

## Quick Reference

<div class="field-list">
| Code | Error | Common Fix |
|------|-------|------------|
| 400 | Bad Request | Check JSON syntax and required fields |
| 401 | Unauthorized | Add/update Bearer token |
| 402 | Payment Required | Upgrade to PRO subscription |
| 403 | Forbidden | Check token permissions/abilities |
| 404 | Not Found | Verify resource ID exists |
| 405 | Method Not Allowed | Use correct HTTP method |
| 422 | Unprocessable Entity | Fix validation errors |
| 429 | Too Many Requests | Wait and retry, respect rate limits |
| 500 | Server Error | Retry with exponential backoff |
| 503 | Service Unavailable | Wait and retry later |
</div>

---

## Debugging Tips

### Log Full Error Response
```javascript
fetch(url, {
  headers: { 'Authorization': 'Bearer TOKEN' }
})
  .then(response => {
    if (!response.ok) {
      return response.json().then(error => {
        console.error('API Error:', {
          status: response.status,
          error: error,
          url: url
        });
        throw new Error(error.message || 'API request failed');
      });
    }
    return response.json();
  });

Test with cURL

curl -v -H "Authorization: Bearer TOKEN" \
     https://versedb.com/api/user/collection
Quick Summary