{
  "openapi": "3.1.0",
  "info": {
    "title": "TVizle.tr Açık API",
    "version": "1.0.0",
    "summary": "Televizyon kanalı künyeleri, yayın akışı ve birleşik arama.",
    "description": "TVizle.tr'nin kamuya açık, anahtarsız API'si. Kanal künyeleri iptv-org açık veri deposundan türetilir ve günlük yenilenir. Site hiçbir yayını barındırmaz veya saklamaz; kamuya açık adresleri dizinler. Uçlar salt-okunurdur ve CORS ile her kökene açıktır.\n\nHız sınırı uygulanmaz; ancak `limit` üst sınırlarına uyulması beklenir. Yanıtlar `Cache-Control` ile önbelleklenebilir.",
    "termsOfService": "https://tvizle.tr/kullanim-sartlari",
    "contact": {
      "name": "TVizle",
      "email": "yasal@tvizle.tr",
      "url": "https://tvizle.tr/iletisim"
    },
    "license": {
      "name": "CC BY-SA 4.0",
      "url": "https://creativecommons.org/licenses/by-sa/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://tvizle.tr",
      "description": "Üretim"
    }
  ],
  "externalDocs": {
    "description": "Ajanlar için özet",
    "url": "https://tvizle.tr/llms-full.txt"
  },
  "tags": [
    {
      "name": "kanallar",
      "description": "Kanal künyeleri ve listeleme."
    },
    {
      "name": "arama",
      "description": "Birleşik arama."
    },
    {
      "name": "ajan",
      "description": "Makine okunur keşif belgeleri."
    }
  ],
  "paths": {
    "/api/kanallar": {
      "get": {
        "tags": [
          "kanallar"
        ],
        "summary": "Kanalları listele veya tek kanal künyesi getir",
        "operationId": "kanallariListele",
        "parameters": [
          {
            "name": "slug",
            "in": "query",
            "required": false,
            "description": "Verilirse yalnızca bu kanalın künyesi döner.",
            "schema": {
              "type": "string",
              "examples": [
                "trt-1"
              ]
            }
          },
          {
            "name": "slugs",
            "in": "query",
            "required": false,
            "description": "Virgülle ayrılmış kanal kimlikleri.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Kanal listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KanalListesi"
                }
              }
            }
          },
          "404": {
            "description": "Kanal bulunamadı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Hata"
                }
              }
            }
          }
        }
      }
    },
    "/api/ara": {
      "get": {
        "tags": [
          "arama"
        ],
        "summary": "Kanal, program, kategori, ülke, dil ve bölgede birleşik arama",
        "operationId": "ara",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Aranacak metin.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "examples": [
                "trt"
              ]
            }
          },
          {
            "name": "tur",
            "in": "query",
            "required": false,
            "description": "Sonucu tek türle sınırla.",
            "schema": {
              "type": "string",
              "enum": [
                "channel",
                "programme",
                "category",
                "country",
                "language",
                "region"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Türlerine göre gruplanmış eşleşmeler.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AramaSonucu"
                }
              }
            }
          }
        }
      }
    },
    "/api/md": {
      "get": {
        "tags": [
          "ajan"
        ],
        "summary": "Bir sayfanın markdown karşılığını getir",
        "description": "HTML ayrıştırmadan aynı bilgiyi veren markdown çıktısı. `Accept: text/markdown` başlığıyla sayfanın kendisine gidildiğinde de aynı yanıt döner.",
        "operationId": "markdown",
        "parameters": [
          {
            "name": "yol",
            "in": "query",
            "required": true,
            "description": "Site içi yol.",
            "schema": {
              "type": "string",
              "examples": [
                "/izle/trt-1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Markdown belge.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Bu yol için markdown karşılığı yok.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/img": {
      "get": {
        "tags": [
          "kanallar"
        ],
        "summary": "Kanal logosunu vekil üzerinden getir",
        "description": "Uzak logoyu HTTPS üzerinden yeniden sunar; karışık içerik ve CORS sorunlarını ortadan kaldırır.",
        "operationId": "logo",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Kaynak logo adresi.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Görsel.",
            "content": {
              "image/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Geçersiz adres.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Hata"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/mcp.json": {
      "get": {
        "tags": [
          "ajan"
        ],
        "summary": "MCP keşif belgesi",
        "operationId": "mcpKesif",
        "responses": {
          "200": {
            "description": "MCP sunucu tanımı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agent.json": {
      "get": {
        "tags": [
          "ajan"
        ],
        "summary": "A2A ajan kartı",
        "operationId": "a2aKart",
        "responses": {
          "200": {
            "description": "Ajan kartı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": [
          "ajan"
        ],
        "summary": "Dil modelleri için site özeti",
        "operationId": "llmsTxt",
        "responses": {
          "200": {
            "description": "Düz metin özet.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "yonetimOturumu": {
        "type": "apiKey",
        "in": "cookie",
        "name": "tvizle_yonetim",
        "description": "Yalnızca /api/yonetim/* uçları için. HMAC imzalı, httpOnly oturum çerezi; /yonetim üzerinden parolayla alınır. Kamuya açık uçların hiçbiri kimlik doğrulama istemez."
      }
    },
    "schemas": {
      "Kanal": {
        "type": "object",
        "required": [
          "slug",
          "id",
          "name"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "description": "Site içi kanal kimliği."
          },
          "id": {
            "type": "string",
            "description": "iptv-org kanal kodu."
          },
          "name": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "quality": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "website": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "playable": {
            "type": "boolean",
            "description": "Tarayıcıda doğrudan izlenebiliyor mu."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "İzleme sayfası."
          }
        }
      },
      "KanalListesi": {
        "type": "object",
        "required": [
          "channels"
        ],
        "properties": {
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "channels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Kanal"
            }
          }
        }
      },
      "AramaSonucu": {
        "type": "object",
        "properties": {
          "q": {
            "type": "string"
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "channel",
                    "programme",
                    "category",
                    "country",
                    "language",
                    "region"
                  ]
                },
                "hits": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "sub": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Hata": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          }
        }
      }
    }
  }
}