Error Reference

API error codes and troubleshooting

Error Response Format

All errors return JSON with this structure:

{
  "error": "ErrorType",
  "message": "Human-readable description of the error"
}

HTTP Status Codes

CodeMeaning
400Bad Request - Invalid request body or parameters
401Unauthorized - Invalid or missing API key
402Payment Required - Insufficient balance
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Something went wrong on our end

Authentication Errors (401)

Invalid API Key

{
  "error": "Unauthorized",
  "message": "Invalid API key"
}

Causes:

  • API key is malformed
  • API key doesn't exist

Solutions:

  • Verify you're using the complete key
  • Generate a new key from the dashboard

Missing API Key

{
  "error": "Unauthorized",
  "message": "Missing Authorization header"
}

Solution: Include the Authorization: Bearer YOUR_KEY header.

Revoked Key

{
  "error": "Unauthorized",
  "message": "API key has been revoked"
}

Solution: Generate a new API key from the dashboard.

Wrong Service

{
  "error": "Unauthorized",
  "message": "API key not authorized for this service"
}

Cause: Using a key for a different service (e.g., using a future "translate" key with verify).

Solution: Create a key specifically for the service you're calling.

Payment Errors (402)

Insufficient Balance

{
  "error": "Payment Required",
  "message": "Insufficient balance"
}

Solution: Add funds to your app from the dashboard.

Prevention: Check your balance before making requests:

  • Monitor the tokenUsage in responses
  • Set up balance alerts (coming soon)

Rate Limit Errors (429)

Per-Minute Limit

{
  "error": "Rate Limit Exceeded",
  "message": "Too many requests per minute"
}

Headers included:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1699999999
Retry-After: 45

Per-Day Limit

{
  "error": "Rate Limit Exceeded",
  "message": "Daily request limit exceeded"
}

Solutions:

  • Wait for the rate limit to reset
  • Implement exponential backoff
  • Cache results when possible

See Rate Limits for detailed handling strategies.

Validation Errors (400)

Missing Required Field

{
  "error": "Bad Request",
  "message": "fact is required"
}

Invalid Field Value

{
  "error": "Bad Request",
  "message": "minRequired must be 2 or 3"
}

Invalid JSON

{
  "error": "Bad Request",
  "message": "Invalid JSON in request body"
}

Solution: Ensure your request body is valid JSON and includes the required fields.

Server Errors (500)

Internal Error

{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred"
}

What to do:

  1. Retry the request after a short delay
  2. If it persists, contact support
  3. Check our status page for known issues

Handling Errors in Code

JavaScript/TypeScript

async function verifyFact(fact: string) {
  const response = await fetch('https://console.mira.network/verify/v1/stream', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.MIRA_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ fact }),
  });

  if (!response.ok) {
    const error = await response.json();

    switch (response.status) {
      case 401:
        throw new Error(`Authentication failed: ${error.message}`);
      case 402:
        throw new Error('Insufficient balance - please add funds');
      case 429:
        const retryAfter = response.headers.get('Retry-After');
        throw new Error(`Rate limited - retry after ${retryAfter}s`);
      default:
        throw new Error(`API error: ${error.message}`);
    }
  }

  // Process successful response...
}

Retry with Exponential Backoff

async function fetchWithRetry(
  fn: () => Promise<Response>,
  maxRetries = 3
): Promise<Response> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fn();

      if (response.status === 429) {
        const retryAfter = parseInt(
          response.headers.get('Retry-After') || '60'
        );
        await sleep(retryAfter * 1000);
        continue;
      }

      if (response.status >= 500) {
        await sleep(Math.pow(2, i) * 1000); // Exponential backoff
        continue;
      }

      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await sleep(Math.pow(2, i) * 1000);
    }
  }

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

function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}