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

# Error Codes

> Complete reference of OLIVE API error codes

# Error Codes Reference

Comprehensive reference of all error codes returned by OLIVE APIs.

## Error Response Format

All errors follow this structure:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable message",
    "details": {
      "field": "Additional context"
    }
  }
}
```

***

## HTTP Status Codes

| Code | Name                  | Description                          |
| ---- | --------------------- | ------------------------------------ |
| 400  | Bad Request           | Invalid request format or parameters |
| 401  | Unauthorized          | Invalid or missing authentication    |
| 402  | Payment Required      | Insufficient balance or funds        |
| 403  | Forbidden             | Authenticated but not authorized     |
| 404  | Not Found             | Resource does not exist              |
| 409  | Conflict              | Resource already exists              |
| 422  | Unprocessable Entity  | Validation failed                    |
| 429  | Too Many Requests     | Rate limit exceeded                  |
| 500  | Internal Server Error | Server-side error                    |
| 503  | Service Unavailable   | Temporary outage                     |

***

## Authentication Errors

| Code                 | HTTP | Description              | Resolution                     |
| -------------------- | ---- | ------------------------ | ------------------------------ |
| `AUTH_MISSING`       | 401  | No auth header provided  | Include `Authorization` header |
| `AUTH_INVALID`       | 401  | Token/key is invalid     | Check credentials              |
| `AUTH_EXPIRED`       | 401  | Token has expired        | Refresh or re-authenticate     |
| `SIGNATURE_INVALID`  | 401  | HMAC signature failed    | Check signing algorithm        |
| `SIGNATURE_EXPIRED`  | 401  | Timestamp too old        | Sync clock, retry              |
| `API_KEY_REVOKED`    | 401  | API key has been revoked | Contact admin for new key      |
| `INSUFFICIENT_SCOPE` | 403  | Key lacks required scope | Use key with proper scope      |

***

## Transaction Errors

| Code                         | HTTP | Description                     | Resolution                       |
| ---------------------------- | ---- | ------------------------------- | -------------------------------- |
| `INSUFFICIENT_BALANCE`       | 402  | Not enough funds                | Check balance before transaction |
| `DAILY_LIMIT_EXCEEDED`       | 400  | Daily transaction limit reached | Wait for next day or upgrade KYC |
| `MONTHLY_LIMIT_EXCEEDED`     | 400  | Monthly limit reached           | Wait for next month              |
| `TRANSACTION_LIMIT_EXCEEDED` | 400  | Single transaction too large    | Reduce amount                    |
| `DUPLICATE_REQUEST`          | 409  | Request ID already used         | Use unique request\_id           |
| `TRANSACTION_FAILED`         | 500  | General processing error        | Retry with same request\_id      |
| `RECIPIENT_NOT_FOUND`        | 404  | Recipient doesn't exist         | Verify recipient ID              |

***

## Card Errors

| Code                  | HTTP | Description                       | Resolution                 |
| --------------------- | ---- | --------------------------------- | -------------------------- |
| `CARD_NOT_FOUND`      | 404  | Card serial not in system         | Verify serial number       |
| `CARD_ALREADY_LINKED` | 409  | Card linked to another subscriber | Card cannot be reused      |
| `CARD_BLOCKED`        | 400  | Card is blocked                   | Unblock card first         |
| `CARD_DISABLED`       | 400  | Card permanently disabled         | Request new card           |
| `INVALID_PIN`         | 400  | Wrong PIN entered                 | Check PIN (max 3 attempts) |
| `PIN_LOCKED`          | 400  | Too many wrong PIN attempts       | Contact support to unlock  |

***

## Subscriber Errors

| Code                       | HTTP | Description               | Resolution              |
| -------------------------- | ---- | ------------------------- | ----------------------- |
| `SUBSCRIBER_NOT_FOUND`     | 404  | Subscriber doesn't exist  | Check ID/phone number   |
| `PHONE_ALREADY_REGISTERED` | 409  | Phone number in use       | Use different phone     |
| `KYC_REQUIRED`             | 400  | Higher KYC level needed   | Upgrade KYC level       |
| `ACCOUNT_SUSPENDED`        | 403  | Account is suspended      | Contact support         |
| `ACCOUNT_BLOCKED`          | 403  | Account is blocked        | Contact compliance      |
| `INVALID_PHONE_FORMAT`     | 400  | Phone number format wrong | Use +232XXXXXXXX format |

***

## Agent Errors

| Code                    | HTTP | Description                   | Resolution                |
| ----------------------- | ---- | ----------------------------- | ------------------------- |
| `AGENT_NOT_FOUND`       | 404  | Agent doesn't exist           | Verify agent ID           |
| `INSUFFICIENT_FLOAT`    | 402  | Agent lacks float             | Request float from master |
| `AGENT_SUSPENDED`       | 403  | Agent is suspended            | Contact admin             |
| `FLOAT_TRANSFER_DENIED` | 403  | Cannot transfer to this agent | Check agent relationship  |

***

## POS/Processor Errors

| Code                      | HTTP | Description             | Resolution                 |
| ------------------------- | ---- | ----------------------- | -------------------------- |
| `PROCESSOR_NOT_FOUND`     | 404  | Processor doesn't exist | Verify processor ID        |
| `PROCESSOR_SUSPENDED`     | 403  | Processor is suspended  | Contact admin              |
| `INVALID_HMAC`            | 401  | HMAC signature invalid  | Check secret and algorithm |
| `TERMINAL_NOT_REGISTERED` | 401  | Unknown terminal        | Register terminal first    |

***

## PEP Access Errors

| Code                    | HTTP | Description                   | Resolution                |
| ----------------------- | ---- | ----------------------------- | ------------------------- |
| `PEP_ACCESS_DENIED`     | 403  | Not authorized for PEP access | Request PEP authorization |
| `INVALID_OTP`           | 400  | Wrong or expired OTP          | Request new OTP           |
| `OTP_EXPIRED`           | 400  | OTP has expired               | Request new OTP           |
| `TOO_MANY_OTP_ATTEMPTS` | 429  | Too many failed OTP attempts  | Wait before retrying      |

***

## Compliance Errors

| Code                    | HTTP | Description                    | Resolution                      |
| ----------------------- | ---- | ------------------------------ | ------------------------------- |
| `COMPLIANCE_HOLD`       | 403  | Transaction flagged for review | Wait for compliance clearance   |
| `BLOCKED_RECIPIENT`     | 403  | Recipient is on blocklist      | Cannot transact with this party |
| `HIGH_RISK_TRANSACTION` | 400  | Transaction blocked by rules   | Contact compliance              |

***

## Validation Errors

| Code                     | HTTP | Description                 | Resolution                   |
| ------------------------ | ---- | --------------------------- | ---------------------------- |
| `VALIDATION_FAILED`      | 422  | Input validation failed     | Check error details          |
| `REQUIRED_FIELD_MISSING` | 400  | Required field not provided | Include all required fields  |
| `INVALID_AMOUNT`         | 400  | Amount format invalid       | Use positive integer (cents) |
| `INVALID_CURRENCY`       | 400  | Unknown currency code       | Use `SLE` or `USD`           |

***

## Rate Limit Errors

| Code           | HTTP | Description       | Resolution     |
| -------------- | ---- | ----------------- | -------------- |
| `RATE_LIMITED` | 429  | Too many requests | Wait and retry |

### Rate Limit Headers

```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704067200
Retry-After: 60
```

***

## Error Handling Best Practices

<CardGroup cols={2}>
  <Card title="Idempotency" icon="repeat">
    Always include `request_id` for safe retries on failures
  </Card>

  <Card title="Exponential Backoff" icon="clock">
    Use exponential backoff for rate limit and server errors
  </Card>

  <Card title="Error Logging" icon="file-lines">
    Log full error responses for debugging
  </Card>

  <Card title="Graceful Degradation" icon="shield">
    Handle errors gracefully in your application
  </Card>
</CardGroup>

### Retry Strategy

```javascript theme={null}
async function withRetry(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429 || error.status >= 500) {
        const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
        await new Promise(r => setTimeout(r, delay));
        continue;
      }
      throw error; // Don't retry 4xx errors
    }
  }
  throw new Error('Max retries exceeded');
}
```

***

## Related

<CardGroup cols={2}>
  <Card title="Troubleshooting" icon="wrench" href="/reference/troubleshooting">
    Common issues and solutions
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/overview">
    Full API documentation
  </Card>
</CardGroup>
