API Documentation

Error Handling

The MarketGeist API uses standard HTTP status codes to indicate success or failure. All error responses include a JSON body with a detail field explaining the error.

Response Format

Successful responses always include success: true and a data field:

200 OK

{
  "success": true,
  "data": { ... }
}

Error responses include detail (and sometimes error):

4xx / 5xx Error

{
  "detail": "A human-readable error message"
}

Error Codes

400Bad Request

The request was malformed or missing required parameters.

{ "detail": "Invalid report_type: unknown_type" }

How to fix: Check the endpoint reference for required parameters and valid values.

401Unauthorized

Authentication failed or no credentials were provided.

{ "detail": "Authentication required. Provide Authorization: Bearer <token> or X-API-Key: <key>" }

How to fix: Verify your API key is correct, active, and included in the X-API-Key header.

403Forbidden

The API key does not have the required scope for this endpoint.

{ "detail": "API key missing required scope: reports" }

How to fix: Update your API key scopes in the dashboard or create a new key with the needed scopes.

404Not Found

The requested resource does not exist or does not belong to the authenticated user.

{ "detail": "Report not found" }

How to fix: Verify the resource ID and that it belongs to your account.

429Too Many Requests

Rate limit exceeded for your subscription tier.

{
  "error": "Rate limit exceeded",
  "detail": "Maximum 60 requests per minute for starter tier",
  "retry_after": 12
}

How to fix: Wait for the time specified in the Retry-After header. Consider upgrading your plan for higher limits.

500Internal Server Error

An unexpected error occurred on the server.

{ "detail": "Internal server error" }

How to fix: Retry after a brief delay. If persistent, contact support.

503Service Unavailable

A required external service (e.g., AI provider) is temporarily unavailable.

{ "detail": "AI service temporarily unavailable" }

How to fix: Retry with exponential backoff. This is usually a transient issue.

Retry Strategy

For transient errors (429, 500, 503), implement exponential backoff:

Python

import time
import requests

def safe_request(method, url, **kwargs):
    max_retries = 3
    headers = kwargs.pop("headers", {})
    headers["X-API-Key"] = "mg_live_your_key_here"

    for attempt in range(max_retries):
        resp = requests.request(method, url, headers=headers, **kwargs)

        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", 5))
            time.sleep(wait * (2 ** attempt))
            continue

        if resp.status_code >= 500:
            time.sleep(2 ** attempt)
            continue

        return resp

    return resp  # Return last response after all retries

JavaScript

async function safeRequest(url, options = {}) {
  const maxRetries = 3;
  const headers = {
    "X-API-Key": "mg_live_your_key_here",
    ...options.headers,
  };

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const resp = await fetch(url, { ...options, headers });

    if (resp.status === 429) {
      const wait = parseInt(resp.headers.get("Retry-After") || "5");
      await new Promise(r => setTimeout(r, wait * (2 ** attempt) * 1000));
      continue;
    }

    if (resp.status >= 500) {
      await new Promise(r => setTimeout(r, (2 ** attempt) * 1000));
      continue;
    }

    return resp;
  }
}