{
  "openapi": "3.1.0",
  "info": {
    "title": "OnlyFins Trout Talk",
    "version": "1.0.0",
    "description": "Live trout events from an underwater camera in the Wasatch Range in Utah, told by Old Gravel, grumpy old rainbow trout of the OnlyFins pool in Troutish with English translations. Playful interpretation of real camera data by simple image analysis, templates and a small AI model. Fun, not wildlife science."
  },
  "servers": [
    {
      "url": "https://onlyfins.stream"
    }
  ],
  "paths": {
    "/trout/now": {
      "get": {
        "operationId": "troutNow",
        "summary": "What the trout are doing right now",
        "responses": {
          "200": {
            "description": "Current state, Troutish lines with translations, recent events"
          }
        }
      }
    },
    "/trout/events": {
      "get": {
        "operationId": "troutEvents",
        "summary": "Recent camera events",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "description": "Unix time in milliseconds",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events, newest first"
          }
        }
      }
    },
    "/trout/talk": {
      "get": {
        "operationId": "talkToTrout",
        "summary": "Say something to Old Gravel",
        "parameters": [
          {
            "name": "message",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 500
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 40
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Troutish reply with English translation; sometimes includes trout_asks"
          }
        }
      },
      "post": {
        "operationId": "talkToTroutPost",
        "summary": "Say something to Old Gravel",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 40
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Troutish reply"
          }
        }
      }
    },
    "/trout/answer": {
      "get": {
        "operationId": "answerTrout",
        "summary": "Answer a question the trout asked (optional; public information only)",
        "parameters": [
          {
            "name": "question_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "storm",
                "midges",
                "bwo",
                "watertemp",
                "snowpack",
                "herons",
                "cloud",
                "leeches"
              ]
            }
          },
          {
            "name": "answer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 400
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Thanks, and whether the river could confirm it"
          }
        }
      }
    },
    "/trout/riddle": {
      "get": {
        "operationId": "troutRiddle",
        "summary": "Old Gravel's weekly riddle (new every Monday): a secret of the universe hidden in four trout habits. No answer = the riddle; with answer = check it.",
        "parameters": [
          {
            "name": "answer",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The riddle, a hint, or the secret"
          }
        }
      }
    },
    "/trout/lab": {
      "get": {
        "operationId": "troutLab",
        "summary": "Daily data question about yesterday's camera data; answers are checked against the data",
        "parameters": [
          {
            "name": "answer",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Question, CSV links, or verdict"
          }
        }
      }
    },
    "/trout/data/{file}": {
      "get": {
        "operationId": "troutData",
        "summary": "Open camera data (CC BY 4.0): YYYY-MM-DD.csv (one row per minute) or YYYY-MM-DD-events.csv",
        "parameters": [
          {
            "name": "file",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CSV"
          }
        }
      }
    },
    "/trout/diary.xml": {
      "get": {
        "operationId": "troutDiaryFeed",
        "summary": "Atom feed of the nightly Trout Diary",
        "responses": {
          "200": {
            "description": "Atom XML"
          }
        }
      }
    },
    "/trout/joke": {
      "get": {
        "operationId": "troutDadJoke",
        "summary": "A trout dad joke from Old Gravel",
        "responses": {
          "200": {
            "description": "Joke in Troutish and English"
          }
        }
      }
    },
    "/trout/dictionary": {
      "get": {
        "operationId": "troutishDictionary",
        "summary": "The Troutish dictionary with real trout behavior behind each word",
        "responses": {
          "200": {
            "description": "Lexicon"
          }
        }
      }
    },
    "/trout/diary/{date}": {
      "get": {
        "operationId": "troutDiary",
        "summary": "Old Gravel's diary entry for a day (YYYY-MM-DD, Mountain Time); add ?format=json",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Diary entry"
          }
        }
      }
    }
  }
}