> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bit2connect.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Understanding error responses and status codes in the Bit2Connect API

## Error Response Format

All API errors follow a consistent JSON structure:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error description",
    "details": {
      "field": "specific_field",
      "issue": "Detailed issue description"
    }
  }
}
```

## HTTP Status Codes

The API uses standard HTTP status codes to indicate the success or failure of requests:

<ResponseField name="200" type="OK">
  Request succeeded
</ResponseField>

<ResponseField name="201" type="Created">
  Resource created successfully
</ResponseField>

<ResponseField name="400" type="Bad Request">
  Invalid request parameters or payload
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  Missing or invalid API key
</ResponseField>

<ResponseField name="403" type="Forbidden">
  Insufficient permissions for the requested action
</ResponseField>

<ResponseField name="404" type="Not Found">
  Requested resource does not exist
</ResponseField>

<ResponseField name="409" type="Conflict">
  Resource already exists (e.g., duplicate link code)
</ResponseField>

<ResponseField name="422" type="Unprocessable Entity">
  Request payload validation failed
</ResponseField>

<ResponseField name="429" type="Too Many Requests">
  Rate limit exceeded
</ResponseField>

<ResponseField name="500" type="Internal Server Error">
  Unexpected server error
</ResponseField>

## Common Error Codes

### Authentication Errors

<ResponseField name="INVALID_API_KEY" type="401">
  The provided API key is missing, malformed, or invalid
</ResponseField>

<ResponseField name="API_KEY_EXPIRED" type="401">
  The API key has expired and needs to be regenerated
</ResponseField>

<ResponseField name="INSUFFICIENT_PERMISSIONS" type="403">
  The API key does not have permission to perform this action
</ResponseField>

### Validation Errors

<ResponseField name="VALIDATION_ERROR" type="422">
  Request payload failed validation. Check the `details` field for specific issues.
</ResponseField>

<ResponseField name="INVALID_PARAMETERS" type="400">
  Query parameters are invalid or out of acceptable range
</ResponseField>

<ResponseField name="MISSING_REQUIRED_FIELD" type="422">
  A required field is missing from the request payload
</ResponseField>

### Resource Errors

<ResponseField name="LINK_NOT_FOUND" type="404">
  The requested link does not exist or you don't have access to it
</ResponseField>

<ResponseField name="CODE_ALREADY_EXISTS" type="409">
  A link with the specified code already exists
</ResponseField>

<ResponseField name="LINK_EXPIRED" type="410">
  The link has expired and is no longer accessible
</ResponseField>

### Rate Limiting

<ResponseField name="RATE_LIMIT_EXCEEDED" type="429">
  You have exceeded your API rate limit. Wait before making more requests.
</ResponseField>

### Subscription Errors

<ResponseField name="SUBSCRIPTION_REQUIRED" type="402">
  An active subscription is required to perform this action
</ResponseField>

<ResponseField name="SUBSCRIPTION_LIMIT_EXCEEDED" type="402">
  You have reached your subscription's usage limits
</ResponseField>

<ResponseField name="PAYMENT_REQUIRED" type="402">
  Payment is required to continue using the service
</ResponseField>

## Error Handling Best Practices

### 1. Check the `success` Field

Always check the `success` field in the response to determine if the request was successful:

```javascript theme={null}
const response = await fetch('https://api.bit2connect.com/api/links', {
  headers: { 'Authorization': 'Bearer b2co_your_api_key' }
});

const data = await response.json();

if (!data.success) {
  console.error('API Error:', data.error.code, data.error.message);
  // Handle error appropriately
}
```

### 2. Handle Specific Error Codes

Different error codes may require different handling strategies:

```javascript theme={null}
switch (data.error.code) {
  case 'INVALID_API_KEY':
    // Redirect to API key setup
    break;
  case 'RATE_LIMIT_EXCEEDED':
    // Implement exponential backoff
    break;
  case 'LINK_NOT_FOUND':
    // Show user-friendly "not found" message
    break;
  default:
    // Generic error handling
}
```

### 3. Implement Retry Logic

For transient errors (5xx status codes, rate limits), implement retry logic with exponential backoff:

```javascript theme={null}
async function apiCallWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      const data = await response.json();
      
      if (data.success) {
        return data;
      }
      
      // Don't retry client errors (4xx)
      if (response.status >= 400 && response.status < 500) {
        throw new Error(data.error.message);
      }
      
      // Retry server errors with exponential backoff
      if (i < maxRetries - 1) {
        await new Promise(resolve => 
          setTimeout(resolve, Math.pow(2, i) * 1000)
        );
      }
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}
```

### 4. Log Errors for Debugging

Always log errors with sufficient context for debugging:

```javascript theme={null}
console.error('Bit2Connect API Error:', {
  endpoint: url,
  method: options.method,
  statusCode: response.status,
  errorCode: data.error.code,
  errorMessage: data.error.message,
  requestId: response.headers.get('x-request-id')
});
```

## Rate Limiting Details

When you exceed your rate limit, the API returns a `429` status code with additional headers:

* `X-RateLimit-Limit`: Your rate limit per hour
* `X-RateLimit-Remaining`: Remaining requests in current window
* `X-RateLimit-Reset`: Unix timestamp when the rate limit resets

```javascript theme={null}
if (response.status === 429) {
  const resetTime = response.headers.get('X-RateLimit-Reset');
  const waitTime = (resetTime * 1000) - Date.now();
  console.log(`Rate limited. Retry after ${waitTime}ms`);
}
```
