Skip to main content

Error Handling

Handle errors gracefully in your Pelago integration.

Error Response Format

All API errors follow a consistent format:

{
"error": {
"type": "invalid_request_error",
"code": "missing_parameter",
"message": "The 'amount' parameter is required",
"param": "amount",
"doc_url": "https://docs.pelago.tech/errors#missing_parameter"
}
}

HTTP Status Codes

CodeDescriptionAction
200SuccessProcess response
201CreatedResource created
400Bad RequestFix request parameters
401UnauthorizedCheck API keys
403ForbiddenCheck permissions
404Not FoundCheck resource ID
409ConflictHandle idempotency
422UnprocessableFix validation errors
429Rate LimitedSlow down requests
500Server ErrorRetry with backoff
503Service UnavailableRetry later

Error Types

authentication_error

Invalid or missing API credentials.

{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "Invalid API key provided"
}
}

Solution:

// Check API key format
if (!apiKey.startsWith('pk_')) {
throw new Error('Invalid API key format');
}

// Verify keys are set
if (!process.env.PELAGO_API_KEY) {
throw new Error('PELAGO_API_KEY not configured');
}

invalid_request_error

Request parameters are invalid or missing.

{
"error": {
"type": "invalid_request_error",
"code": "invalid_amount",
"message": "Amount must be greater than 0",
"param": "amount"
}
}

Common Codes:

CodeDescription
missing_parameterRequired field missing
invalid_parameterField value invalid
invalid_amountAmount <= 0 or too large
invalid_currencyUnsupported currency
invalid_networkUnsupported network
invalid_walletMalformed wallet address

rate_limit_error

Too many requests.

{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Retry after 60 seconds"
}
}

Solution:

async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.type === 'rate_limit_error') {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(r => setTimeout(r, delay));
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}

payment_error

Payment-specific errors.

CodeDescriptionRecovery
payment_expiredPayment timed outCreate new payment
payment_already_completedAlready paidNo action needed
insufficient_fundsCustomer lacks fundsCustomer adds funds
network_errorBlockchain issueRetry later
wallet_errorInvalid walletFix wallet address

api_error

Server-side issues.

{
"error": {
"type": "api_error",
"code": "internal_error",
"message": "An internal error occurred"
}
}

Solution: Retry with exponential backoff.

SDK Error Handling

JavaScript

import { PelagoClient, PelagoError } from '@pelago/sdk';

try {
const payment = await pelago.payments.create({
amount: 100,
currency: 'USD',
// ...
});
} catch (error) {
if (error instanceof PelagoError) {
switch (error.type) {
case 'authentication_error':
console.error('Check your API keys');
break;
case 'invalid_request_error':
console.error('Invalid param:', error.param);
break;
case 'rate_limit_error':
console.error('Slow down, retrying...');
await delay(60000);
// Retry
break;
case 'payment_error':
console.error('Payment error:', error.code);
break;
default:
console.error('Unexpected error:', error.message);
}
} else {
// Network error or other issue
console.error('Connection error:', error);
}
}

Python

from pelago import PelagoClient, PelagoError
from pelago.errors import (
AuthenticationError,
InvalidRequestError,
RateLimitError,
PaymentError
)

try:
payment = pelago.payments.create(
amount=100,
currency='USD',
# ...
)
except AuthenticationError as e:
print('Check your API keys')
except InvalidRequestError as e:
print('Invalid param:', e.param)
except RateLimitError:
print('Rate limited, retrying...')
time.sleep(60)
# Retry
except PaymentError as e:
print('Payment error:', e.code)
except PelagoError as e:
print('Unexpected error:', e.message)

Validation Errors

For validation errors, check all failed fields:

{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "Request validation failed",
"errors": [
{
"param": "amount",
"message": "Amount must be greater than 0"
},
{
"param": "currency",
"message": "Currency must be uppercase"
}
]
}
}

Handling:

catch (error) {
if (error.code === 'validation_failed') {
for (const fieldError of error.errors) {
console.error(`${fieldError.param}: ${fieldError.message}`);
}
}
}

Network Error Handling

async function createPaymentWithRetry(params: PaymentParams) {
const maxRetries = 3;
let lastError: Error;

for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await pelago.payments.create(params);
} catch (error) {
lastError = error;

// Don't retry client errors
if (error.type === 'invalid_request_error') {
throw error;
}

// Don't retry authentication errors
if (error.type === 'authentication_error') {
throw error;
}

// Retry server errors and network issues
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retry ${attempt}/${maxRetries} in ${delay}ms`);
await new Promise(r => setTimeout(r, delay));
}
}
}

throw lastError;
}

Error Logging Best Practices

import { PelagoError } from '@pelago/sdk';

function logError(error: Error, context: object) {
if (error instanceof PelagoError) {
console.error({
type: 'pelago_error',
errorType: error.type,
code: error.code,
message: error.message,
param: error.param,
requestId: error.requestId, // For support
...context
});
} else {
console.error({
type: 'unknown_error',
message: error.message,
stack: error.stack,
...context
});
}
}

// Usage
try {
await pelago.payments.create(params);
} catch (error) {
logError(error, {
action: 'create_payment',
orderId: params.metadata.orderId
});
throw error;
}

Next Steps