Skip to content

Error Codes

SandBase uses standard HTTP status codes and a consistent JSON error format across all endpoints. This page documents all error codes, their meanings, and recommended handling strategies.

Error Response Format

All error responses follow this structure:

json
{
  "code": 400,
  "message": "Invalid request: model field is required"
}
FieldTypeDescription
codeintegerHTTP status code
messagestringHuman-readable error description

Anthropic-Compatible Errors

The /v1/messages endpoint returns errors in Anthropic's format:

json
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "max_tokens is required"
  }
}

HTTP Status Codes

Client Errors (4xx)

StatusNameDescription
400Bad RequestInvalid request body, missing required fields, or unsupported parameters
401UnauthorizedMissing, invalid, revoked, or expired API key
402Payment RequiredInsufficient account balance to process the request
403ForbiddenAPI key lacks permission for the requested resource
404Not FoundRequested resource (model, sandbox, webhook) does not exist
409ConflictResource state conflict (e.g., pausing an already-paused sandbox)
429Too Many RequestsRate limit exceeded

Server Errors (5xx)

StatusNameDescription
500Internal Server ErrorUnexpected server-side error
502Bad GatewayUpstream provider returned an error or is unreachable
503Service UnavailableService temporarily unavailable (maintenance or overload)
504Gateway TimeoutUpstream provider did not respond in time

Common Errors and Solutions

400 — Bad Request

MessageCauseSolution
invalid request bodyMalformed JSON or missing required fieldsCheck your JSON syntax and include all required fields
model field is requiredMissing model in request bodyAdd a valid model identifier
max_tokens is requiredMissing max_tokens (Anthropic endpoint)Include max_tokens in the request
unknown agent: <slug>Invalid template ID for sandbox creationUse a valid template slug (e.g., code_interpreter)
invalid sandbox idMalformed sandbox IDUse the ID returned from sandbox creation
file too largeFile exceeds 1MB limit (sandbox filesystem)Read smaller files or use streaming
events list cannot be emptyWebhook registration with no eventsSpecify at least one event type
invalid webhook urlWebhook URL too short or malformedProvide a valid HTTPS URL

401 — Unauthorized

MessageCauseSolution
missing API key in Authorization headerNo auth header providedAdd Authorization: Bearer sk-sb-... or x-api-key: sk-sb-...
invalid API keyKey not found in databaseVerify the key is correct and hasn't been deleted
API key has been revokedKey was disabled in the DashboardCreate a new key or re-enable the existing one
API key has expiredKey past its expiration dateCreate a new key with a later expiration
invalid signatureWebhook signature verification failedCheck your webhook secret and signature computation

402 — Payment Required

MessageCauseSolution
insufficient balanceOrganization credit balance is zero or negativeTop up your account in the Dashboard under Billing

404 — Not Found

MessageCauseSolution
model not foundRequested model doesn't exist or isn't enabledCheck the Models page for available models
sandbox not foundSandbox doesn't exist or belongs to another orgVerify the sandbox ID and that it hasn't been destroyed
webhook not foundWebhook doesn't exist or belongs to another orgVerify the webhook ID

409 — Conflict

MessageReasonSolution
sandbox is not activeAttempting keepalive on a non-running sandboxOnly call keepalive on sandboxes with status running
sandbox maximum lifetime exceededSandbox has exceeded max allowed lifetimeCreate a new sandbox instead

429 — Too Many Requests

MessageCauseSolution
rate limit exceededToo many requests in the current windowWait and retry with exponential backoff

WARNING

429 responses do not include Retry-After or X-RateLimit-* headers. Use client-side exponential backoff to pace retries — see Rate Limiting.

500 — Internal Server Error

MessageCauseSolution
internal errorUnexpected server failureRetry after a brief delay. If persistent, contact support

502 — Bad Gateway

MessageCauseSolution
failed to create sandbox in providerE2B provider returned an errorRetry after a brief delay
failed to pause sandbox in providerProvider failed to pauseCheck sandbox status and retry
failed to destroy sandbox in providerProvider failed to destroyRetry or check Dashboard
failed to execute command in sandboxCommand execution failed at provider levelVerify sandbox is running and retry
failed to read file from sandboxFile read failed at provider levelVerify the file path exists
failed to list directory in sandboxDirectory listing failedVerify the path exists
upstream provider errorLLM provider returned an errorRetry; SandBase may automatically failover

Retry Strategies

When to Retry

Status CodeRetry?Strategy
400NoFix the request — retrying won't help
401NoFix authentication — retrying won't help
402NoTop up balance — retrying won't help
403NoCheck permissions — retrying won't help
404NoResource doesn't exist — retrying won't help
409MaybeCheck resource state, then retry if appropriate
429YesBack off (exponential) and retry — no Retry-After header is sent
500YesRetry with exponential backoff
502YesRetry with exponential backoff
503YesRetry with exponential backoff
504YesRetry with exponential backoff

Exponential Backoff

For retryable errors, use exponential backoff with jitter:

python
import time
import random
import requests

def request_with_retry(url, headers, json_body, max_retries=5):
    """Make a request with exponential backoff retry."""
    for attempt in range(max_retries):
        response = requests.post(url, headers=headers, json=json_body)

        if response.status_code in (429, 500, 502, 503, 504):
            # No Retry-After header is sent — use exponential backoff with jitter
            delay = min(2 ** attempt + random.random(), 60)
            time.sleep(delay)
            continue

        return response

    raise Exception(f"Max retries ({max_retries}) exceeded")
javascript
async function requestWithRetry(url, options, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if ([429, 500, 502, 503, 504].includes(response.status)) {
      // No Retry-After header is sent — use exponential backoff with jitter
      const delay = Math.min(2 ** attempt + Math.random(), 60);
      await new Promise(r => setTimeout(r, delay * 1000));
      continue;
    }

    return response;
  }

  throw new Error(`Max retries (${maxRetries}) exceeded`);
}
ParameterValueDescription
Base delay1 secondInitial wait time
Multiplier2xDouble the delay each attempt
Max delay60 secondsCap the maximum wait time
Jitter0–1 secondRandom addition to prevent thundering herd
Max retries5Maximum number of attempts

Streaming Errors

When using streaming (stream: true), errors can occur mid-stream. These are delivered as SSE events:

OpenAI Format (Chat Completions)

data: {"error":{"message":"upstream timeout","type":"server_error","code":"stream_timeout"}}

data: [DONE]

Anthropic Format (Messages)

event: error
data: {"type":"error","error":{"type":"api_error","message":"upstream timeout"}}

event: message_stop
data: {"type":"message_stop"}

Stream-Specific Errors

ErrorDescriptionHandling
stream_timeoutNo data received from upstream for 60sRetry the full request
upstream_disconnectProvider connection droppedRetry the full request
content_filterContent was filtered mid-generationCheck your prompt content

Error Monitoring

Monitor error rates in the SandBase Dashboard under Usage → Errors. You can:

  • View error rates by status code over time
  • Filter by endpoint, model, or API key
  • Set up alerts for elevated error rates
  • Export error logs for debugging