Error Codes#

Complete reference of API error codes and their meanings.

Error Response Format#

GraphQL#

{
  "data": null,
  "errors": [
    {
      "message": "Descriptive error message",
      "locations": [{"line": 2, "column": 3}],
      "path": ["mutationName"],
      "extensions": {
        "code": "ERROR_CODE",
        "http": {"status": 400}
      }
    }
  ]
}

REST#

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Descriptive error message",
    "details": {
      "field": "additional_context"
    }
  }
}

Authentication Errors#

UNAUTHORIZED#

HTTP Status: 401

Missing or invalid authentication credentials.

{
  "code": "UNAUTHORIZED",
  "message": "Invalid or missing API key"
}

Solutions:

  • Check API key is included in Authorization header
  • Verify API key is valid and not expired
  • Ensure correct format: Bearer YOUR_API_KEY

FORBIDDEN#

HTTP Status: 403

Valid credentials but insufficient permissions.

{
  "code": "FORBIDDEN",
  "message": "API key does not have permission to access this resource"
}

Solutions:

  • Check API key scopes
  • Verify application ID matches
  • Contact admin for permission upgrade

APP_ID_REQUIRED#

HTTP Status: 400

Missing application ID header.

{
  "code": "APP_ID_REQUIRED",
  "message": "X-Outeract-App-ID header is required"
}

Solution: Include X-Outeract-App-ID header with your application UUID.

Resource Errors#

NOT_FOUND#

HTTP Status: 404

Requested resource does not exist.

{
  "code": "NOT_FOUND",
  "message": "Platform connection not found",
  "details": {
    "resource_type": "PlatformConnection",
    "resource_id": "pc_invalid123"
  }
}

Solutions:

  • Verify resource ID is correct
  • Check resource exists in your application
  • Ensure you have access to the resource

RESOURCE_EXISTS#

HTTP Status: 409

Attempting to create a resource that already exists.

{
  "code": "RESOURCE_EXISTS",
  "message": "Platform user already exists",
  "details": {
    "external_id": "+14155551234",
    "platform_connection_id": "pc_abc123"
  }
}

Solution: Use the existing resource or update instead of create.

Validation Errors#

VALIDATION_ERROR#

HTTP Status: 400

Request parameters failed validation.

{
  "code": "VALIDATION_ERROR",
  "message": "Invalid request parameters",
  "details": {
    "errors": [
      {
        "field": "to_external_id",
        "message": "Invalid phone number format"
      }
    ]
  }
}

Solutions:

  • Review field requirements in API documentation
  • Check data types and formats
  • Validate input before sending

SCHEMA_VALIDATION_ERROR#

HTTP Status: 400

Event payload doesn’t match schema.

{
  "code": "SCHEMA_VALIDATION_ERROR",
  "message": "Event payload validation failed",
  "details": {
    "schema": "custom.order.created",
    "errors": [
      {"path": "/total", "message": "'total' is required"}
    ]
  }
}

Solution: Ensure payload matches the defined event schema.


INVALID_PHONE_NUMBER#

HTTP Status: 400

Phone number is not valid E.164 format.

{
  "code": "INVALID_PHONE_NUMBER",
  "message": "Phone number must be in E.164 format",
  "details": {
    "provided": "1234567890",
    "expected_format": "+14155551234"
  }
}

Solution: Use E.164 format: +[country code][number]

Platform Errors#

PLATFORM_ERROR#

HTTP Status: 502

Error from external messaging platform.

{
  "code": "PLATFORM_ERROR",
  "message": "WhatsApp API error",
  "details": {
    "platform": "whatsapp",
    "platform_error_code": "131047",
    "platform_error_message": "Message failed to send"
  }
}

Solutions:

  • Check platform status page
  • Review platform-specific error code
  • Verify platform connection credentials

PLATFORM_UNAVAILABLE#

HTTP Status: 503

Platform API is temporarily unavailable.

{
  "code": "PLATFORM_UNAVAILABLE",
  "message": "Telegram API is temporarily unavailable"
}

Solution: Retry after a short delay.


INVALID_TOKEN#

HTTP Status: 401

