Skip to content

Error Handling

This guide explains how to handle errors from the MenoTime API. Understanding error responses helps you troubleshoot issues and implement robust error handling in your application.

Standard Error Response Format

All API errors follow a consistent JSON structure:

{
  "status": "error",
  "code": "ERROR_CODE",
  "message": "Human-readable error message",
  "details": {
    "additional": "information"
  }
}

Error Response Fields

Field Type Description
status string Always "error" for error responses
code string Machine-readable error code (e.g., VALIDATION_ERROR)
message string Human-readable error message
details object Additional context-specific error information

HTTP Status Codes

2xx - Success

Code Meaning
200 OK - Request succeeded, response body contains result
201 Created - Resource successfully created
202 Accepted - Request accepted for processing (async operations)
204 No Content - Request succeeded, no response body

3xx - Redirection

Code Meaning
301 Moved Permanently - Resource moved to new location
302 Found - Temporary redirect

4xx - Client Error

Code Meaning
400 Bad Request - Invalid request syntax or parameters
401 Unauthorized - Authentication required or failed
403 Forbidden - Authenticated but insufficient permissions
404 Not Found - Resource does not exist
409 Conflict - Request conflicts with current state
422 Unprocessable Entity - Validation error in request data
429 Too Many Requests - Rate limit exceeded

5xx - Server Error

Code Meaning
500 Internal Server Error - Unexpected server error
502 Bad Gateway - Invalid response from upstream service
503 Service Unavailable - Server temporarily unavailable
504 Gateway Timeout - Request timeout

Error Code Reference

Authentication Errors (401 Unauthorized)

Code HTTP Status Description Solution
INVALID_CREDENTIALS 401 Email or password incorrect Verify credentials and retry login
MISSING_AUTHORIZATION 401 Authorization header missing Include Authorization header
INVALID_TOKEN 401 Malformed or invalid token Obtain new token via login
TOKEN_EXPIRED 401 Access token has expired Use refresh token to get new access token
INVALID_REFRESH_TOKEN 401 Refresh token invalid or expired Log in again to obtain new tokens

Authorization Errors (403 Forbidden)

Code HTTP Status Description Solution
FORBIDDEN 403 Insufficient permissions for resource Use account with required role
INSUFFICIENT_ROLE 403 User role lacks required permission Request access from administrator
ORGANIZATION_ACCESS_DENIED 403 Access denied to this organization Request access from organization administrator

Validation Errors (422 Unprocessable Entity)

Code HTTP Status Description Solution
VALIDATION_ERROR 422 One or more fields invalid See details array for specific fields
DE_IDENTIFICATION_ERROR 422 Data contains potential identifiers Remove identifying information
DUPLICATE_ENTRY 422 Record with same data already exists Check for existing record
INVALID_ENUM_VALUE 422 Invalid value for enumerated field Use one of allowed values

Not Found Errors (404 Not Found)

Code HTTP Status Description Solution
NOT_FOUND 404 Requested resource does not exist Check resource ID
PATIENT_NOT_FOUND 404 Patient with ID not found Verify patient ID
VISIT_NOT_FOUND 404 Visit with ID not found Verify visit ID
BATCH_NOT_FOUND 404 Batch processing job not found Check batch ID

Rate Limiting (429 Too Many Requests)

Code HTTP Status Description Solution
RATE_LIMITED 429 Request rate limit exceeded Wait and retry after reset time
BURST_LIMIT_EXCEEDED 429 Burst rate limit exceeded Space out rapid requests

Server Errors (5xx)

Code HTTP Status Description Solution
INTERNAL_SERVER_ERROR 500 Unexpected server error Retry request after delay
SERVICE_UNAVAILABLE 503 Server temporarily unavailable Retry after some time
DATABASE_ERROR 500 Database operation failed Retry request
TIMEOUT_ERROR 504 Request processing timeout Reduce request size or retry

Common Error Scenarios

1. Invalid Credentials (401)

Request:

curl -X POST https://api.menotime.timelessbiotech.com/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"wrongpassword"}'

Response (401 Unauthorized):

{
  "status": "error",
  "code": "INVALID_CREDENTIALS",
  "message": "Invalid email or password",
  "details": {
    "attempt": 1,
    "max_attempts": 5
  }
}

Solution: Verify email and password are correct. After 5 failed attempts, account may be temporarily locked.

2. Missing Authorization Header (401)

Request:

curl -X GET https://api.menotime.timelessbiotech.com/v1/patients

Response (401 Unauthorized):

