Skip to content

Error Handling

This guide explains how to handle errors when integrating with FLUID Network's API, including error code ranges, response structures, retry strategies, and best practices.

Error Response Structure

All API errors return a consistent JSON structure:

json
{
  "error": {
    "code": 3009,
    "message": "Insufficient funds",
    "category": "accounts",
    "details": {
      "transaction_id": "txn_1234567890",
      "available_balance": 5000,
      "requested_amount": 10000
    }
  }
}

Response Fields

FieldTypeDescription
codeintegerNumeric error code (see ranges below)
messagestringHuman-readable error message
categorystringError category for grouping
detailsobjectAdditional context (optional)

Error Code Ranges

FLUID Network uses structured error code ranges to categorize errors:

Range Overview

RangeCategoryDescriptionTypical Cause
1000-1999GeneralApplication-wide errorsInvalid requests, auth failures, rate limits
2000-2999IntegrationExternal service errorsBank API issues, connector failures, timeouts
3000-3999TransactionsTransaction processingValidation, duplicate references, insufficient funds
4000-4999WebhooksWebhook deliverySignature validation, delivery failures, timeouts
5000-5999SettlementsSettlement processingBatch errors, invalid currencies, empty batches

General Errors (1000-1999)

HTTP-Like Errors (1400-1499)

Standard HTTP status code equivalents:

CodeErrorHTTP StatusDescriptionAction
1400Bad Request400Invalid request format or parametersFix request structure
1401Unauthorized401Missing or invalid API keyCheck authentication
1403Forbidden403Insufficient permissionsVerify authorization
1404Not Found404Resource doesn't existCheck resource ID
1405Method Not Allowed405HTTP method not supportedUse correct method
1409Conflict409Request conflicts with current stateResolve conflict
1422Invalid Record422Validation failed on modelFix validation errors
1429Too Many Requests429Rate limit exceededImplement backoff
1500Internal Server Error500Unexpected server errorRetry with backoff
1503Service Unavailable503Service temporarily downWait and retry

Security Errors (1450-1499)

Authentication and authorization failures:

CodeErrorSeverityDescriptionAction
1451IP BlockedHighIP not whitelistedAdd IP to whitelist
1452IP Validation FailedMediumIP format invalidCheck IP address
1453Rate Limit by IPMediumToo many requests from IPImplement backoff
1454Rate Limit by PartnerMediumPartner quota exceededUpgrade plan or wait
1455Rate Limit by BankMediumBank quota exceededContact support
1456Payment Rate LimitHighPayment processing limit hitCritical: implement backoff

HMAC Authentication Errors (1401)

HMAC signature validation failures:

CodeErrorDescriptionAction
1401Signature MissingNo HMAC signature headerInclude signature
1401Signature InvalidSignature doesn't matchCheck secret key
1401Timestamp ExpiredRequest too old (>5 min)Send fresh request
1400Timestamp InvalidTimestamp format wrongUse Unix timestamp
1401Timestamp MissingNo timestamp headerInclude timestamp

Example: Handling Authentication Errors

When handling authentication errors, implement logic to:

Code 1401 (Unauthorized):

  • Check if API key is correct for your environment
  • Verify Authorization header format: Bearer {api_key}
  • For HMAC authentication: verify signature, timestamp, and secret key
  • Ensure timestamp is within 5 minutes of current time

Code 1403 (Forbidden):

  • Verify account permissions and status
  • Check if feature is enabled for your plan
  • Contact support if permissions issue persists

Rate Limit Errors (1429, 1453-1456):

  • Implement exponential backoff retry strategy
  • Log rate limit warnings for monitoring
  • Consider implementing request queue to smooth traffic
  • Upgrade plan if consistently hitting limits

Integration Errors (2000-2999)

Connector Errors (2001-2099)

Bank integration and connector failures:

CodeErrorDescriptionRetry?Action
2001Bank Connector ErrorGeneric connector failureYesRetry with backoff
2002Bank API ErrorBank API returned errorDependsCheck error details
2003No Connector AvailableBank not supportedNoUse different bank

Upstream Errors (2400-2599)

External service communication issues:

CodeErrorDescriptionRetry?Action
2408Upstream TimeoutRequest to bank timed outYesRetry with longer timeout
2500Upstream ErrorBank service errorYesRetry with backoff
2502Connection FailedCannot connect to bankYesCheck connectivity

Example: Handling Integration Errors

When initiating transactions, implement retry logic for integration errors:

Retry Strategy:

  • Maximum 3 retry attempts recommended
  • Use exponential backoff: 1s, 2s, 4s delays
  • Check if error code is retryable before retrying
  • Stop immediately for non-retryable errors

