{
  "openapi": "3.1.0",
  "info": {
    "title": "FreeRide Gateway API",
    "version": "0.4.0",
    "description": "Local OpenAI-compatible gateway for routing requests across free-tier AI inference providers (OpenRouter, Groq, NVIDIA NIM, Cloudflare Workers AI, HuggingFace, Cerebras, Ollama). Automatically fails over when rate limits or quotas are hit.",
    "contact": {
      "url": "https://github.com/Shaivpidadi/FreeRideV3"
    },
    "license": {
      "name": "MIT",
      "url": "https://github.com/Shaivpidadi/FreeRideV3/blob/main/LICENSE"
    }
  },
  "servers": [
    {
      "url": "http://localhost:11343",
      "description": "Local FreeRide gateway (default)"
    },
    {
      "url": "https://api.free-ride.xyz",
      "description": "Public API endpoints (install.sh, stats)"
    }
  ],
  "paths": {
    "/v1/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "summary": "Create chat completion",
        "description": "OpenAI-compatible chat completions endpoint. Routes requests across configured free-tier providers with automatic failover on rate limits or quota exhaustion.",
        "tags": ["Chat"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful completion",
            "headers": {
              "X-FreeRide-Provider": {
                "description": "Provider that fulfilled the request",
                "schema": {
                  "type": "string",
                  "enum": ["openrouter", "groq", "nvidia_nim", "cloudflare", "huggingface", "cerebras", "ollama"]
                }
              },
              "X-RateLimit-Limit": {
                "description": "Provider-specific rate limit (when available)",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Remaining requests in current window (when available)",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when limit resets (when available)",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-sent events stream for streaming completions"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "All providers rate-limited",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "All providers unavailable",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List available models",
        "description": "Returns models from all configured providers. Cached to reduce upstream calls.",
        "tags": ["Models"],
        "responses": {
          "200": {
            "description": "List of models",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelListResponse"
                }
              }
            }
          },
          "500": {
            "description": "Error fetching models",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Create Anthropic-style message",
        "description": "Anthropic Messages API compatibility endpoint. Routes to providers supporting the Messages format.",
        "tags": ["Messages"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "model": {
                    "type": "string"
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "max_tokens": {
                    "type": "integer"
                  },
                  "stream": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message created",
            "headers": {
              "X-FreeRide-Provider": {
                "description": "Provider that fulfilled the request",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "healthCheck",
        "summary": "Health check",
        "description": "Returns gateway health status and configured provider count",
        "tags": ["System"],
        "responses": {
          "200": {
            "description": "Gateway healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": ["ok"]
                    },
                    "providers": {
                      "type": "integer",
                      "description": "Number of configured providers"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/stats": {
      "get": {
        "operationId": "getStats",
        "summary": "Get usage statistics",
        "description": "Returns aggregated token usage statistics across all FreeRide deployments",
        "tags": ["Stats"],
        "servers": [
          {
            "url": "https://api.free-ride.xyz"
          }
        ],
        "responses": {
          "200": {
            "description": "Usage statistics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "combined": {
                      "type": "integer",
                      "description": "Total tokens served"
                    },
                    "ratePerSec": {
                      "type": "number",
                      "description": "Tokens per second (trailing 7-day average)"
                    },
                    "since": {
                      "type": "string",
                      "format": "date",
                      "description": "Start date of tracking"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/install.sh": {
      "get": {
        "operationId": "getInstaller",
        "summary": "Get installation script",
        "description": "Shell script to install freeride-gateway via uv or pip",
        "tags": ["Install"],
        "servers": [
          {
            "url": "https://api.free-ride.xyz"
          }
        ],
        "responses": {
          "200": {
            "description": "Installation script",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ChatCompletionRequest": {
        "type": "object",
        "required": ["model", "messages"],
        "properties": {
          "model": {
            "type": "string",
            "description": "Model identifier (e.g., gpt-4, claude-3-5-sonnet, llama-3.1-70b)"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["role", "content"],
              "properties": {
                "role": {
                  "type": "string",
                  "enum": ["system", "user", "assistant", "tool"]
                },
                "content": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "default": 1
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1
          },
          "stream": {
            "type": "boolean",
            "default": false
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "ChatCompletionResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "enum": ["chat.completion"]
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "message": {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string"
                    },
                    "content": {
                      "type": "string"
                    }
                  }
                },
                "finish_reason": {
                  "type": "string",
                  "enum": ["stop", "length", "tool_calls"]
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "completion_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              }
            }
          }
        }
      },
      "ModelListResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": ["list"]
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "object": {
                  "type": "string",
                  "enum": ["model"]
                },
                "created": {
                  "type": "integer"
                },
                "owned_by": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["message", "type"],
            "properties": {
              "message": {
                "type": "string",
                "description": "Human-readable error message"
              },
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "authentication_error",
                  "rate_limit_error",
                  "quota_exhausted_error",
                  "model_not_found_error",
                  "server_error",
                  "service_unavailable_error"
                ]
              },
              "code": {
                "type": "string",
                "description": "Machine-readable error code"
              },
              "param": {
                "type": "string",
                "description": "Parameter that caused the error"
              }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limited",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before retrying",
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServerError": {
        "description": "Server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Chat",
      "description": "Chat completion endpoints"
    },
    {
      "name": "Messages",
      "description": "Anthropic Messages API compatibility"
    },
    {
      "name": "Models",
      "description": "Model listing"
    },
    {
      "name": "System",
      "description": "Health and status"
    },
    {
      "name": "Stats",
      "description": "Usage statistics"
    },
    {
      "name": "Install",
      "description": "Installation resources"
    }
  ]
}
