Error handling

The Mira API uses standard HTTP status codes to indicate request success or failure. All errors are returned in a consistent JSON format with detailed information about the issue.

Error response format

All API errors are returned in the following format:

JSON
{
  "detail": "The 'model' field is required."
}

The detail field contains a human-readable error description. The HTTP status code indicates the error category.

HTTP status codes

400 Bad Request

The request contains invalid parameters or is missing required fields. Check the request body and parameter format.

400 error example
{
  "detail": "The 'temperature' parameter must be between 0 and 2."
}
  • Missing required fieldThe model or messages field is not provided in the request body.
  • Invalid parameter valueFor example, temperature outside the 0-2 range or a non-existent model.
  • Malformed JSONThe request body is not valid JSON.

401 Unauthorized

The API key is invalid, expired, or missing. Make sure the Authorization header contains a valid key.

401 error example
{
  "detail": "Invalid API key."
}

403 Forbidden

The API key is valid but does not have permission for the requested action. This may mean your plan does not include access to the requested model.

403 error example
{
  "detail": "Your plan does not include access to the mira-max model."
}

404 Not Found

The requested endpoint does not exist. Check the URL and HTTP method.

404 error example
{
  "detail": "Endpoint not found."
}

429 Too Many Requests

Rate limit exceeded. The response includes a Retry-After header indicating the number of seconds until the next allowed request.

429 error example
HTTP/1.1 429 Too Many Requests
Retry-After: 60

{
  "detail": "Rate limit exceeded. Please retry after 60 seconds."
}
Always check the Retry-After header when receiving a 429 error. Do not retry without waiting the specified interval.

500 Internal Server Error

An internal server error occurred. This is not related to your request. Retry after a few seconds.

500 error example
{
  "detail": "Internal server error."
}

Error summary table

CodeDescriptionAction
400Bad request (invalid parameters)Fix your parameters
401Unauthorized (invalid API key)Check your API key
402Payment required (insufficient balance)Top up your balance
403Forbidden (plan restriction)Upgrade your plan
404Not foundCheck the URL
429Rate limitedWait for Retry-After
500Server errorRetry the request

Retry logic

For 429, 500, and 503 errors, implement exponential backoff. Start with a short delay and increase it with each attempt.

Retry logic in Python

Python
import os
import time
import requests

def call_mira_api(messages, max_retries=5):
    url = "https://api.vmira.ai/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {os.environ['MIRA_API_KEY']}",
        "Content-Type": "application/json",
    }
    payload = {"model": "mira", "messages": messages}

    for attempt in range(max_retries):
        response = requests.post(url, headers=headers, json=payload)

        if response.status_code == 200:
            return response.json()

        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 60))
            print(f"Rate limited. Waiting {retry_after}s...")
            time.sleep(retry_after)
            continue

        if response.status_code in (500, 503):
            delay = min(2 ** attempt, 60)  # 1, 2, 4, 8, 16, max 60s
            print(f"Server error {response.status_code}. Retrying in {delay}s...")
            time.sleep(delay)
            continue

        # Non-retryable error
        response.raise_for_status()

    raise Exception("Max retries exceeded")

# Usage
result = call_mira_api([{"role": "user", "content": "Hello"}])
print(result["choices"][0]["message"]["content"])

Retry logic in JavaScript

JavaScript (Node.js)
async function callMiraAPI(messages, maxRetries = 5) {
  const url = "https://api.vmira.ai/v1/chat/completions";

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.MIRA_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ model: "mira", messages }),
    });

    if (response.ok) {
      return await response.json();
    }

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get("Retry-After") || "60", 10);
      console.log(`Rate limited. Waiting ${retryAfter}s...`);
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      continue;
    }

    if (response.status === 500 || response.status === 503) {
      const delay = Math.min(2 ** attempt, 60) * 1000;
      console.log(`Server error ${response.status}. Retrying in ${delay / 1000}s...`);
      await new Promise((r) => setTimeout(r, delay));
      continue;
    }

    // Non-retryable error
    const error = await response.json();
    throw new Error(`API error ${response.status}: ${error.error.message}`);
  }

  throw new Error("Max retries exceeded");
}

// Usage
const result = await callMiraAPI([{ role: "user", content: "Hello" }]);
console.log(result.choices[0].message.content);
Add random jitter to the delay to avoid the "thundering herd" problem — when many clients retry simultaneously.

Next steps