Error Codes

Comprehensive catalog of all error codes returned by LendFoundry APIs with resolution steps

Error Codes

📘

Comprehensive Error Reference

This document provides a complete catalog of all error codes returned by LendFoundry APIs. Each error includes HTTP status code, error code, message, and resolution steps.

Understanding error responses is critical for building robust integrations that handle failures gracefully.


Error Response Format

All errors follow this standard JSON format:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": [
      {
        "field": "field_name",
        "issue": "SPECIFIC_ISSUE"
      }
    ],
    "trace_id": "a1b2c3d4e5f6",
    "timestamp": "2025-12-15T10:30:00Z"
  }
}
FieldTypeDescription
codestringMachine-readable error code
messagestringHuman-readable error description
detailsarraySpecific field-level errors (optional)
trace_idstringUnique identifier for support tickets
timestampstringWhen the error occurred (ISO 8601)

HTTP Status Codes Overview

%%{init: {'theme': 'base', 'themeVariables': {'background': '#ffffff', 'mainBkg': '#ffffff', 'clusterBkg': '#f9fafb', 'clusterBorder': '#2563eb', 'primaryColor': '#2563eb', 'primaryTextColor': '#ffffff', 'titleColor': '#000000', 'lineColor': '#374151'}, 'flowchart': {'padding': 25, 'nodeSpacing': 45, 'rankSpacing': 50}}}%%
flowchart LR
    subgraph ERRORS[📋 Error Categories]
        A[4xx Client] --> B[400 Bad Request]
        A --> C[401 Unauthorized]
        A --> D[403 Forbidden]
        A --> E[404 Not Found]
        A --> F[429 Rate Limit]
        G[5xx Server] --> H[500 Internal]
        G --> I[503 Unavailable]
    end
    
    style A fill:#d97706,stroke:#b45309,color:#fff
    style G fill:#dc2626,stroke:#b91c1c,color:#fff
    style B fill:#d97706,stroke:#b45309,color:#fff
    style C fill:#d97706,stroke:#b45309,color:#fff
    style D fill:#d97706,stroke:#b45309,color:#fff
    style E fill:#d97706,stroke:#b45309,color:#fff
    style F fill:#d97706,stroke:#b45309,color:#fff
    style H fill:#dc2626,stroke:#b91c1c,color:#fff
    style I fill:#dc2626,stroke:#b91c1c,color:#fff
StatusMeaningRetryableCommon Causes
400Bad Request❌ NoInvalid request format, missing fields
401Unauthorized⚠️ SometimesInvalid credentials, expired token
403Forbidden❌ NoInsufficient permissions
404Not Found❌ NoResource doesn't exist
409Conflict❌ NoDuplicate resource, state conflict
422Unprocessable Entity❌ NoValidation errors, business rules
429Too Many Requests✅ YesRate limit exceeded
500Internal Server Error✅ YesServer-side error
502Bad Gateway✅ YesGateway error
503Service Unavailable✅ YesService temporarily down
504Gateway Timeout✅ YesRequest timeout

Authentication Errors (401, 403)

UNAUTHORIZED

HTTP Status: 401
System: Both LOS and LMS

Message: "Invalid or missing authentication credentials"

Causes:

  • LOS: API key missing, invalid, or revoked
  • LMS: JWT token missing, invalid, or expired

Resolution:

# LOS - Check API key format
headers = {"Authorization": api_key}  # No Bearer prefix

# LMS - Refresh expired token
token = refresh_jwt_token()
headers = {"Authorization": f"Bearer {token}"}

Example Response:

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

TOKEN_EXPIRED

HTTP Status: 401
System: LMS only

Message: "JWT token has expired"

Resolution: Request new token via OAuth endpoint

def refresh_token(client_id, client_secret):
    """Request new JWT token."""
    response = requests.post(
        "https://api.demo.lms.lendfoundry.com/oauth/token",
        data={
            "grant_type": "client_credentials",
            "client_id": client_id,
            "client_secret": client_secret
        }
    )
    return response.json()["access_token"]

Example Response:

{
  "error": {
    "code": "TOKEN_EXPIRED",
    "message": "JWT token expired at 2025-12-15T10:30:00Z",
    "details": "Request a new token from /oauth/token"
  }
}

