Skip to content

Error Codes Reference

Complete reference for all error codes in the FLUID Network API. Use this guide to understand, handle, and troubleshoot errors in your integration.

Error Code Ranges

FLUID Network uses structured error codes organized by category:

RangeCategoryDescription
1000-1999General ApplicationAuthentication, validation, rate limiting, HTTP errors
2000-2999Integration/ConnectorBank connector, upstream service errors
3000-3999Transaction ProcessingTransaction lifecycle, status, and validation errors
4000-4999Webhook/NotificationWebhook delivery and subscription errors
5000-5999Settlement/BatchSettlement batch processing errors

Error Response Format

All API errors follow this structure:

json
{
  "success": false,
  "error": {
    "code": 3009,
    "message": "Insufficient funds",
    "category": "accounts",
    "details": {
      "transaction_id": "txn_abc123",
      "account_number": "024XXXXXXXX"
    }
  }
}

General Application Errors (1000-1999)

Core Application Errors

CodeMessageCategoryDescriptionHTTP Status
1000An unexpected error occurredgeneralUnknown server error - contact support if persists500
1007Validation failedvalidationRequest validation failed - check error details422

HTTP Request Errors (1400-1499)

CodeMessageCategoryDescriptionHTTP Status
1400Bad requestrequestMalformed request syntax or invalid parameters400
1401UnauthorizedauthenticationMissing or invalid authentication credentials401
1403ForbiddenauthorizationAuthenticated but insufficient permissions403
1404Resource not foundgeneralRequested resource does not exist404
1405Method not allowedrequestHTTP method not supported for this endpoint405
1409Request conflicts with current stategeneralResource state conflict (e.g., duplicate operation)409
1422Invalid recordvalidationActiveRecord validation failed422
1429Too many requestsrate_limitingRate limit exceeded - retry after cooldown429
1500Internal server errorgeneralUnexpected server error500
1503Service temporarily unavailableavailabilityService is down for maintenance or overloaded503

Security Errors (1450-1499)

CodeMessageCategorySeverityDescriptionHTTP Status
1451IP address not authorizedsecurityhighYour IP is not whitelisted for this partner403
1452IP address validation failedsecuritymediumIP validation check failed403
1453Rate limit exceeded for IP addresssecuritymediumToo many requests from your IP429
1454Rate limit exceeded for payment partnersecuritymediumPartner-level rate limit exceeded429
1455Rate limit exceeded for banksecuritymediumBank-level rate limit exceeded429
1456Payment processing rate limit exceededsecurityhighCritical payment processing limit hit429

Rate Limiting Response: When you receive rate limit errors (1453-1456), implement exponential backoff. See Rate Limiting Guide for details.

HMAC Authentication Errors (1400-1499)

CodeMessageCategorySeverityDescriptionHTTP Status
1401HMAC signature requiredauthenticationhighMissing X-Signature header401
1401Invalid HMAC signatureauthenticationhighSignature verification failed - check secret key401
1401Request timestamp expiredauthenticationhighTimestamp older than 5 minutes (replay protection)401
1401Request timestamp requiredauthenticationhighMissing X-Timestamp header401
1400Invalid timestamp formatvalidationmediumTimestamp must be Unix epoch (seconds)400

HMAC Signature Debugging: If you receive signature errors, verify:

  1. You're using the correct secret key from the dashboard
  2. The signature string is built correctly: method + path + timestamp + body
  3. The timestamp matches what you sent in X-Timestamp
  4. Request body is sent as raw JSON (not form-encoded)

See HMAC Authentication Guide for implementation examples.

Integration/Connector Errors (2000-2999)

CodeMessageCategoryDescriptionHTTP StatusRetry?
2001Bank connector errorconnectorsBank integration layer error502Yes (exponential backoff)
2002Bank API errorconnectorsBank's API returned an error502Depends on bank error
2003No connector available for bankconnectorsBank integration not configured503No
2408Upstream service timeoutconnectorsBank/upstream service timed out504Yes (after delay)
2500Upstream service errorconnectorsUpstream service returned error502Yes (exponential backoff)
2502Upstream connection failedconnectorsCannot connect to upstream service502Yes (exponential backoff)

Connector Errors: Connector errors (2xxx) indicate issues with bank integrations or upstream services. These are typically transient:

  • Retry strategy: Exponential backoff (1s, 2s, 4s, 8s)
  • Max retries: 3 attempts

For persistent errors, contact support with the transaction ID.

Transaction Processing Errors (3000-3999)

