Skip to main content
Version: 2019-05-29 (Current)

Error Handling

Understand Omise API errors and implement robust error handling for reliable payment integrations. Learn about HTTP status codes, error response formats, and best practices for debugging.

Overviewโ€‹

The Omise API uses conventional HTTP response codes to indicate the success or failure of an API request. Errors return JSON-encoded responses with detailed information to help you debug and handle failures gracefully.

Quick Reference
  • 2xx codes โ†’ Success
  • 4xx codes โ†’ Client errors (your request was invalid)
  • 5xx codes โ†’ Server errors (something went wrong on Omise's side)
  • All errors return JSON with object: "error" and descriptive fields

Error Response Formatโ€‹

All API errors return a consistent JSON structure:

{
"object": "error",
"location": "https://www.omise.co/api-errors#authentication-failure",
"code": "authentication_failure",
"message": "authentication failed"
}

Error Object Fieldsโ€‹

FieldTypeDescription
objectstringAlways "error" for error responses
locationstringURL to documentation for this error type
codestringMachine-readable error code (lowercase with underscores)
messagestringHuman-readable error message in English
Additional Fields

Some errors may include additional context-specific fields like charge_id, customer_id, or validation_errors for detailed debugging.


HTTP Status Codesโ€‹

2xx Successโ€‹

200 OKโ€‹

Meaning: Request succeeded

{
"object": "charge",
"id": "chrg_test_5xuy4w91xqz7d1w9u0t",
"amount": 100000,
"status": "successful"
}

When it occurs:

  • โœ… GET requests returned data successfully
  • โœ… POST/PATCH requests completed successfully
  • โœ… DELETE requests removed resource successfully

201 Createdโ€‹

Meaning: Resource created successfully

When it occurs:

  • โœ… POST request created a new resource (rare, usually returns 200)

4xx Client Errorsโ€‹

Client errors indicate problems with the request you sent. Fix the request and retry.

400 Bad Requestโ€‹

Meaning: The request was malformed or contains invalid parameters

{
"object": "error",
"location": "https://www.omise.co/api-errors#bad-request",
"code": "bad_request",
"message": "amount must be at least 2000 (in subunits)"
}

Common causes:

  • โŒ Missing required parameters
  • โŒ Invalid parameter values
  • โŒ Amount below minimum threshold
  • โŒ Unsupported currency
  • โŒ Malformed JSON payload
  • โŒ Invalid parameter types

Example scenarios:

# Missing required parameter
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "currency=thb"
# Error: amount is required

# Amount too small
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100" \
-d "currency=thb"
# Error: amount must be at least 2000 (20 THB)

How to fix:

  1. โœ… Check API documentation for required parameters
  2. โœ… Validate parameter values before sending
  3. โœ… Ensure proper data types (numbers as numbers, not strings)
  4. โœ… Verify currency-specific minimum amounts

401 Unauthorizedโ€‹

Meaning: Authentication failed - invalid or missing API key

{
"object": "error",
"location": "https://www.omise.co/api-errors#authentication-failure",
"code": "authentication_failure",
"message": "authentication failed"
}

Common causes:

  • โŒ No API key provided
  • โŒ Invalid API key format
  • โŒ Revoked or expired API key
  • โŒ Wrong key for environment (test key in production)
  • โŒ API key not properly encoded in Authorization header

Example scenarios:

# Missing API key
curl https://api.omise.co/account
# Error: authentication failed

# Invalid API key
curl https://api.omise.co/account \
-u invalid_key:
# Error: authentication failed

# Using public key for secret key operation
curl https://api.omise.co/charges \
-X POST \
-u pkey_test_...: \
-d "amount=100000" \
-d "currency=thb"
# Error: authentication failed

How to fix:

  1. โœ… Verify API key is correct (copy from Dashboard)
  2. โœ… Check for extra spaces or characters
  3. โœ… Use secret key for server-side operations
  4. โœ… Use public key only for tokens/sources
  5. โœ… Ensure key hasn't been revoked
  6. โœ… Verify test vs live key matches environment

Learn more about Authentication โ†’


402 Payment Requiredโ€‹

Meaning: Card or payment method was declined

{
"object": "error",
"location": "https://www.omise.co/api-errors#payment-declined",
"code": "payment_declined",
"message": "Your card was declined",
"charge_id": "chrg_test_5xuy4w91xqz7d1w9u0t"
}

Common causes:

  • โŒ Insufficient funds
  • โŒ Card expired
  • โŒ Incorrect card details (CVV, expiry)
  • โŒ Card issuer declined (fraud suspicion)
  • โŒ Card not enabled for online payments
  • โŒ Transaction limit exceeded

Payment-specific error codes:

CodeMeaningAction
insufficient_fundNot enough money on cardAsk customer to use different card
invalid_cardCard number invalidVerify card number
stolen_or_lost_cardCard reported stolen/lostAsk customer to contact bank
failed_processingProcessing failedRetry or use different card
payment_cancelledCustomer cancelled paymentCustomer action, no fix needed
payment_expiredPayment window expiredCreate new charge

Example scenario:

# Charge attempt with insufficient funds
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=1000000" \
-d "currency=thb" \
-d "card=tokn_test_..."
# Error: insufficient_fund

How to fix:

  1. โœ… Show clear error message to customer
  2. โœ… Ask customer to try different payment method
  3. โœ… Don't retry same card multiple times (avoid card blocks)
  4. โœ… Suggest customer contacts their bank
  5. โœ… Log decline reason for analysis
Don't Retry Payment Failures

Repeatedly attempting declined cards can trigger fraud alerts and get cards blocked. Instead, ask customers to verify their payment details or use an alternative payment method.


404 Not Foundโ€‹

Meaning: The requested resource doesn't exist

{
"object": "error",
"location": "https://www.omise.co/api-errors#not-found",
"code": "not_found",
"message": "charge chrg_test_invalid was not found"
}

Common causes:

  • โŒ Invalid resource ID
  • โŒ Resource was deleted
  • โŒ Wrong API endpoint URL
  • โŒ Typo in resource ID
  • โŒ Using test ID in live mode (or vice versa)

Example scenarios:

# Invalid charge ID
curl https://api.omise.co/charges/chrg_invalid \
-u skey_test_...:
# Error: not found

# Wrong endpoint
curl https://api.omise.co/charge/chrg_test_... \
-u skey_test_...:
# Error: not found (should be /charges not /charge)

How to fix:

  1. โœ… Verify resource ID is correct
  2. โœ… Check resource wasn't deleted
  3. โœ… Ensure test/live mode matches key
  4. โœ… Verify endpoint URL spelling
  5. โœ… Search for resource using list endpoint

422 Unprocessable Entityโ€‹

Meaning: Request was well-formed but contains semantic errors

{
"object": "error",
"location": "https://www.omise.co/api-errors#invalid-charge",
"code": "invalid_charge",
"message": "charge has already been captured"
}

Common causes:

  • โŒ Attempting invalid state transition
  • โŒ Business logic violation
  • โŒ Resource already processed
  • โŒ Invalid parameter combination

Example scenarios:

# Capturing already-captured charge
curl https://api.omise.co/charges/chrg_test_.../capture \
-X POST \
-u skey_test_...:
# Error: charge has already been captured

# Refunding more than charge amount
curl https://api.omise.co/charges/chrg_test_.../refunds \
-X POST \
-u skey_test_...: \
-d "amount=200000"
# Error: refund amount exceeds available amount

How to fix:

  1. โœ… Check resource state before operations
  2. โœ… Verify business logic constraints
  3. โœ… Don't retry same operation (it may have succeeded)
  4. โœ… Retrieve resource to check current state

429 Too Many Requestsโ€‹

Meaning: You've exceeded rate limits

{
"object": "error",
"location": "https://www.omise.co/api-errors#rate-limit-exceeded",
"code": "rate_limit_exceeded",
"message": "too many requests, please try again later"
}

Response headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1612137600
Retry-After: 60

How to fix:

  1. โœ… Implement exponential backoff
  2. โœ… Check Retry-After header
  3. โœ… Reduce request frequency
  4. โœ… Batch operations where possible
  5. โœ… Cache responses when appropriate

Learn more about Rate Limiting โ†’


5xx Server Errorsโ€‹

Server errors indicate problems on Omise's side. These are rare but should be handled gracefully.

500 Internal Server Errorโ€‹

Meaning: Something went wrong on Omise's servers

{
"object": "error",
"location": "https://www.omise.co/api-errors#internal-server-error",
"code": "internal_server_error",
"message": "An internal server error occurred"
}

When it occurs:

  • โš ๏ธ Unexpected server-side error
  • โš ๏ธ Temporary service disruption
  • โš ๏ธ Database connectivity issues

How to handle:

  1. โœ… Retry request with exponential backoff
  2. โœ… Check status.omise.co for incidents
  3. โœ… Contact support if persists
  4. โœ… Log error details for debugging

503 Service Unavailableโ€‹

Meaning: Service is temporarily unavailable

{
"object": "error",
"location": "https://www.omise.co/api-errors#service-unavailable",
"code": "service_unavailable",
"message": "Service temporarily unavailable"
}

When it occurs:

  • โš ๏ธ Scheduled maintenance
  • โš ๏ธ Service overload
  • โš ๏ธ Upstream provider issues

How to handle:

  1. โœ… Retry after delay (check Retry-After header)
  2. โœ… Show maintenance message to users
  3. โœ… Queue requests for later processing
  4. โœ… Check status page

Common Error Codesโ€‹

Authentication Errorsโ€‹

CodeHTTP StatusDescriptionSolution
authentication_failure401Invalid or missing API keyVerify API key is correct
forbidden403Key lacks required permissionsUse secret key for this operation

Request Errorsโ€‹

CodeHTTP StatusDescriptionSolution
bad_request400Invalid request parametersCheck required parameters and formats
invalid_charge422Charge state doesn't allow operationVerify charge status first
invalid_customer422Customer operation not allowedCheck customer state
not_found404Resource doesn't existVerify resource ID

Payment Errorsโ€‹

CodeHTTP StatusDescriptionSolution
payment_declined402Payment was declinedAsk customer to use different card
insufficient_fund402Not enough balanceRequest different payment method
invalid_card402Card details invalidVerify card number and CVV
stolen_or_lost_card402Card reported stolen/lostCustomer must contact bank
failed_processing402Payment processing failedRetry or use different card
payment_cancelled402Customer cancelled paymentCustomer action
payment_expired402Payment window expiredCreate new charge

System Errorsโ€‹

CodeHTTP StatusDescriptionSolution
internal_server_error500Server-side errorRetry with backoff
service_unavailable503Service temporarily downWait and retry
rate_limit_exceeded429Too many requestsImplement rate limiting

Error Handling Best Practicesโ€‹

1. Always Check HTTP Status Firstโ€‹

# โœ… Good - Check status code
require 'omise'

begin
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: params[:token]
})

# Success
render json: charge

rescue Omise::Error => e
# Handle error based on type
case e.http_status
when 400
render json: { error: 'Invalid request' }, status: 400
when 401
render json: { error: 'Authentication failed' }, status: 401
when 402
render json: { error: 'Payment declined', code: e.code }, status: 402
when 404
render json: { error: 'Resource not found' }, status: 404
when 422
render json: { error: 'Invalid operation', message: e.message }, status: 422
when 429
render json: { error: 'Rate limit exceeded' }, status: 429
when 500, 503
render json: { error: 'Service temporarily unavailable' }, status: 503
else
render json: { error: 'An error occurred' }, status: 500
end
end

2. Parse Error Detailsโ€‹

# โœ… Good - Extract error details
import omise

try:
charge = omise.Charge.create(
amount=100000,
currency='thb',
card=token
)
return charge

except omise.errors.BaseError as e:
error_code = e.code
error_message = e.message

# Log for debugging
logger.error(f"Charge failed: {error_code} - {error_message}")

# Return user-friendly message
if error_code == 'insufficient_fund':
return {'error': 'Insufficient funds. Please try a different card.'}
elif error_code == 'invalid_card':
return {'error': 'Invalid card details. Please check and try again.'}
else:
return {'error': 'Payment failed. Please try again.'}

3. Implement Retry Logic for Server Errorsโ€‹

// โœ… Good - Retry with exponential backoff
const omise = require('omise')({ secretKey: process.env.OMISE_SECRET_KEY });

async function createChargeWithRetry(chargeData, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const charge = await omise.charges.create(chargeData);
return { success: true, charge };

} catch (error) {
const isServerError = error.statusCode >= 500;
const isLastAttempt = attempt === maxRetries - 1;

if (isServerError && !isLastAttempt) {
// Exponential backoff: 1s, 2s, 4s
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}

// Don't retry client errors or last attempt
return {
success: false,
error: {
code: error.code,
message: error.message,
statusCode: error.statusCode
}
};
}
}
}

4. Validate Before Sending Requestsโ€‹

<?php
// โœ… Good - Validate before API call

function createCharge($amount, $currency, $token) {
// Validate amount
$minAmounts = [
'thb' => 2000, // 20 THB
'jpy' => 50, // 50 JPY
'sgd' => 100, // 1 SGD
];

if ($amount < $minAmounts[$currency]) {
return [
'error' => 'Amount below minimum for ' . strtoupper($currency),
'min_amount' => $minAmounts[$currency]
];
}

// Validate currency
$supportedCurrencies = ['thb', 'jpy', 'sgd', 'myr', 'usd'];
if (!in_array($currency, $supportedCurrencies)) {
return [
'error' => 'Unsupported currency',
'supported' => $supportedCurrencies
];
}

// Validate token format
if (!preg_match('/^tokn_test_[a-z0-9]+$/', $token) &&
!preg_match('/^tokn_[a-z0-9]+$/', $token)) {
return ['error' => 'Invalid token format'];
}

try {
$charge = OmiseCharge::create([
'amount' => $amount,
'currency' => $currency,
'card' => $token
]);

return ['success' => true, 'charge' => $charge];

} catch (Exception $e) {
return [
'error' => $e->getMessage(),
'code' => $e->getCode()
];
}
}

5. Show User-Friendly Messagesโ€‹

// โœ… Good - Translate error codes to user messages
package main

import (
"github.com/omise/omise-go"
)

func getUserMessage(err error) string {
if omiseErr, ok := err.(*omise.Error); ok {
switch omiseErr.Code {
case "authentication_failure":
return "A system error occurred. Please try again later."
case "insufficient_fund":
return "Your card has insufficient funds. Please use a different card."
case "invalid_card":
return "The card details are invalid. Please check and try again."
case "stolen_or_lost_card":
return "This card cannot be used. Please contact your bank."
case "payment_cancelled":
return "Payment was cancelled. You can try again when ready."
case "payment_expired":
return "Payment session expired. Please start a new payment."
case "rate_limit_exceeded":
return "Too many attempts. Please wait a moment and try again."
case "service_unavailable":
return "Payment service is temporarily unavailable. Please try again later."
default:
return "Payment failed. Please try again or use a different payment method."
}
}
return "An unexpected error occurred. Please try again."
}

func createCharge(amount int64, currency string, token string) (string, error) {
client, _ := omise.NewClient(
os.Getenv("OMISE_PUBLIC_KEY"),
os.Getenv("OMISE_SECRET_KEY"),
)

charge, err := client.CreateCharge(&omise.ChargeParams{
Amount: amount,
Currency: currency,
Card: token,
})

if err != nil {
userMessage := getUserMessage(err)
return userMessage, err
}

return "Payment successful!", nil
}

6. Log Errors for Debuggingโ€‹

# โœ… Good - Comprehensive error logging
require 'logger'

logger = Logger.new('omise_errors.log')

begin
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: token
})

rescue Omise::Error => e
# Log detailed error information
logger.error({
timestamp: Time.now.iso8601,
error_type: 'omise_api_error',
http_status: e.http_status,
error_code: e.code,
error_message: e.message,
request_id: e.request_id,
charge_params: {
amount: 100000,
currency: 'thb',
token: token[0..10] + '...' # Partial token for security
},
backtrace: e.backtrace.first(5)
}.to_json)

# Re-raise or handle
raise
end

7. Don't Expose Sensitive Error Detailsโ€‹

// โŒ Bad - Exposes internal details
app.post('/charge', async (req, res) => {
try {
const charge = await omise.charges.create(req.body);
res.json(charge);
} catch (error) {
// DON'T DO THIS - Exposes API key, internal paths, etc.
res.status(500).json({ error: error.toString() });
}
});

// โœ… Good - Safe error messages
app.post('/charge', async (req, res) => {
try {
const charge = await omise.charges.create({
amount: req.body.amount,
currency: req.body.currency,
card: req.body.token
});
res.json({ success: true, charge_id: charge.id });

} catch (error) {
// Log full error server-side
console.error('Charge failed:', error);

// Return safe message to client
const safeMessage = {
success: false,
error: {
code: error.code || 'unknown',
message: getUserFriendlyMessage(error.code)
}
};

res.status(error.statusCode || 500).json(safeMessage);
}
});

Debugging Errorsโ€‹

1. Use Test Mode for Developmentโ€‹

Always use test API keys during development:

# โœ… Test mode - safe for debugging
export OMISE_SECRET_KEY=skey_test_5xuy4w91xqz7d1w9u0t

# Test mode errors are identical to live mode
curl https://api.omise.co/charges \
-X POST \
-u $OMISE_SECRET_KEY: \
-d "amount=100000" \
-d "currency=thb" \
-d "card=tokn_test_no1t4tnemucod0e51mo"

2. Check Request/Response in Dashboardโ€‹

  1. Go to Dashboard โ†’ Logs
  2. View all API requests and responses
  3. See exact error details
  4. Review request parameters

3. Enable Debug Loggingโ€‹

# Ruby - Enable debug logging
require 'omise'

Omise.api_key = ENV['OMISE_SECRET_KEY']
Omise.debug = true # Prints HTTP requests/responses

charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: token
})
# Python - Enable debug logging
import omise
import logging

# Enable HTTP debugging
logging.basicConfig(level=logging.DEBUG)

omise.api_secret = os.environ['OMISE_SECRET_KEY']
// Node.js - Use request interception
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

// Log all requests/responses
omise.interceptor = {
request: (config) => {
console.log('Request:', config);
return config;
},
response: (response) => {
console.log('Response:', response);
return response;
},
responseError: (error) => {
console.error('Error:', error);
throw error;
}
};

4. Test with Curlโ€‹

# Verbose output shows full HTTP exchange
curl -v https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100000" \
-d "currency=thb" \
-d "card=tokn_test_..."

# Shows:
# > POST /charges HTTP/1.1
# > Authorization: Basic ...
# > Content-Type: application/x-www-form-urlencoded
# < HTTP/1.1 200 OK
# < Content-Type: application/json

5. Common Debugging Stepsโ€‹