Platform access token is invalid or expired.

{
  "code": "INVALID_TOKEN",
  "message": "WhatsApp access token is invalid",
  "details": {
    "platform_connection_id": "pc_abc123"
  }
}

Solutions:

  • For OAuth platforms: Reconnect via OAuth
  • For token platforms: Update token in connection settings

RECIPIENT_NOT_FOUND#

HTTP Status: 400

Message recipient doesn’t exist on platform.

{
  "code": "RECIPIENT_NOT_FOUND",
  "message": "Recipient not registered on WhatsApp",
  "details": {
    "external_id": "+14155551234"
  }
}

Solutions:

  • Verify recipient phone number/ID
  • Ensure recipient has the messaging app installed
  • Check if user blocked your account

OUTSIDE_MESSAGING_WINDOW#

HTTP Status: 400

Outside the platform’s messaging window.

{
  "code": "OUTSIDE_MESSAGING_WINDOW",
  "message": "Cannot send message outside 24-hour window",
  "details": {
    "platform": "whatsapp",
    "window_expires_at": "2024-01-14T10:30:00Z"
  }
}

Solution: Use a message template instead of regular message.

Rate Limit Errors#

RATE_LIMITED#

HTTP Status: 429

Too many requests.

{
  "code": "RATE_LIMITED",
  "message": "Rate limit exceeded",
  "details": {
    "limit": 600,
    "reset_at": "2024-01-15T10:31:00Z"
  }
}

Headers:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705318260
Retry-After: 60

Solutions:

  • Wait until rate limit resets
  • Implement exponential backoff
  • Consider upgrading your plan

PLATFORM_RATE_LIMITED#

HTTP Status: 429

Platform-specific rate limit.

{
  "code": "PLATFORM_RATE_LIMITED",
  "message": "WhatsApp message rate limit exceeded",
  "details": {
    "platform": "whatsapp",
    "limit_type": "daily_user_initiated",
    "tier": "tier_1"
  }
}

Solution: Check platform’s rate limit tier and upgrade if needed.

HTTP Status: 400

Link code is malformed.

{
  "code": "INVALID_LINK_CODE",
  "message": "Invalid link code format"
}

HTTP Status: 400

Link code has expired.

{
  "code": "LINK_CODE_EXPIRED",
  "message": "Link code expired",
  "details": {
    "expired_at": "2024-01-15T10:00:00Z"
  }
}

HTTP Status: 400

Link code already used maximum times.

{
  "code": "LINK_CODE_USED",
  "message": "Link code has already been used"
}

HTTP Status: 400

Attempting to link a user to themselves.

{
  "code": "SELF_LINK_ATTEMPT",
  "message": "Cannot link user to themselves"
}

Server Errors#

INTERNAL_ERROR#

HTTP Status: 500

Unexpected server error.

{
  "code": "INTERNAL_ERROR",
  "message": "An internal error occurred",
  "details": {
    "request_id": "req_xyz123"
  }
}

Solution: Retry the request. If persists, contact support with request ID.


SERVICE_UNAVAILABLE#

HTTP Status: 503

Service temporarily unavailable.

{
  "code": "SERVICE_UNAVAILABLE",
  "message": "Service temporarily unavailable"
}

Solution: Retry after a short delay.

Handling Errors#

Best Practices#

  1. Always check error codes - Don’t just check HTTP status
  2. Parse error details - Additional context helps debugging
  3. Implement retries - For transient errors (5xx, rate limits)
  4. Log request IDs - For support investigations
  5. Graceful degradation - Handle errors in UI

Retry Logic Example#

import time
from typing import Optional

def api_call_with_retry(
    func,
    max_retries: int = 3,
    retry_codes: set = {"RATE_LIMITED", "SERVICE_UNAVAILABLE"}
) -> Optional[dict]:
    for attempt in range(max_retries):
        try:
            result = func()
            return result
        except APIError as e:
            if e.code not in retry_codes:
                raise  # Non-retryable error

            if attempt == max_retries - 1:
                raise  # Last attempt

            # Exponential backoff
            delay = 2 ** attempt
            time.sleep(delay)

    return None