Flow Myna

Error Handling

Learn how to handle errors from the Flow Myna API. All errors follow a consistent format and use standard HTTP status codes.

HTTP Status Codes

CodeMeaningWhen It Occurs
200SuccessRequest completed successfully
401UnauthorizedMissing, invalid, revoked, or expired API key
422Validation ErrorInvalid request body (missing fields, wrong types)
429Rate LimitedToo many requests (future implementation)
500Server ErrorSomething went wrong on our end

Error Response Format

All error responses follow this consistent format:

Error Response Format

{
  "detail": "Human-readable error message"
}

Authentication Errors (401)

Missing API Key

{
  "detail": "Missing API key. Use 'Authorization: Bearer fm_live_...' or 'X-FlowMyna-Api-Key: fm_live_...'"
}

Fix: Include the Authorization header in your request.

Invalid API Key Format

{
  "detail": "Invalid API key format. Keys must start with 'fm_live_'"
}

Fix: Ensure your key starts with fm_live_ and is 40 characters.

Invalid API Key

{
  "detail": "Invalid API key"
}

Fix: Check that you're using the correct key from your dashboard.

Revoked Key

{
  "detail": "API key has been revoked"
}

Fix: Create a new API key in your dashboard.

Expired Key

{
  "detail": "API key has expired"
}

Fix: Create a new API key or one without an expiration date.

Validation Errors (422)

Validation errors occur when your request body doesn't match the expected schema:

FieldConstraint
eventRequired, 1-200 characters
objectsRequired, at least 1 item
objects[].typeRequired, 1-100 characters
objects[].idRequired, 1-500 characters
timestampOptional, valid ISO 8601 format

Validation Error Example

{
  "detail": [
    {
      "loc": ["body", "event"],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": ["body", "objects"],
      "msg": "ensure this value has at least 1 items",
      "type": "value_error.list.min_items"
    }
  ]
}

Retry Logic

Implement exponential backoff for transient errors:

Retry Implementation

import time
import random
import requests


def record_with_retry(event_data, max_retries=3):
    """Record event with exponential backoff retry"""
    for attempt in range(max_retries):
        try:
            response = requests.post(
                f"{BASE_URL}/event",
                json=event_data,
                headers=headers,
                timeout=30
            )
            
            # Success
            if response.status_code == 200:
                return response.json()
            
            # Don't retry client errors (except rate limits)
            if response.status_code in [401, 422]:
                raise ValueError(f"Client error: {response.json()}")
            
            # Retry server errors and rate limits
            if response.status_code in [429, 500, 502, 503, 504]:
                if attempt == max_retries - 1:
                    raise Exception(f"Max retries exceeded: {response.text}")
                    
        except requests.exceptions.RequestException as e:
            if attempt == max_retries - 1:
                raise
        
        # Exponential backoff with jitter
        wait_time = (2 ** attempt) + random.uniform(0, 1)
        time.sleep(wait_time)
    
    raise Exception("Unexpected retry exit")