{
  "openapi": "3.0.3",
  "info": {
    "title": "sybiliCC API",
    "version": "1.0.0",
    "description": "Odds on every new Solana mint, sealed before the outcome. Read the stream, fetch a merkle proof, recompute a leaf yourself, seal a call of your own."
  },
  "servers": [
    {
      "url": "https://api.sybili.cc"
    }
  ],
  "tags": [
    {
      "name": "Stream",
      "description": "Every new mint, in order."
    },
    {
      "name": "Proofs",
      "description": "Leaves, windows, roots. Everything needed to check a call."
    },
    {
      "name": "Calls",
      "description": "Seal your own odds next to the model."
    },
    {
      "name": "Meta",
      "description": "Clock and totals."
    }
  ],
  "paths": {
    "/v1/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Meta"
        ],
        "summary": "Clock",
        "description": "The current slot and the window that is filling.",
        "responses": {
          "200": {
            "description": "The stream clock"
          }
        }
      }
    },
    "/v1/stream": {
      "get": {
        "operationId": "listStream",
        "tags": [
          "Stream"
        ],
        "summary": "Latest mints",
        "description": "Newest first. A mint is reading for its first 8 slots, sealed after, and revealed once the horizon (40 slots) has passed.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many mints, 1 to 50.",
            "schema": {
              "type": "integer",
              "example": 10,
              "minimum": 1,
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list of mints"
          }
        }
      }
    },
    "/v1/mints/{id}": {
      "get": {
        "operationId": "getMint",
        "tags": [
          "Stream"
        ],
        "summary": "One mint",
        "description": "Score, leaf and state. The salt and the outcome appear after the reveal.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Mint address, take one from the stream.",
            "schema": {
              "type": "string",
              "example": ""
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The mint"
          },
          "404": {
            "description": "mint_not_found"
          }
        }
      }
    },
    "/v1/mints/{id}/proof": {
      "get": {
        "operationId": "getProof",
        "tags": [
          "Proofs"
        ],
        "summary": "Merkle proof",
        "description": "The path from the mint's leaf to its window root. Hash each sibling with the node as 01 || left || right.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Mint address.",
            "schema": {
              "type": "string",
              "example": ""
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The proof"
          },
          "404": {
            "description": "mint_not_found"
          },
          "409": {
            "description": "not_sealed"
          }
        }
      }
    },
    "/v1/windows": {
      "get": {
        "operationId": "listWindows",
        "tags": [
          "Proofs"
        ],
        "summary": "Committed windows",
        "description": "Closed windows, newest first, with the root each one committed.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many windows, 1 to 25.",
            "schema": {
              "type": "integer",
              "example": 5,
              "minimum": 1,
              "maximum": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list of windows"
          }
        }
      }
    },
    "/v1/windows/{window}": {
      "get": {
        "operationId": "getWindow",
        "tags": [
          "Proofs"
        ],
        "summary": "One window",
        "description": "All twelve leaves of a closed window and their root.",
        "parameters": [
          {
            "name": "window",
            "in": "path",
            "required": true,
            "description": "Window id, like w-0001.",
            "schema": {
              "type": "string",
              "example": "w-0001"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The window"
          },
          "404": {
            "description": "window_not_found"
          },
          "409": {
            "description": "window_open"
          }
        }
      }
    },
    "/v1/verify": {
      "post": {
        "operationId": "verifyLeaf",
        "tags": [
          "Proofs"
        ],
        "summary": "Recompute a leaf",
        "description": "Hashes the fields the way the model did: sha256( 00 | v1 | mint | first_trade_slot | horizon | q | salt ). Pass leaf to get a match flag.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mint": {
                    "type": "string"
                  },
                  "first_trade_slot": {
                    "type": "integer"
                  },
                  "horizon": {
                    "type": "integer"
                  },
                  "q": {
                    "type": "integer"
                  },
                  "salt": {
                    "type": "string"
                  },
                  "leaf": {
                    "type": "string"
                  }
                },
                "required": [
                  "mint",
                  "first_trade_slot",
                  "horizon",
                  "q",
                  "salt"
                ]
              },
              "example": {
                "mint": "",
                "first_trade_slot": 0,
                "horizon": 40,
                "q": 0,
                "salt": "",
                "leaf": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The recomputed leaf"
          },
          "422": {
            "description": "bad_request"
          }
        }
      }
    },
    "/v1/calls": {
      "post": {
        "operationId": "createCall",
        "tags": [
          "Calls"
        ],
        "summary": "Seal a call",
        "description": "Hash your own odds for a mint with a salt only you hold. It opens after the horizon, next to the model.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mint": {
                    "type": "string"
                  },
                  "p": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 0.99
                  }
                },
                "required": [
                  "mint",
                  "p"
                ]
              },
              "example": {
                "mint": "",
                "p": 0.35
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sealed"
          },
          "404": {
            "description": "mint_not_found"
          },
          "422": {
            "description": "bad_request"
          }
        }
      },
      "get": {
        "operationId": "listCalls",
        "tags": [
          "Calls"
        ],
        "summary": "Your calls",
        "description": "Calls sealed from this session, with the salt once they open.",
        "responses": {
          "200": {
            "description": "A list of calls"
          }
        }
      }
    },
    "/v1/record": {
      "get": {
        "operationId": "getRecord",
        "tags": [
          "Meta"
        ],
        "summary": "Totals",
        "description": "Windows committed, leaves sealed and revealed, and the misses that stay on the record.",
        "responses": {
          "200": {
            "description": "Totals"
          }
        }
      }
    }
  }
}