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

# Error Handling

> API error codes and handling

# Error Handling

The API uses standard HTTP status codes and returns detailed error information in the response body.

## HTTP Status Codes

| Code  | Description                                                 |
| ----- | ----------------------------------------------------------- |
| `200` | Success                                                     |
| `201` | Created                                                     |
| `400` | Bad Request - Invalid parameters                            |
| `401` | Unauthorized - Invalid or missing API key                   |
| `403` | Forbidden - Insufficient permissions                        |
| `404` | Not Found - Resource doesn't exist                          |
| `409` | Conflict - Duplicate idempotency key with different payload |
| `422` | Unprocessable Entity - Validation failed                    |
| `429` | Too Many Requests - Rate limit exceeded                     |
| `500` | Internal Server Error                                       |

## Error Response Format

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": [
      {
        "field": "fieldName",
        "message": "Field-specific error"
      }
    ],
    "requestId": "req_abc123"
  }
}
```

## Common Error Codes

### Validation Errors

| Code                     | Description                          |
| ------------------------ | ------------------------------------ |
| `VALIDATION_ERROR`       | Request parameters failed validation |
| `INVALID_CURRENCY`       | Unsupported currency code            |
| `INVALID_AMOUNT`         | Amount is out of allowed range       |
| `INVALID_WALLET_ADDRESS` | Wallet address format is invalid     |
| `INVALID_NETWORK`        | Unsupported network                  |
| `INVALID_GATEWAY`        | Gateway ID not found or not enabled  |

### Resource Errors

| Code                    | Description                               |
| ----------------------- | ----------------------------------------- |
| `TRANSACTION_NOT_FOUND` | Transaction ID doesn't exist              |
| `PROJECT_NOT_FOUND`     | Project ID doesn't exist                  |
| `GATEWAY_UNAVAILABLE`   | Selected gateway is currently unavailable |

### Rate Limiting

| Code                  | Description                                               |
| --------------------- | --------------------------------------------------------- |
| `RATE_LIMIT_EXCEEDED` | Too many requests — include a `pk_` key for higher limits |

### Authentication Errors

| Code              | Description                       |
| ----------------- | --------------------------------- |
| `INVALID_API_KEY` | The API key is invalid or revoked |

## Handling Errors

### JavaScript Example

```javascript theme={null}
async function getQuotes(params) {
  const response = await fetch(
    `https://api.nowramp.com/public/v1/onramp/quotes?${new URLSearchParams(params)}`
  );

  const data = await response.json();

  if (!data.success) {
    switch (data.error.code) {
      case 'VALIDATION_ERROR':
        // Show field-specific errors to the user
        console.error('Validation:', data.error.details);
        break;
      case 'INVALID_AMOUNT':
        // Amount is below minimum or above maximum
        console.error('Invalid amount:', data.error.message);
        break;
      case 'RATE_LIMIT_EXCEEDED':
        // Back off and retry
        await new Promise(r => setTimeout(r, 5000));
        return getQuotes(params);
      default:
        throw new Error(data.error.message);
    }
  }

  return data.data;
}
```

## Retry Strategy

For transient errors (5xx, network issues), implement exponential backoff:

```javascript theme={null}
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);

      if (response.status >= 500) {
        throw new Error('Server error');
      }

      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;

      const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}
```

<Info>
  Always include the `requestId` from error responses when contacting support.
</Info>
