Skip to main content

Error Response Format

{
  "error": {
    "code": "invalid_request",
    "message": "The 'engine' field is required"
  }
}

HTTP Status Codes

The Python SDK maps HTTP status codes to SDK error codes as follows:
StatusSDK error codeExceptionWhat to do
400invalid_requestValidationErrorFix request parameters
401authentication_failedAuthenticationErrorCheck API key
403permission_deniedSubconsciousErrorCheck permissions
404not_foundNotFoundErrorVerify run ID
429rate_limitedRateLimitErrorBack off and retry
503service_unavailableSubconsciousErrorEngine down, retry later
504timeoutSubconsciousErrorRetry with longer timeout
otherinternal_errorSubconsciousErrorRetry with backoff

SDK Exceptions

Both SDKs throw typed exceptions you can catch:
from subconscious import Subconscious
from subconscious.errors import (
    SubconsciousError,     # Base class
    AuthenticationError,   # 401
    ValidationError,       # 400
    NotFoundError,         # 404
    RateLimitError,        # 429
    RequestTooLargeError,  # raised client-side when the payload is too big
)
import os

client = Subconscious(api_key=os.environ.get("SUBCONSCIOUS_API_KEY"))

try:
    run = client.run(
        engine="tim",
        input={"instructions": "Hello"},
        options={"await_completion": True},
    )
except AuthenticationError:
    print("Invalid API key")
except ValidationError as e:
    print(f"Bad request: {e.args[0]}")
except RateLimitError as e:
    print(f"Rate limited: {e.args[0]}")
except RequestTooLargeError as e:
    print(f"Payload too large: {e}")
except SubconsciousError as e:
    print(f"Error {e.status}: {e.code} - {e.args[0]}")
Exception properties:
  • code — Error type ("invalid_request", "authentication_failed", "permission_denied", "not_found", "rate_limited", "internal_error", "service_unavailable", "timeout")
  • status — HTTP status code
  • details — Additional context (e.g. validation errors). May be None.
  • Human-readable message — in Python, read via str(e) (returns "<code>: <message>") or e.args[0] (raw message). In Node, read via e.message.
RequestTooLargeError is a ValueError subclass (not a SubconsciousError) raised on the client before any HTTP request when the serialized run body exceeds the 5 MiB API limit — catch it separately if you send large multimodal inputs.

Retry Logic

Retry on 429 and 5xx errors with exponential backoff:
import time
import os
from subconscious import Subconscious
from subconscious.errors import SubconsciousError

client = Subconscious(api_key=os.environ.get("SUBCONSCIOUS_API_KEY"))

def run_with_retry(instructions, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.run(
                engine="tim",
                input={"instructions": instructions},
                options={"await_completion": True},
            )
        except SubconsciousError as e:
            retryable = e.status == 429 or e.status >= 500
            if not retryable or attempt == max_retries - 1:
                raise
            time.sleep(2 ** attempt)

run = run_with_retry("Summarize the news")

Run-Level Errors

Runs can fail after being accepted. Check the status field:
run = client.run(
    engine="tim",
    input={"instructions": "Your task"},
    options={"await_completion": True},
)

match run.status:
    case "succeeded":
        print(run.result.answer)
    case "failed":
        print(f"Failed: {run.error.message}")
    case "timed_out":
        print("Timed out")
    case "canceled":
        print("Canceled")

Quick Reference

ErrorStatusFix
Missing API key401Add Authorization: Bearer sk-... header
Invalid API key401Check key is active in dashboard
Bad request400Check required fields and types
Run not found404Verify run ID exists
Rate limited429Back off and retry
Engine down503Retry in a few minutes
Gateway timeout504Retry with a longer timeout
Payload too largen/aRequestTooLargeError raised client-side before the request; split input