{
  "openapi": "3.1.0",
  "info": {
    "title": "crypto-ai.dev Market Data API",
    "version": "1.2.0",
    "description": "Free, no-signup market data API. Crypto prices volume-weighted across Binance, Coinbase, Kraken & OKX (15s-delayed free tier, real-time keyed), live market caps, 7d history, 25 crypto-linked stock quotes (~15min delayed), coin-tagged news, and trading signals.",
    "contact": {
      "url": "https://crypto-ai.dev",
      "email": "hello@crypto-ai.dev"
    },
    "license": {
      "name": "Data: public exchange feeds, attribution appreciated"
    }
  },
  "servers": [
    {
      "url": "https://crypto-ai-prices.fly.dev",
      "description": "Production (REST + WebSocket)"
    },
    {
      "url": "https://crypto-ai.dev",
      "description": "Web-app endpoints (wire)"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "name": "X-API-Key",
        "in": "header",
        "description": "Grants real-time (non-delayed) access. Contact waitlist for access."
      }
    },
    "schemas": {
      "Price": {
        "type": "object",
        "properties": {
          "price": {
            "type": "number",
            "description": "Latest trade price (simple mean across venues)."
          },
          "vwap": {
            "type": "number",
            "description": "Volume-weighted average price across venues — the headline fair price."
          },
          "change24h": {
            "type": "number",
            "description": "Percentage change vs 24h ago (rolling, history-anchored)."
          },
          "change7d": {
            "type": "number",
            "description": "Percentage change vs 7 days ago."
          },
          "volume24h": {
            "type": "number",
            "description": "USD-notional 24h volume (base * vwap summed across venues)."
          },
          "spread": {
            "type": "number",
            "description": "Percent gap between highest and lowest venue price."
          },
          "high24h": {
            "type": "number",
            "nullable": true,
            "description": "True 24h high (minute resolution, cross-venue mean)."
          },
          "low24h": {
            "type": "number",
            "nullable": true,
            "description": "True 24h low."
          },
          "venues": {
            "type": "object",
            "description": "Per-venue last price and timestamp.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "price": {
                  "type": "number"
                },
                "timestamp": {
                  "type": "integer",
                  "description": "Epoch ms"
                }
              }
            }
          },
          "marketCap": {
            "type": "number",
            "nullable": true,
            "description": "Circulating supply × live cross-venue price."
          },
          "circulatingSupply": {
            "type": "number",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Contributing venues."
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "price",
          "vwap",
          "change24h",
          "volume24h",
          "sources"
        ]
      },
      "StockQuote": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "cat": {
            "type": "string",
            "description": "Category: Crypto-native, Miner, ETF, Infra, Fintech, Big tech."
          },
          "price": {
            "type": "number"
          },
          "change24h": {
            "type": "number",
            "nullable": true,
            "description": "Percent vs previous session close."
          },
          "change7d": {
            "type": "number",
            "nullable": true,
            "description": "Percent vs 7 sessions ago."
          },
          "spark7d": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "Last 7 daily closes."
          },
          "volumeUsd": {
            "type": "number",
            "nullable": true,
            "description": "Today's volume in USD notional."
          },
          "marketCap": {
            "type": "number",
            "nullable": true
          },
          "dayHigh": {
            "type": "number",
            "nullable": true
          },
          "dayLow": {
            "type": "number",
            "nullable": true
          },
          "w52High": {
            "type": "number",
            "nullable": true
          },
          "w52Low": {
            "type": "number",
            "nullable": true
          }
        },
        "required": [
          "symbol",
          "name",
          "price"
        ]
      },
      "Signal": {
        "type": "object",
        "properties": {
          "direction": {
            "type": "string",
            "enum": [
              "BUY",
              "SELL"
            ]
          },
          "price": {
            "type": "number"
          },
          "timestamp": {
            "type": "integer",
            "description": "Epoch ms"
          },
          "note": {
            "type": "string"
          }
        }
      },
      "PricesResponse": {
        "type": "object",
        "properties": {
          "live": {
            "type": "boolean"
          },
          "delay": {
            "type": "number",
            "description": "Seconds of delay (0 when live)."
          },
          "timestamp": {
            "type": "integer"
          },
          "prices": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Price"
            }
          }
        },
        "required": [
          "live",
          "delay",
          "timestamp",
          "prices"
        ]
      },
      "HistoryPoint": {
        "type": "object",
        "properties": {
          "t": {
            "type": "integer",
            "description": "Epoch ms"
          },
          "price": {
            "type": "number"
          }
        },
        "required": [
          "t",
          "price"
        ]
      },
      "HistoryResponse": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string"
          },
          "points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HistoryPoint"
            },
            "description": "Last 24h, hourly."
          },
          "points7d": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HistoryPoint"
            },
            "description": "Last 7 days, hourly."
          }
        }
      },
      "WireItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "link": {
            "type": "string",
            "format": "uri"
          },
          "source": {
            "type": "string",
            "enum": [
              "CoinDesk",
              "CoinTelegraph",
              "Decrypt",
              "The Block"
            ]
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "summary": {
            "type": "string"
          },
          "coins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/api/prices": {
      "get": {
        "summary": "Current prices for every tracked asset",
        "security": [
          {},
          {
            "ApiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "Prices object keyed by symbol",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/prices/{symbol}": {
      "get": {
        "summary": "Current price for a single asset",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "BTC"
          }
        ],
        "security": [
          {},
          {
            "ApiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Unknown symbol"
          }
        }
      }
    },
    "/api/history/{symbol}": {
      "get": {
        "summary": "24-hour price history",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "BTC"
          }
        ],
        "responses": {
          "200": {
            "description": "Sampled time-series",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown symbol"
          }
        }
      }
    },
    "/api/stocks": {
      "get": {
        "summary": "Delayed quotes for 25 crypto-linked equities",
        "description": "Exchanges, treasuries, miners, Bitcoin ETFs, and infra. Delayed up to ~15 minutes, refreshed every 90s.",
        "responses": {
          "200": {
            "description": "Quotes keyed by ticker",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "delayed": {
                      "type": "boolean"
                    },
                    "delayNote": {
                      "type": "string"
                    },
                    "updated": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "quotes": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/StockQuote"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/stocks/{symbol}": {
      "get": {
        "summary": "One equity + 1 month of daily closes",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "COIN"
          }
        ],
        "responses": {
          "200": {
            "description": "Quote + chart series",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "symbol": {
                      "type": "string"
                    },
                    "delayed": {
                      "type": "boolean"
                    },
                    "quote": {
                      "$ref": "#/components/schemas/StockQuote"
                    },
                    "points": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HistoryPoint"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown ticker"
          }
        }
      }
    },
    "/api/signals/{symbol}": {
      "get": {
        "summary": "Latest trading signals per timeframe for a coin",
        "description": "Read-only. Signals are posted by authenticated webhooks (e.g. TradingView alerts). Timeframes: 1w, 1d, 12h, 4h, 1h.",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "ETH"
          }
        ],
        "responses": {
          "200": {
            "description": "Per-timeframe latest signal + recent history",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "symbol": {
                      "type": "string"
                    },
                    "timeframes": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "latest": {
                            "$ref": "#/components/schemas/Signal"
                          },
                          "count": {
                            "type": "integer"
                          },
                          "history": {
                            "type": "array",
                            "items": {
                              "$ref": "#/components/schemas/Signal"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/wire": {
      "servers": [
        {
          "url": "https://crypto-ai.dev"
        }
      ],
      "get": {
        "summary": "Coin-tagged news feed (last 72h)",
        "parameters": [
          {
            "name": "coin",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter to items mentioning this symbol."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Full-text filter over title + summary."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "News items, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WireItem"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Service health + per-venue connection stats",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/predictions": {
      "get": {
        "summary": "Live prediction-market odds (Polymarket + Kalshi), normalized",
        "description": "Most-traded prediction markets refreshed every 5 minutes. Probabilities are 0-1. Hosted on crypto-ai.dev, not the Fly API host. Link to the source market when republishing odds.",
        "servers": [
          {
            "url": "https://crypto-ai.dev"
          }
        ],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "crypto",
                "macro",
                "politics",
                "sports",
                "economy",
                "science",
                "pop-culture",
                "world"
              ]
            },
            "description": "Return one category as a flat events list. Omit for the full grouped payload (crypto, macro, top, categories)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Odds payload",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "polymarket",
                              "kalshi"
                            ]
                          },
                          "volume24hr": {
                            "type": "number"
                          },
                          "endDate": {
                            "type": "string",
                            "nullable": true
                          },
                          "outcomes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string"
                                },
                                "prob": {
                                  "type": "number"
                                }
                              }
                            }
                          },
                          "outcomeCount": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "attribution": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Upstream odds sources unavailable"
          }
        }
      }
    }
  }
}