Retryable Integration Errors:

  • 2001 - Bank Connector Error (temporary connector issue)
  • 2002 - Bank API Error (may succeed on retry depending on details)
  • 2408 - Upstream Timeout (retry with longer timeout)
  • 2500 - Upstream Error (temporary bank service issue)
  • 2502 - Connection Failed (network connectivity issue)

Implementation Approach:

  1. Attempt API call
  2. On error, extract error code from response
  3. Check if error code is in retryable list
  4. If retryable and under max attempts: wait with exponential backoff, then retry
  5. If non-retryable or max attempts reached: throw error permanently

Backoff Calculation:

  • Attempt 1 delay: 1000ms (2^0 * 1000)
  • Attempt 2 delay: 2000ms (2^1 * 1000)
  • Attempt 3 delay: 4000ms (2^2 * 1000)
  • Cap maximum delay at 30 seconds

Transaction Errors (3000-3999)

Processing Errors (3001-3099)

Transaction state and validation issues:

CodeErrorDescriptionAction
3001Invalid Status TransitionCannot change to requested statusCheck current status
3002Invalid Approval MethodApproval method not allowedUse valid method
3003Duplicate Referencepartner_reference already usedUse unique reference
3004Invalid CurrencyCurrency not supportedUse GHS
3005Limit ExceededAmount exceeds transaction limitReduce amount
3006Already ProcessedTransaction already completedCheck status
3007Invalid AmountAmount format or value invalidValidate amount
3008Account InactiveCustomer account not activeContact support
3009Insufficient FundsCustomer lacks sufficient balanceNotify customer

Resource Errors (3400+)

CodeErrorDescriptionAction
3404Transaction Not FoundTransaction ID doesn't existVerify ID

Example: Handling Transaction Errors

Implement specific handling for transaction validation and processing errors:

Code 3003 (Duplicate Reference):

  • Transaction with this partner_reference already exists
  • Query existing transaction by reference
  • Return existing transaction instead of creating duplicate
  • This is idempotency in action - safe to return existing result

Code 3004 (Invalid Currency):

  • Currency code not supported by FLUID Network
  • Valid currency: GHS (Ghana Cedis)
  • Display error to user with supported currency
  • Do not retry - this is a permanent validation error

Code 3007 (Invalid Amount):

  • Amount format or value is invalid
  • Amount must be positive integer in smallest currency unit (pesewas)
  • Example: 50.00 GHS = 5000 pesewas
  • Check for negative values, zero, or non-integer values

Code 3008 (Account Inactive):

  • Customer's bank account is not active
  • Notify customer to activate their account
  • Contact customer support if issue persists
  • Do not retry automatically - requires customer action

Code 3009 (Insufficient Funds):

  • Customer lacks sufficient balance in their account
  • Extract available balance from error details if provided
  • Display friendly message: "Insufficient funds. Please add money and try again."
  • Notify customer with available vs. requested amount
  • Allow customer to retry after adding funds

Webhook Errors (4000-4999)

Delivery Errors (4001-4099)

Webhook sending and receiving issues:

CodeErrorDescriptionAction
4001Delivery FailedHTTP error from your endpointFix endpoint
4408TimeoutYour endpoint didn't respond in 5sOptimize response time

Configuration Errors (4400+)

CodeErrorDescriptionAction
4400Invalid PayloadWebhook payload malformedContact support
4401Signature InvalidHMAC signature mismatchCheck webhook secret
4403Not SubscribedEvent type not enabledEnable event
4404Not ConfiguredNo webhook URL setSet webhook URL

Example: Webhook Error Monitoring

Implement monitoring to track webhook delivery health:

Code 4001 (Delivery Failed):

  • Webhook delivery to your endpoint returned HTTP error
  • Check your endpoint health and availability
  • Verify endpoint URL is correct and accessible
  • Review server logs for request handling errors

Code 4408 (Timeout):

  • Your endpoint didn't respond within 5 seconds
  • Optimize webhook endpoint response time
  • Acknowledge webhook immediately (return 200 OK)
  • Process webhook payload asynchronously in background job

Code 4401 (Signature Invalid):

  • HMAC signature verification failed
  • Verify webhook secret configuration matches FLUID Network dashboard
  • Check signature calculation algorithm and header format

Monitoring Strategy:

  • Track webhook failure rates per event type
  • Alert if overall failure rate exceeds 5%
  • Alert if authentication error rate exceeds 1%
  • Run health checks every 5 minutes
  • Log webhook delivery failures with context (error code, event type, attempt count)