CodeMessageCategoryDescriptionHTTP StatusAction Required
3001Invalid status transitiontransactionsCannot transition between these statuses400Check current transaction status
3002Invalid approval methodtransactionsApproval method not supported for this transaction400Use supported approval method
3003Duplicate transaction referencetransactionsTransaction with this reference already exists409Use unique reference or retrieve existing
3004Unsupported currencytransactionsCurrency not supported (must be GHS)400Use GHS only
3005Transaction limit exceededtransactionsAmount exceeds configured limits400Check partner limits in dashboard
3006Transaction already processedtransactionsTransaction is already complete/failed409Check transaction status
3007Invalid transaction amounttransactionsAmount is zero, negative, or exceeds max400Validate amount (min: 1.00)
3008Account is inactiveaccountsCustomer account is inactive/blocked400Verify account status with bank
3009Insufficient fundsaccountsCustomer account has insufficient balance400Customer needs to fund account
3404Transaction not foundtransactionsTransaction ID does not exist404Verify transaction ID

Idempotency: When you receive error 3003 (duplicate reference), your transaction may already be processing. Always:

  1. Use the same reference for retries of the same payment
  2. Call GET /debit-requests/:reference to check status before retrying
  3. Never create new references for the same payment

See Idempotency Guide for best practices.

Transaction Status Transitions

Valid status transitions (violating these causes error 3001):

See Status Codes Reference for complete status definitions.

Webhook/Notification Errors (4000-4999)

CodeMessageCategoryDescriptionHTTP StatusAction Required
4001Webhook delivery failedwebhooksFailed to deliver webhook to your URL502Ensure endpoint returns 200
4400Invalid webhook payloadwebhooksWebhook payload validation failed400Check webhook signature/payload
4401Invalid webhook signaturewebhooksWebhook signature verification failed401Verify using webhook secret
4403Partner not subscribed to eventwebhooksYou're not subscribed to this event type403Enable event in dashboard
4404Webhook not configured for partnerwebhooksNo webhook URL configured404Configure webhook URL in dashboard
4408Webhook delivery timeoutwebhooksYour webhook endpoint timed out (>30s)408Optimize webhook handler

Webhook Best Practices: To avoid webhook errors:

  • Return 200 quickly: Process webhooks asynchronously (queue for background processing)
  • Verify signatures: Always validate X-Signature header before processing
  • Handle retries: Webhooks retry up to 5 times with exponential backoff
  • Idempotent handling: Use event_id to deduplicate webhook events

See Webhook Overview for implementation guide.

Settlement/Batch Errors (5000-5999)

CodeMessageCategoryDescriptionHTTP StatusAction Required
5001Settlement batch cannot be processedsettlementsBatch is in invalid state for processing400Check batch status
5002No transactions to settlesettlementsBatch contains no eligible transactions400Verify transactions in batch
5003Settlement currency not supportedsettlementsCurrency not supported for settlements400Use GHS only
5004Settlement line item transaction type invalidsettlementsTransaction type cannot be settled400Only debit transactions can be settled
5005Settlement batch already processedsettlementsBatch has already been processed409Check batch status
5404Settlement batch not foundsettlementsBatch ID does not exist404Verify batch ID

Error Handling Patterns

Pattern 1: Basic Error Handling

When making API requests, implement error handling that:

  1. Catches HTTP errors from the API response
  2. Extracts error details from the response body (code, message, category)
  3. Handles specific error codes with appropriate logic:
    • 3009 (Insufficient funds): Notify customer to fund their account
    • 3003 (Duplicate reference): Check existing transaction status instead of creating new one
    • 1429 (Rate limit): Wait briefly and retry the request
  4. Logs error information for debugging and monitoring
  5. Propagates unhandled errors to higher-level error handlers

Implementation approach:

  • Use try-catch blocks around API calls
  • Check if error response contains structured error data
  • Use switch/case or if-else to handle specific error codes
  • Implement appropriate recovery actions for each error type

Pattern 2: Retry Logic with Exponential Backoff

For transient errors (network issues, rate limits, temporary service unavailability), implement retry logic with exponential backoff:

Key implementation steps:

  1. Attempt the API call and catch errors
  2. Identify retryable errors by checking error codes:
    • 2001, 2002, 2408, 2500, 2502 (connector/integration errors)
    • 1429 (rate limiting)
  3. Calculate delay using exponential backoff formula: base_delay * (2 ^ attempt_number)
    • Attempt 0: 1 second
    • Attempt 1: 2 seconds
    • Attempt 2: 4 seconds
  4. Wait for the delay before retrying
  5. Limit total retry attempts (recommended: 3 retries maximum)
  6. Throw error if all retries are exhausted

Logic flow:

for each attempt (0 to max_retries):
  try:
    execute API call
    return successful result
  catch error:
    if error is not retryable:
      throw error immediately
    if last attempt:
      throw error (no more retries)
    calculate delay = base * (2 ^ attempt)
    wait for delay
    continue to next attempt

This pattern prevents overwhelming the API during temporary outages while giving enough time for services to recover.

Pattern 3: Handling Validation Errors

When validation fails (error codes 1007 or 1422), the error response includes field-specific validation details in the details object.

Error response structure for validation errors:

json
{
  "success": false,
  "error": {
    "code": 1007,
    "message": "Validation failed",
    "category": "validation",
    "details": {
      "amount": ["must be greater than 0"],
      "currency": ["must be GHS"],
      "phone_number": ["is required"]
    }
  }
}

Handling approach:

  1. Check error code for 1007 (validation failed) or 1422 (invalid record)
  2. Extract field errors from the details object
  3. Iterate through field errors to display user-friendly messages
  4. Map to UI fields if showing errors in a form
  5. Log validation errors for debugging incorrect API usage

This allows you to show specific validation errors for each field rather than a generic "validation failed" message.

Troubleshooting Guide

Authentication Issues

Problem: Receiving error 1401 (Unauthorized)

Solutions:

  1. Verify API key is correct and active in dashboard
  2. Check Authorization: Bearer YOUR_API_KEY header format
  3. Ensure you're using the correct environment (sandbox vs production)
  4. Confirm API key has necessary permissions for the endpoint

Problem: HMAC signature errors (1401 - Invalid HMAC signature)

Solutions:

  1. Verify signature string construction: METHOD + PATH + TIMESTAMP + BODY
  2. Ensure timestamp in signature matches X-Timestamp header
  3. Check timestamp is recent (within 5 minutes)
  4. Use raw JSON body (not form-encoded) in signature
  5. Verify you're using correct webhook secret from dashboard

See HMAC Authentication for detailed debugging steps.

Rate Limiting

Problem: Error 1429 or 1453-1456 (Rate limit exceeded)

Solutions:

  1. Implement exponential backoff (see examples above)
  2. Cache transaction status queries instead of polling frequently
  3. Use webhooks instead of polling for status updates
  4. Contact support to discuss higher rate limits

Rate Limits:

  • Payment Providers API: 1000 requests/minute per partner
  • Banks API: 200 requests/minute per bank

Transaction Processing

Problem: Error 3003 (Duplicate transaction reference)

Solutions:

  1. DO NOT create a new reference and retry
  2. Use GET /debit-requests/:reference to check existing transaction status
  3. If status is failed, you can retry with the same reference
  4. Implement idempotency correctly - see Idempotency Guide

Problem: Error 3009 (Insufficient funds)

Solutions:

  1. This is a customer-side issue - notify customer to fund account
  2. Implement graceful error messaging in your UI
  3. Consider implementing retry logic that allows customer to retry after funding

Problem: Error 3004 (Unsupported currency)

Solutions:

  1. FLUID Network currently only supports GHS (Ghana)
  2. Verify currency is set to "GHS" in all requests
  3. See Currency Codes Reference

Connector/Bank Errors

Problem: Errors 2001, 2002, 2408, 2500, 2502

Solutions:

  1. These are typically transient - implement retry with exponential backoff
  2. If persistent (>5 minutes), contact support with transaction ID
  3. Consider implementing fallback notification to customer

Webhook Issues

Problem: Error 4001 (Webhook delivery failed)

Solutions:

  1. Ensure webhook endpoint is publicly accessible (not localhost)
  2. Endpoint must return HTTP 200 status code
  3. Respond within 30 seconds (queue long-running tasks)
  4. Check firewall/security rules aren't blocking FLUID IPs

Problem: Error 4401 (Invalid webhook signature)

Solutions:

  1. Verify signature using webhook secret from dashboard
  2. Use raw request body (don't parse before verifying)
  3. Check you're using correct signature algorithm (HMAC-SHA256)
  4. See Signature Verification

Best Practices

1. Always Use Structured Error Handling

✅ Correct approach: Handle errors by checking the numeric error code from the API response. Error codes are stable and won't change between API versions.

❌ Incorrect approach: Don't parse or match error message text strings. Error messages may be updated for clarity without notice, which would break string-based error handling.

Why: Error codes provide a stable contract for error handling, while message text is meant for human readability and may evolve over time.

2. Implement Retry Logic for Transient Errors

Retry these error codes with exponential backoff:

  • 2001-2999: Connector/integration errors
  • 1429: Rate limiting errors
  • 1503: Service unavailable

3. Log Error Details for Debugging

Always log:

  • Error code
  • Error message
  • Transaction ID (if applicable)
  • Request ID (from X-Request-ID response header)
  • Timestamp

4. Use Webhooks Instead of Polling

Polling for transaction status can cause rate limiting. Use webhooks for real-time updates:

  • Subscribe to debit_request.completed and debit_request.failed events
  • See Webhooks Overview

5. Implement Idempotency Correctly

  • Use same reference for retries of the same payment
  • Check transaction status before retrying on errors
  • See Idempotency Guide

Support

If you encounter errors not covered in this guide:

  1. Review Error Handling Guide for patterns
  2. Contact support with:
    • Error code
    • Transaction ID or Reference
    • Request ID (from X-Request-ID header)
    • Timestamp of occurrence