For Authentication Errors:

  1. โœ… Copy API key from Dashboard (don't type manually)
  2. โœ… Check for extra spaces or line breaks
  3. โœ… Verify test vs live key matches environment
  4. โœ… Ensure Authorization header format: Basic base64(key:)

For Payment Errors:

  1. โœ… Try with test card numbers first
  2. โœ… Verify card details are correct
  3. โœ… Check if card supports online payments
  4. โœ… Test with different cards to isolate issue

For Validation Errors:

  1. โœ… Read error message carefully
  2. โœ… Check API documentation for parameter requirements
  3. โœ… Verify data types (number vs string)
  4. โœ… Check minimum/maximum values

For Server Errors:

  1. โœ… Check status.omise.co
  2. โœ… Retry after a delay
  3. โœ… Contact support if persistent
  4. โœ… Save request/response for debugging

Error Handling Checklistโ€‹

Before going live, ensure your error handling:

  • Catches all API exceptions/errors
  • Checks HTTP status codes
  • Parses error codes for specific handling
  • Shows user-friendly error messages
  • Logs errors with full context (server-side only)
  • Implements retry logic for server errors
  • Uses exponential backoff for retries
  • Doesn't retry payment failures
  • Validates requests before sending
  • Doesn't expose sensitive error details to users
  • Handles network timeouts
  • Has fallback for service unavailability
  • Monitors error rates
  • Alerts on unusual error patterns
  • Tests error scenarios in development

Testing Error Scenariosโ€‹

Test Authentication Errorsโ€‹

# Invalid API key
curl https://api.omise.co/account \
-u invalid_key:
# Returns 401 authentication_failure

# Wrong key type
curl https://api.omise.co/charges \
-X POST \
-u pkey_test_...: \
-d "amount=100000"
# Returns 401 authentication_failure

Test Validation Errorsโ€‹

# Amount too small
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100" \
-d "currency=thb"
# Returns 400 bad_request

# Invalid currency
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100000" \
-d "currency=invalid"
# Returns 400 bad_request

Test Payment Errorsโ€‹

Use special test cards that trigger specific errors:

# Insufficient funds
curl https://vault.omise.co/tokens \
-X POST \
-u pkey_test_...: \
-d "card[number]=4111111111111111" \
-d "card[name]=Test User" \
-d "card[expiration_month]=12" \
-d "card[expiration_year]=2025" \
-d "card[security_code]=123"
# Use token in charge - will decline with insufficient_fund

# Failed processing
curl https://vault.omise.co/tokens \
-X POST \
-u pkey_test_...: \
-d "card[number]=4000000000000002" \
-d "card[name]=Test User" \
-d "card[expiration_month]=12" \
-d "card[expiration_year]=2025" \
-d "card[security_code]=123"
# Use token in charge - will decline with failed_processing

View all test cards โ†’


FAQโ€‹

Should I retry failed payments automatically?

No, don't automatically retry payment failures (4xx errors). Repeatedly attempting declined cards can:

  • Trigger fraud alerts
  • Get cards blocked by issuers
  • Frustrate customers

Instead:

  • Show clear error message
  • Ask customer to verify payment details
  • Suggest alternative payment method
  • Let customer manually retry when ready

You can retry server errors (5xx) with exponential backoff.

How do I know if a charge failed?

Check the HTTP status code and charge status:

Success:

  • HTTP 200 OK
  • charge.status = "successful" (captured)
  • charge.status = "pending" (authorized, not captured yet)

Failure:

  • HTTP 402 Payment Required
  • Error response with code like payment_declined
  • charge.status = "failed" or "expired"
What's the difference between 4xx and 5xx errors?

4xx = Client Errors (your fault)

  • Your request was invalid
  • Fix the request and retry
  • Examples: bad parameters, declined payment, invalid auth

5xx = Server Errors (our fault)

  • Something went wrong on Omise's side
  • Request was valid, but couldn't be processed
  • Retry with backoff
  • Examples: service down, internal error
How long should I wait before retrying?

Use exponential backoff:

  1. First retry: Wait 1 second
  2. Second retry: Wait 2 seconds
  3. Third retry: Wait 4 seconds
  4. Fourth retry: Wait 8 seconds
  5. Give up after 3-5 attempts
async function retryWithBackoff(fn, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
if (error.statusCode < 500 || attempt === maxAttempts - 1) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
Can I get more details about payment failures?

Payment failure reasons are intentionally limited for security. Card issuers don't always provide specific decline reasons to prevent fraud.

What you get:

  • โœ… High-level error code (insufficient_fund, invalid_card)
  • โœ… Generic error message

What you don't get:

  • โŒ Exact card balance
  • โŒ Specific fraud flags
  • โŒ Internal bank codes

This protects cardholders from attackers testing stolen cards.


Quick Referenceโ€‹

Error Response Structureโ€‹

{
"object": "error",
"location": "https://www.omise.co/api-errors#<error-code>",
"code": "<error_code>",
"message": "<human-readable message>"
}

Common Status Codesโ€‹

StatusMeaningAction
200SuccessProcess response
400Bad RequestFix parameters
401UnauthorizedFix API key
402Payment FailedShow error, don't retry
404Not FoundVerify resource ID
422Invalid StateCheck resource state
429Rate LimitedImplement backoff
500Server ErrorRetry with backoff
503Service DownRetry later

Error Handling Patternโ€‹

1. Try API request
2. Catch error
3. Check HTTP status
4. Parse error code
5. Log error (server-side)
6. Show user message (safe)
7. Retry only if 5xx
8. Monitor error rates


Next: Learn about Pagination to handle large result sets efficiently.