Settlement Errors (5000-5999)

Batch Processing Errors (5001-5099)

Settlement batch issues:

CodeErrorDescriptionAction
5001Batch Not ProcessableBatch in invalid stateCheck batch status
5002Empty BatchNo transactions to settleVerify transactions
5003Invalid CurrencyCurrency not supportedUse valid currency
5004Invalid Transaction TypeWrong transaction in batchVerify transaction types
5005Already ProcessedBatch already settledCheck batch status

Resource Errors (5400+)

CodeErrorDescriptionAction
5404Batch Not FoundSettlement batch doesn't existVerify batch ID

Error Handling Best Practices

1. Categorize Errors by Retryability

Classify errors into retryable and permanent categories:

Retryable Errors (temporary failures - safe to retry):

  • 1429 - Rate limit exceeded
  • 1453, 1454, 1455, 1456 - Various rate limit errors
  • 1500 - Internal server error
  • 1503 - Service unavailable
  • 2001, 2002 - Connector errors
  • 2408, 2500, 2502 - Upstream communication errors
  • 4001, 4408 - Webhook delivery issues

Permanent Errors (won't succeed on retry - fix required):

  • 1401 - Unauthorized (invalid credentials)
  • 1403 - Forbidden (insufficient permissions)
  • 1404 - Not found (resource doesn't exist)
  • 3003 - Duplicate reference (already processed)
  • 3004 - Invalid currency (unsupported currency)
  • 3007 - Invalid amount (validation failure)
  • 3008 - Account inactive (requires customer action)
  • 3009 - Insufficient funds (requires customer action)

Implementation: Check error code against retryable list before implementing retry logic.

2. Implement Exponential Backoff

Use exponential backoff for retrying failed requests:

Retry Strategy:

  • Maximum 3 retry attempts recommended
  • Base delay: 1000ms (1 second)
  • Exponential growth: delay = 1000ms × 2^(attempt - 1)
  • Add random jitter (0-1000ms) to prevent thundering herd
  • Cap maximum delay at 30 seconds

Delay Calculation:

  • Attempt 1: 1000ms + jitter
  • Attempt 2: 2000ms + jitter
  • Attempt 3: 4000ms + jitter

Logic Flow:

  1. Attempt API call
  2. On error, extract error code from response
  3. Check if error code is retryable (skip retry for permanent errors)
  4. If retryable and under max attempts: calculate delay, wait, retry
  5. If non-retryable or max attempts reached: throw error permanently

Important: Never retry permanent errors (authentication failures, validation errors, resource not found).

3. Log Errors with Context

Implement comprehensive error logging with contextual information:

Log Entry Structure:

  • Timestamp (ISO 8601 format)
  • Error code and message from API response
  • Error category (authentication, transactions, integration, etc.)
  • HTTP status code
  • Request context:
    • Transaction ID
    • Partner reference
    • Amount and currency
    • Phone number (masked for privacy - only show last 4 digits)
  • Stack trace for debugging

Logging Levels:

  • Error: All API errors
  • Critical: Errors with high severity (codes 1500, 2500, or flagged as high severity)
  • Warning: Rate limit warnings, retryable errors

Privacy Considerations:

  • Mask sensitive data (phone numbers, account numbers)
  • Never log full API keys or secrets
  • Use last 4 digits or character masking (e.g., +233200****002)

Alerting:

  • Send critical alerts for:
    • High severity errors (1500, 2500)
    • Authentication failures (1401, 1403)
    • Sustained rate limiting (1429, 145x)
  • Include full context in alerts for faster incident response

4. Provide User-Friendly Messages

Map technical error codes to customer-facing messages:

Error Message Principles:

  • Use clear, non-technical language
  • Provide actionable guidance when possible
  • Avoid exposing internal technical details
  • Be empathetic and helpful in tone

Common User-Facing Messages:

Error CodeUser-Friendly Message
1401"We couldn't process your request. Please try again."
1429"Too many requests. Please wait a moment and try again."
1456"High transaction volume. Please try again in a few minutes."
3003"This transaction has already been processed."
3004"The selected currency is not supported."
3007"The amount entered is invalid. Please check and try again."
3008"Your account is inactive. Please contact support."
3009"Insufficient funds. Please add money to your account and try again."
2001"We're experiencing technical difficulties. Please try again later."
2408"The request timed out. Please try again."
2502"Unable to connect to payment service. Please try again."
Default"An unexpected error occurred. Please try again or contact support."

Implementation Pattern:

  1. Extract error code from API response
  2. Map error code to user-friendly message
  3. Display message to user in UI
  4. Log technical error details separately for debugging

5. Monitor Error Rates

Track error metrics to proactively identify integration issues:

Key Metrics to Monitor:

  • Overall error rate (errors per total requests)
  • Error rate by category (authentication, transactions, integration, webhooks, settlements)
  • Error rate by specific error code
  • Error rate over time windows (last 1 minute, 5 minutes, 15 minutes, 1 hour)

Alerting Thresholds:

  • High Priority: Overall error rate exceeds 5%
  • Critical: Authentication error rate exceeds 1%
  • Warning: Specific error code appears more than 10 times per minute
  • Critical: Integration errors (2xxx) exceed 3% of requests

Monitoring Implementation:

  1. Record each error with: error code, category, timestamp
  2. Calculate error rates over sliding time windows
  3. Group errors by category for targeted analysis
  4. Trigger alerts when thresholds are exceeded
  5. Track total requests for accurate rate calculation

Dashboard Metrics:

  • Error count by category (pie chart)
  • Error rate over time (line chart)
  • Top 10 error codes by frequency (bar chart)
  • Recent error log with context

Best Practices:

  • Review error dashboards daily
  • Set up real-time alerts for critical thresholds
  • Investigate sudden spikes in error rates immediately
  • Track error rate trends to identify degradation over time

Testing Error Scenarios

Sandbox Error Simulation

Use FLUID Network sandbox environment with specific test data to trigger errors:

Test Insufficient Funds Error (3009):

  • Use very large amount (e.g., 999999999 pesewas)
  • Use sandbox test phone number: +233200000002
  • Expected response: Error code 3009 with insufficient funds message

Test Invalid Currency Error (3004):

  • Use invalid currency code (e.g., ZZZ)
  • Expected response: Error code 3004 with invalid currency message

Test Duplicate Reference Error (3003):

  • Create transaction with specific partner_reference
  • Attempt to create another transaction with same partner_reference
  • Expected response: First succeeds, second returns error code 3003

Sandbox Test Phone Numbers:

  • +233200000001 - Successful transactions
  • +233200000002 - Insufficient funds error
  • +233200000003 - Account inactive error
  • +233200000004 - Invalid account error

Error Handling Test Suite

Implement comprehensive tests for error handling logic:

Test Cases to Include:

  1. Retry on Transient Errors:

    • Mock API to return error code 1500 (internal server error) twice, then succeed
    • Verify retry logic attempts request 3 times total
    • Verify final result is successful response
  2. No Retry on Permanent Errors:

    • Mock API to return error code 3009 (insufficient funds)
    • Verify retry logic throws error immediately
    • Verify only 1 API attempt is made (no retries)
  3. Log Errors with Context:

    • Mock API to return error code 3007 (invalid amount)
    • Verify error logging function is called with correct parameters
    • Verify log entry contains error code, category, and request context
  4. Exponential Backoff Timing:

    • Mock API to fail with retryable error
    • Measure delay between retry attempts
    • Verify delays follow exponential pattern: ~1s, ~2s, ~4s
  5. User-Friendly Messages:

    • Test error code to user message mapping
    • Verify all error codes have appropriate messages
    • Verify default message for unknown error codes

Testing Tools:

  • Use HTTP mocking libraries to simulate API responses
  • Mock error responses with proper structure (code, message, category, details)
  • Use timing assertions to verify backoff delays
  • Test both successful and failed retry scenarios

Quick Reference

Error Decision Tree

Error Received

Is code 1xxx?
    ↓ Yes → Authentication/Rate limit issue
    ├─ 1401? → Check API key/signature
    ├─ 1429/145x? → Implement backoff
    └─ 1500/1503? → Retry with backoff
    ↓ No
Is code 2xxx?
    ↓ Yes → Integration issue
    ├─ 2001/2002? → Retry with backoff
    ├─ 2408/250x? → Retry with longer timeout
    └─ 2003? → Bank not supported (permanent)
    ↓ No
Is code 3xxx?
    ↓ Yes → Transaction issue
    ├─ 3003? → Duplicate (check existing)
    ├─ 3009? → Insufficient funds (notify user)
    └─ 3004/3007? → Validation error (fix input)
    ↓ No
Is code 4xxx?
    ↓ Yes → Webhook issue
    ├─ 4001/4408? → Fix webhook endpoint
    └─ 4401? → Check webhook secret
    ↓ No
Is code 5xxx?
    ↓ Yes → Settlement issue
    └─ Contact support

Support

If you encounter errors not covered in this guide: