Docs/Errors

Error Handling

Understanding and handling errors in the Fivo API.

Error Response Format

All API errors follow a consistent format:

Error Response Structure
{
  "success": false,
  "error": "Human-readable error message",
  "details": [
    {
      "field": "amount",
      "message": "Must be a positive number"
    }
  ]
}

HTTP Status Codes

CodeStatusDescription
200OKRequest successful
201CreatedResource created successfully
400Bad RequestInvalid request data or validation error
401UnauthorizedMissing or invalid authentication
403ForbiddenNot authorized to access this resource
404Not FoundResource not found
409ConflictResource already exists (e.g., duplicate txHash)
429Too Many RequestsRate limit exceeded
500Internal ErrorServer error - please contact support

Common Errors

Validation Errors (400)

Invalid input data

Request body doesn't match expected schema. Check the details array for specific field errors.

json
{
  "success": false,
  "error": "Invalid input data",
  "details": [
    {"path": ["amount"], "message": "Expected number, received string"},
    {"path": ["token"], "message": "Invalid enum value. Expected 'USDC' | 'EURC'"}
  ]
}
Invalid amount

Amount must be between 0.01 and 1,000,000.

Invalid merchant address

The toAddress doesn't match the merchant's wallet address.

Authentication Errors (401/403)

No token provided

Protected endpoint requires authentication. Include Authorization or X-API-Key header.

Invalid or expired token

JWT token has expired (15 min lifetime) or is malformed. Re-authenticate to get a new token.

Invalid API key

API key not found or has been revoked. Check that you're using the correct key.

Resource Errors (404/409)

Merchant not found

No merchant exists with the given ID. Verify your merchantId.

Payment not found

No payment exists with the given ID. Check the payment ID is correct.

Payment already exists

A payment with this txHash already exists. This prevents double-spend attacks.

Rate Limiting

When you exceed rate limits, you'll receive a 429 response with additional headers:

Rate Limit Response
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705312800

{
  "success": false,
  "error": "Too many requests",
  "code": "RATE_LIMIT_EXCEEDED",
  "retryAfter": 60
}

Rate Limit Headers

HeaderDescription
Retry-AfterSeconds to wait before retrying
X-RateLimit-LimitMaximum requests allowed in window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when limit resets
i

Best Practice

Implement exponential backoff when you receive 429 errors. Start with theRetry-After value and increase wait time for subsequent retries.

CCTP Errors

Cross-chain payments can fail for several reasons:

Error CodeDescriptionResolution
ATTESTATION_TIMEOUTCircle attestation took too longAutomatic retry, usually resolves
MINT_FAILEDFailed to mint on destinationContact support with payment ID
INSUFFICIENT_GASBackend wallet lacks gasInternal issue, contact support
INVALID_MESSAGECCTP message was invalidContact support with tx hash

Failed CCTP payments store the error in the failure_reason field, accessible via the payment status API.

Fraud Detection

Fivo includes built-in fraud detection. These errors indicate potential attacks:

Payment amount verification failed

The claimed amount doesn't match the actual blockchain transaction amount. This could indicate an attempt to manipulate payment records.

!

Security

Fraud attempts are logged with full details (IP, wallet address, transaction). Repeated attempts may result in IP blocking.

Error Handling Example

Here's how to properly handle API errors in your code:

JavaScript Error Handling
async function createPayment(data) {
  try {
    const response = await fetch('https://api.fivo.finance/payments', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.FIVO_API_KEY
      },
      body: JSON.stringify(data)
    });

    const result = await response.json();

    if (!response.ok) {
      // Handle specific error codes
      switch (response.status) {
        case 400:
          console.error('Validation error:', result.details);
          throw new Error('Invalid payment data');

        case 401:
          console.error('Authentication failed');
          throw new Error('Please check your API key');

        case 429:
          const retryAfter = response.headers.get('Retry-After');
          console.log(`Rate limited. Retry after ${retryAfter}s`);
          throw new Error('Too many requests');

        default:
          throw new Error(result.error || 'Unknown error');
      }
    }

    return result.data;
  } catch (error) {
    console.error('Payment failed:', error.message);
    throw error;
  }
}

Still Having Issues?

If you encounter an error not listed here, please contact support with:

  • The full error response
  • Request details (endpoint, method, body)
  • Payment ID or transaction hash (if applicable)
  • Timestamp of when the error occurred
Contact Support