FORBIDDEN

HTTP Status: 403
System: Both

Message: "Insufficient permissions to access this resource"

Resolution: Contact support to verify account permissions

Example Response:

{
  "error": {
    "code": "FORBIDDEN",
    "message": "Insufficient permissions to access this resource",
    "details": "Your API key does not have access to this endpoint"
  }
}

Validation Errors (400, 422)

INVALID_REQUEST

HTTP Status: 400
System: Both

Message: "Request body is malformed or missing required fields"

Common Causes:

  • Invalid JSON syntax
  • Missing required fields
  • Wrong data types

Example Response:

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Request body is malformed",
    "details": [
      {
        "field": "loan_amount",
        "issue": "REQUIRED_FIELD_MISSING"
      },
      {
        "field": "interest_rate",
        "issue": "INVALID_TYPE",
        "expected": "number",
        "received": "string"
      }
    ]
  }
}

VALIDATION_ERROR

HTTP Status: 422
System: Both

Message: "Request failed validation"

Common Issues:

Issue CodeDescription
INVALID_LOAN_AMOUNTAmount outside valid range
INVALID_DATE_FORMATDate format incorrect
INVALID_EMAILEmail format invalid
INVALID_PHONEPhone number format invalid
INVALID_SSNSSN format invalid

Example Response:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Loan amount cannot exceed maximum product limit",
    "details": [
      {
        "field": "loan_amount",
        "issue": "MAX_LIMIT_EXCEEDED",
        "max": 50000,
        "provided": 75000
      }
    ]
  }
}

INVALID_DATE_FORMAT

HTTP Status: 422
System: Both

Message: "Date format is invalid"

Expected Format: ISO 8601 (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ssZ)

Example Response:

{
  "error": {
    "code": "INVALID_DATE_FORMAT",
    "message": "Date must be in ISO 8601 format",
    "details": [
      {
        "field": "application_date",
        "issue": "INVALID_FORMAT",
        "expected": "YYYY-MM-DD",
        "received": "12/15/2025"
      }
    ]
  }
}

Resource Errors (404, 409)

RESOURCE_NOT_FOUND

HTTP Status: 404
System: Both

Message: "The requested resource does not exist"

Common Resources: Loan, Application, Borrower, Document

Example Response:

{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Loan with ID LN-2024-001234 not found",
    "details": {
      "resource_type": "loan",
      "resource_id": "LN-2024-001234"
    }
  }
}

Resolution:

  • Verify resource ID is correct
  • Check if resource was deleted
  • Confirm using correct environment

DUPLICATE_RESOURCE

HTTP Status: 409
System: Both

Message: "Resource already exists"

Example Response:

{
  "error": {
    "code": "DUPLICATE_RESOURCE",
    "message": "Application with this borrower already exists",
    "details": {
      "resource_type": "application",
      "existing_id": "APP-2024-001234"
    }
  }
}

Resolution: Use existing resource or update instead of create


RESOURCE_CONFLICT

HTTP Status: 409
System: Both

Message: "Resource state conflict"

Example: Trying to approve an already-approved application

Resolution: Check current resource state before operation


Business Rule Errors (422)

BUSINESS_RULE_VIOLATION

HTTP Status: 422
System: Both

Message: "Operation violates business rules"

Common Rules:

Rule CodeDescription
LOAN_AMOUNT_EXCEEDS_LIMITAmount exceeds product limit
INSUFFICIENT_COLLATERALCollateral value insufficient
CREDIT_SCORE_TOO_LOWCredit score below minimum
DTI_TOO_HIGHDebt-to-income ratio exceeds limit
INVALID_LOAN_PURPOSEPurpose not allowed for product

Example Response:

{
  "error": {
    "code": "BUSINESS_RULE_VIOLATION",
    "message": "Loan amount exceeds maximum product limit",
    "details": [
      {
        "rule": "LOAN_AMOUNT_EXCEEDS_LIMIT",
        "product_id": "PROD001",
        "max_amount": 50000,
        "requested_amount": 75000
      }
    ]
  }
}

WORKFLOW_STATE_INVALID