{
  "status": "error",
  "code": "MISSING_AUTHORIZATION",
  "message": "Authorization header is required",
  "details": {
    "required_header": "Authorization",
    "format": "Bearer {token}"
  }
}

Solution: Include Authorization header with valid JWT token:

curl -X GET https://api.menotime.timelessbiotech.com/v1/patients \
  -H "Authorization: Bearer {access_token}"

3. Expired Access Token (401)

Response (401 Unauthorized):

{
  "status": "error",
  "code": "TOKEN_EXPIRED",
  "message": "Access token has expired. Please refresh your token.",
  "details": {
    "expired_at": "2024-02-15T15:30:00Z",
    "refresh_endpoint": "/auth/refresh"
  }
}

Solution: Use refresh token to get new access token:

curl -X POST https://api.menotime.timelessbiotech.com/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh_token":"'$REFRESH_TOKEN'"}'

4. Insufficient Permissions (403)

Response (403 Forbidden):

{
  "status": "error",
  "code": "FORBIDDEN",
  "message": "Insufficient permissions for this resource",
  "details": {
    "required_role": "admin",
    "user_role": "readonly",
    "resource": "POST /patients"
  }
}

Solution: Use an account with the required role (admin, provider, etc.) or request role upgrade from administrator.

5. Validation Error - Invalid Field (422)

Request:

curl -X POST https://api.menotime.timelessbiotech.com/v1/patients \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"age_years":150,"race":"invalid_value"}'

Response (422 Unprocessable Entity):

{
  "status": "error",
  "code": "VALIDATION_ERROR",
  "message": "Validation failed",
  "details": [
    {
      "field": "age_years",
      "message": "Age must be between 18 and 120"
    },
    {
      "field": "race",
      "message": "Invalid value 'invalid_value'. Must be one of: caucasian, african_american, asian, hispanic, native_american, pacific_islander, other, unknown"
    }
  ]
}

Solution: Correct the invalid values according to the error messages.

6. Missing Required Field (422)

Request:

curl -X POST https://api.menotime.timelessbiotech.com/v1/patients \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"age_years":52}'

Response (422 Unprocessable Entity):

{
  "status": "error",
  "code": "VALIDATION_ERROR",
  "message": "Validation failed",
  "details": [
    {
      "field": "race",
      "message": "This field is required"
    },
    {
      "field": "ethnicity",
      "message": "This field is required"
    },
    {
      "field": "region",
      "message": "This field is required"
    },
    {
      "field": "menopause_status",
      "message": "This field is required"
    }
  ]
}

Solution: Include all required fields in the request.

7. Resource Not Found (404)

Request:

curl -X GET https://api.menotime.timelessbiotech.com/v1/patients/pat_invalid \
  -H "Authorization: Bearer {access_token}"

Response (404 Not Found):

{
  "status": "error",
  "code": "PATIENT_NOT_FOUND",
  "message": "Patient not found",
  "details": {
    "patient_id": "pat_invalid",
    "searched_fields": ["id"]
  }
}

Solution: Verify the correct patient ID and retry the request.

8. Rate Limit Exceeded (429)

Response (429 Too Many Requests):

{
  "status": "error",
  "code": "RATE_LIMITED",
  "message": "Rate limit exceeded. Please retry after some time.",
  "details": {
    "limit": 1000,
    "window": "1 hour",
    "reset_at": "2024-02-15T15:30:00Z",
    "retry_after_seconds": 3600
  }
}

Response Headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1708015800
Retry-After: 3600

Solution: Implement exponential backoff and wait until rate limit window resets. Check Retry-After header for recommended wait time.

9. De-identification Validation Error (422)

Request (contains potential identifier):

curl -X POST https://api.menotime.timelessbiotech.com/v1/patients \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "age_years": 52,
    "race": "caucasian",
    "ethnicity": "non_hispanic",
    "region": "northeast",
    "menopause_status": "perimenopause",
    "notes": "Patient Jane Doe from Boston MA"
  }'

Response (422 Unprocessable Entity):

{
  "status": "error",
  "code": "DE_IDENTIFICATION_ERROR",
  "message": "Data contains potential identifiers",
  "details": [
    {
      "field": "notes",
      "warning": "Text contains possible personal name: 'Jane Doe'",
      "position": "characters 7-14"
    },
    {
      "field": "notes",
      "warning": "Text contains specific location: 'Boston MA'",
      "position": "characters 21-30"
    }
  ]
}

Solution: Remove identifying information from the data and retry.

10. Server Error (500)

Response (500 Internal Server Error):

