{
  "openapi": "3.1.0",
  "info": {
    "title": "FanGraph API",
    "version": "0.7.0",
    "description": "Pop and K-pop factual data. Default vertical=kpop; use vertical=pop for Pop. Send x-api-key with an admin-issued or verified-account key. API keys are required for all /api/v1 requests. Create a free verified developer account at /signup. Limits: 60 requests/IP/minute, 120/key/minute and 10,000/account/UTC day shared across keys. The separate same-origin /api/playground supports four bounded demos, 5/IP/minute and 20/IP/day. No complete or real-time coverage guarantee.",
    "contact": {
      "name": "FanGraph support",
      "email": "swiftapps13@gmail.com",
      "url": "https://fangraphapi.com/support"
    }
  },
  "servers": [
    {
      "url": "https://fangraphapi.com/api/v1"
    }
  ],
  "paths": {
    "/groups": {
      "get": {
        "summary": "List groups",
        "operationId": "list_groups",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/groups/{id}": {
      "get": {
        "summary": "Group details",
        "operationId": "group_details",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/groups/{id}/members": {
      "get": {
        "summary": "Group members",
        "operationId": "group_members",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/members": {
      "get": {
        "summary": "List artists",
        "operationId": "list_artists",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/members/{id}": {
      "get": {
        "summary": "Artist details",
        "operationId": "artist_details",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/releases": {
      "get": {
        "summary": "List releases",
        "operationId": "list_releases",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "artist",
            "in": "query",
            "description": "Filter by FanGraph artist entity ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Release"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/releases/upcoming": {
      "get": {
        "summary": "Upcoming releases",
        "operationId": "upcoming_releases",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "artist",
            "in": "query",
            "description": "Filter by FanGraph artist entity ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Release"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/birthdays/today": {
      "get": {
        "summary": "Birthdays today",
        "operationId": "birthdays_today",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/birthdays/{date}": {
      "get": {
        "summary": "Birthdays by MM-DD",
        "operationId": "birthdays_by_mm-dd",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{2}-\\d{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/comebacks": {
      "get": {
        "summary": "Upcoming comeback announcements",
        "operationId": "upcoming_comeback_announcements",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "artist",
            "in": "query",
            "description": "Filter by FanGraph artist entity ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Release"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "summary": "List events",
        "operationId": "list_events",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/calendar/{month}": {
      "get": {
        "summary": "Monthly calendar",
        "operationId": "monthly_calendar",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "month",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/Entity"
                          },
                          {
                            "$ref": "#/components/schemas/Release"
                          },
                          {
                            "$ref": "#/components/schemas/Event"
                          }
                        ]
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/changes": {
      "get": {
        "summary": "Approved change feed",
        "operationId": "approved_change_feed",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Change"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/random/member": {
      "get": {
        "summary": "Random artist",
        "operationId": "random_artist",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    },
    "/sources": {
      "get": {
        "summary": "Official announcement source check times and health",
        "operationId": "list_announcement_sources",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "kpop"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Data envelope. Details remain an array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "meta"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AnnouncementSource"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Missing endpoint or record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Request budget exhausted. Retry after the indicated seconds.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the exhausted window resets"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "Entity": {
        "type": "object",
        "required": ["id", "vertical_id", "kind", "slug", "name"],
        "properties": {
          "id": {
            "type": "string"
          },
          "vertical_id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": ["group", "member", "agency"]
          },
          "birth_date": {
            "type": ["string", "null"]
          },
          "debut_date": {
            "type": ["string", "null"]
          },
          "country": {
            "type": ["string", "null"]
          },
          "official_url": {
            "type": ["string", "null"]
          },
          "provenance": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Provenance"
            }
          }
        }
      },
      "Provenance": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "entity_id": {
            "type": "string"
          },
          "source_id": {
            "type": "string"
          },
          "source_record_id": {
            "type": "string"
          },
          "field": {
            "type": "string"
          },
          "value_json": {
            "type": "string"
          },
          "retrieved_at": {
            "type": "string"
          }
        }
      },
      "Release": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "vertical_id": {
            "type": "string"
          },
          "artist_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "release_date": {
            "type": "string"
          },
          "date_precision": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "source_url": {
            "type": "string"
          },
          "verified_at": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "market": {
            "type": ["string", "null"]
          },
          "announcement_source_id": {
            "type": ["string", "null"]
          }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "vertical_id": {
            "type": "string"
          },
          "artist_id": {
            "type": ["string", "null"]
          },
          "title": {
            "type": "string"
          },
          "starts_at": {
            "type": "string"
          },
          "ends_at": {
            "type": ["string", "null"]
          },
          "timezone": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "venue": {
            "type": ["string", "null"]
          },
          "source_url": {
            "type": "string"
          }
        }
      },
      "Change": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "entity_id": {
            "type": "string"
          },
          "field": {
            "type": "string"
          },
          "old_value_json": {
            "type": "string"
          },
          "new_value_json": {
            "type": "string"
          },
          "source_id": {
            "type": "string"
          },
          "source_record_id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "detected_at": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["message"],
            "properties": {
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "Meta": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "vertical": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "data_mode": {
            "type": "string",
            "enum": ["demo", "d1"]
          }
        }
      },
      "AnnouncementSource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "artist_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "health": {
            "type": "string"
          },
          "last_checked_at": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "last_success_at": {
            "type": ["string", "null"],
            "format": "date-time"
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "FanGraph developer documentation",
    "url": "https://fangraphapi.com/docs"
  }
}