HTTP Status: 422
System: Both

Message: "Invalid workflow state transition"

Example: Trying to fund an application that's not approved

Resolution: Check current state and use valid transition

{
  "error": {
    "code": "WORKFLOW_STATE_INVALID",
    "message": "Cannot fund application in current state",
    "details": {
      "current_state": "under_review",
      "requested_action": "fund",
      "valid_actions": ["approve", "decline"]
    }
  }
}

Rate Limiting Errors (429)

RATE_LIMIT_EXCEEDED

HTTP Status: 429
System: Both

Message: "Rate limit exceeded. Please retry after the specified time."

Example Response:

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded",
    "details": {
      "limit": 100,
      "remaining": 0,
      "reset_at": "2025-12-15T10:31:00Z",
      "retry_after": 60
    }
  }
}

Resolution:

  • Wait for retry_after seconds
  • Implement exponential backoff
  • Reduce request frequency
  • Use request batching

Server Errors (500, 502, 503, 504)

INTERNAL_SERVER_ERROR

HTTP Status: 500
Retryable: ✅ Yes (with backoff)

Resolution:

  • Retry with exponential backoff
  • If persists, contact support with trace_id

Example Response:

{
  "error": {
    "code": "INTERNAL_SERVER_ERROR",
    "message": "An unexpected error occurred",
    "trace_id": "a1b2c3d4e5f6",
    "details": "Please contact support with trace_id if issue persists"
  }
}

SERVICE_UNAVAILABLE

HTTP Status: 503
Retryable: ✅ Yes

Resolution: Retry after delay (check Retry-After header)


Error Handling Best Practices

Comprehensive Error Handler

import requests
import time

class APIError(Exception):
    """Custom exception for API errors."""
    def __init__(self, code, message, details=None, trace_id=None):
        self.code = code
        self.message = message
        self.details = details
        self.trace_id = trace_id
        super().__init__(f"{code}: {message}")

def handle_response(response):
    """Handle API response and raise appropriate errors."""
    if response.status_code >= 400:
        error_data = response.json().get('error', {})
        
        raise APIError(
            code=error_data.get('code', 'UNKNOWN_ERROR'),
            message=error_data.get('message', 'Unknown error'),
            details=error_data.get('details'),
            trace_id=error_data.get('trace_id')
        )
    
    return response.json()

def make_request_with_retry(url, headers, data=None, max_retries=3):
    """Make request with comprehensive error handling."""
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=data, headers=headers)
            return handle_response(response)
            
        except APIError as e:
            # Handle specific error codes
            if e.code == 'RATE_LIMIT_EXCEEDED':
                retry_after = e.details.get('retry_after', 60) if e.details else 60
                time.sleep(retry_after)
                continue
            elif e.code == 'TOKEN_EXPIRED':
                # Refresh token and retry
                headers['Authorization'] = f"Bearer {refresh_token()}"
                continue
            elif e.code in ['INTERNAL_SERVER_ERROR', 'SERVICE_UNAVAILABLE']:
                # Exponential backoff for server errors
                time.sleep(2 ** attempt)
                continue
            else:
                # Non-retryable error
                raise
                
        except requests.exceptions.RequestException as e:
            if attempt == max_retries - 1:
                raise
            time.sleep(2 ** attempt)
    
    raise Exception("Max retries exceeded")

Error Code Quick Reference

Error CodeHTTP StatusSystemRetryableDescription
UNAUTHORIZED401Both⚠️Invalid credentials
TOKEN_EXPIRED401LMSJWT expired
FORBIDDEN403BothInsufficient permissions
INVALID_REQUEST400BothMalformed request
VALIDATION_ERROR422BothValidation failed
RESOURCE_NOT_FOUND404BothResource doesn't exist
DUPLICATE_RESOURCE409BothResource already exists
BUSINESS_RULE_VIOLATION422BothBusiness rule violation
RATE_LIMIT_EXCEEDED429BothRate limit exceeded
INTERNAL_SERVER_ERROR500BothServer error
SERVICE_UNAVAILABLE503BothService unavailable

Support

Need help with an error?


Understanding Errors?

Head to the Versioning guide to understand API versioning and deprecation policies.