Uprails

Errors

Understanding and handling errors from the Uprails API.

Error Response Format

When an error occurs, the API returns a JSON response with an error object containing the error type, code, and a human-readable message.

Error Responsejson
{
  "error": {
    "type": "invalid_request",
    "code": "IR_04",
    "message": "Invalid value for field: amount"
  }
}

HTTP Status Codes

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

StatusDescription
200Request succeeded
201Resource created successfully
400Bad request - invalid parameters or missing required fields
401Unauthorized - invalid or missing API key
403Forbidden - insufficient permissions
404Not found - resource doesn't exist
409Conflict - resource already exists or action conflicts
422Unprocessable entity - request understood but cannot be processed
429Too many requests - rate limit exceeded
500Internal server error - something went wrong on our end
502Bad gateway - upstream service error
503Service unavailable - temporary outage

Error Types

Errors are categorized by type to help you handle them appropriately:

authentication_error

Issues with API authentication. Check that your API key is correct and has the required permissions.

invalid_request

The request was malformed or contained invalid parameters. Check the request body and parameters.

processing_error

An error occurred while processing the payment. This may include card declines or issues with the payment method.

rate_limit_error

Too many requests were made in a short period. Wait and retry with exponential backoff.

api_error

An unexpected error occurred on our servers. These are rare and usually temporary. Retry with exponential backoff.

Common Error Codes

CodeTypeDescription
AU_01authentication_errorInvalid API key provided
AU_02authentication_errorAPI key has been revoked
IR_01invalid_requestMissing required field
IR_04invalid_requestInvalid field value
IR_05invalid_requestResource not found
PE_01processing_errorCard declined
PE_02processing_errorInsufficient funds
PE_03processing_errorExpired card
CE_01connector_errorProcessor unavailable
RL_01rate_limit_errorRate limit exceeded

Handling Errors

Here's an example of how to handle errors in your code:

Error Handling Examplejavascript
try {
  const response = await fetch('https://api.uprails.com/payments', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'api-key': 'snd_YOUR_API_KEY'
    },
    body: JSON.stringify({
      amount: 1000,
      currency: 'USD',
      profile_id: 'YOUR_PROFILE_ID'
    })
  });

  const data = await response.json();

  if (!response.ok) {
    const { error } = data;

    switch (error.type) {
      case 'authentication_error':
        // Handle invalid API key
        console.error('Authentication failed:', error.message);
        break;
      case 'invalid_request':
        // Handle validation errors
        console.error('Invalid request:', error.message);
        break;
      case 'processing_error':
        // Handle payment processing errors
        console.error('Payment failed:', error.message);
        break;
      case 'rate_limit_error':
        // Wait and retry
        console.error('Rate limited, retrying...');
        break;
      default:
        // Handle unexpected errors
        console.error('An error occurred:', error.message);
    }
    return;
  }

  // Success - process the payment
  console.log('Payment succeeded:', data.payment_id);

} catch (networkError) {
  // Handle network errors
  console.error('Network error:', networkError);
}

Retry Strategy

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

Retry with Exponential Backoffjavascript
async function retryWithBackoff(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (i === maxRetries - 1) throw error;

      // Only retry on 5xx errors and rate limits
      if (error.status < 500 && error.status !== 429) throw error;

      // Exponential backoff with jitter
      const delay = Math.min(1000 * Math.pow(2, i) + Math.random() * 1000, 30000);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}
Idempotency Keys
Always use idempotency keys when retrying POST requests to prevent duplicate operations.