{
  "status": "error",
  "code": "INTERNAL_SERVER_ERROR",
  "message": "An unexpected error occurred",
  "details": {
    "request_id": "req_12345678",
    "timestamp": "2024-02-15T14:30:00Z",
    "support": "Contact support with request_id"
  }
}

Solution: Note the request_id and contact support. Implement retry logic with exponential backoff.

Error Handling Best Practices

1. Implement Retry Logic

import time
import requests

def retry_request(url, max_retries=3, backoff_factor=2):
    for attempt in range(max_retries):
        try:
            response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            if response.status_code in [429, 500, 502, 503, 504]:
                wait_time = backoff_factor ** attempt
                print(f"Retry after {wait_time} seconds")
                time.sleep(wait_time)
            else:
                raise
    raise Exception("Max retries exceeded")

2. Handle Rate Limiting

import time

def make_request_with_rate_limit(url, headers):
    response = requests.get(url, headers=headers)

    if response.status_code == 429:
        retry_after = int(response.headers.get('Retry-After', 60))
        print(f"Rate limited. Retrying after {retry_after} seconds")
        time.sleep(retry_after)
        return make_request_with_rate_limit(url, headers)

    return response.json()

3. Validate Before Submission

def validate_patient_data(data):
    errors = []

    # Check required fields
    required = ['age_years', 'race', 'ethnicity', 'region', 'menopause_status']
    for field in required:
        if field not in data:
            errors.append(f"Missing required field: {field}")

    # Validate age range
    if data.get('age_years'):
        if not (18 <= data['age_years'] <= 120):
            errors.append("Age must be between 18 and 120")

    # Validate enum values
    valid_races = ['caucasian', 'african_american', 'asian', 'hispanic', 'native_american', 'pacific_islander', 'other', 'unknown']
    if data.get('race') and data['race'] not in valid_races:
        errors.append(f"Invalid race. Must be one of: {', '.join(valid_races)}")

    return errors

# Usage
data = {"age_years": 52, "race": "invalid"}
errors = validate_patient_data(data)
if errors:
    print("Validation errors:", errors)
else:
    # Submit to API
    pass

4. Log Errors for Debugging

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def make_api_request(url, method='GET', data=None):
    try:
        if method == 'GET':
            response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
        else:
            response = requests.post(url, json=data, headers={"Authorization": f"Bearer {token}"})

        response.raise_for_status()
        return response.json()

    except requests.exceptions.HTTPError as e:
        error_data = e.response.json()
        logger.error(f"API Error: {error_data['code']} - {error_data['message']}")
        logger.error(f"Request ID: {e.response.headers.get('X-Request-ID')}")
        raise

    except Exception as e:
        logger.error(f"Unexpected error: {str(e)}")
        raise

5. Check Response Status

def safe_api_call(url, headers):
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        return response.json()["data"]
    elif response.status_code == 401:
        print("Authentication failed. Please re-login.")
    elif response.status_code == 403:
        print("Access denied. Insufficient permissions.")
    elif response.status_code == 404:
        print("Resource not found.")
    elif response.status_code == 422:
        errors = response.json()["details"]
        print("Validation errors:", errors)
    elif response.status_code == 429:
        print("Rate limited. Please wait before retrying.")
    elif response.status_code >= 500:
        print("Server error. Please try again later.")
    else:
        print(f"Unexpected status: {response.status_code}")

Error Codes Quick Reference

All Error Codes (Alphabetical)

BURST_LIMIT_EXCEEDED
DATABASE_ERROR
DE_IDENTIFICATION_ERROR
DUPLICATE_ENTRY
FORBIDDEN
INSUFFICIENT_ROLE
INTERNAL_SERVER_ERROR
INVALID_CREDENTIALS
INVALID_ENUM_VALUE
INVALID_REFRESH_TOKEN
INVALID_TOKEN
MISSING_AUTHORIZATION
NOT_FOUND
ORGANIZATION_ACCESS_DENIED
PATIENT_NOT_FOUND
RATE_LIMITED
SERVICE_UNAVAILABLE
TIMEOUT_ERROR
TOKEN_EXPIRED
VALIDATION_ERROR
VISIT_NOT_FOUND

Support

If you encounter persistent errors:

  1. Check the error code against this reference
  2. Review error details for specific field names or issues
  3. Implement retry logic for transient failures
  4. Contact support with request_id for unresolved issues

  5. Technical Support: api-support@timelessbiotech.com

  6. HIPAA/Compliance: hipaa-compliance@timelessbiotech.com