{
  "openapi": "3.1.0",
  "info": {
    "title": "TikLive Public LIVE API",
    "version": "1.0.0",
    "description": "Public TikTok LIVE metadata and event streams. API accounts and keys are separate from TikLive application accounts. API keys are sent in the X-API-Key header and must never be exposed in browser code."
  },
  "servers": [{ "url": "https://api.tiklive.eu" }],
  "tags": [{ "name": "LIVE" }, { "name": "Usage" }],
  "components": {
    "securitySchemes": { "ApiKey": { "type": "apiKey", "in": "header", "name": "X-API-Key" } },
    "schemas": {
      "Error": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": ["error"] },
      "Room": { "type": "object", "description": "Public room fields returned by the upstream connector. Fields can vary by LIVE state.", "properties": { "username": { "type": "string" }, "isLive": { "type": "boolean" }, "roomId": { "type": ["string", "null"] }, "viewerCount": { "type": ["integer", "null"] }, "title": { "type": ["string", "null"] } }, "additionalProperties": true }
    }
  },
  "paths": {
    "/v1/live/{username}": {
      "get": {
        "tags": ["LIVE"], "summary": "Get public LIVE room information", "security": [{ "ApiKey": [] }],
        "parameters": [{ "name": "username", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[A-Za-z0-9._]{2,30}$" } }],
        "responses": {
          "200": { "description": "Public room information", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Room" } } }, "headers": { "X-RateLimit-Limit": { "schema": { "type": "integer" } }, "X-RateLimit-Remaining": { "schema": { "type": "integer" } }, "X-RateLimit-Reset": { "schema": { "type": "integer" } } } },
          "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Daily quota reached" }, "502": { "description": "TikTok upstream temporarily unavailable" }
        }
      }
    },
    "/v1/usage": { "get": { "tags": ["Usage"], "summary": "Get today's API usage", "security": [{ "ApiKey": [] }], "responses": { "200": { "description": "Daily usage and quota" }, "401": { "description": "Invalid API key" } } } },
    "/v1/live/{username}/events": {
      "get": { "tags": ["LIVE"], "summary": "Realtime events WebSocket", "description": "Connect using wss://api.tiklive.eu/v1/live/{username}/events, then send {\"apiKey\":\"tlapi_...\"} as the first WebSocket message within 5 seconds. Events include ready, status, connected, disconnected, live, chat, gift, like, viewers, member, social and streamEnd. A connection uses one concurrent LIVE slot. Daily REST request quotas apply only to REST calls.", "parameters": [{ "name": "username", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[A-Za-z0-9._]{2,30}$" } }], "responses": { "101": { "description": "WebSocket connection upgraded" }, "401": { "description": "API key required in first message" }, "4429": { "description": "Concurrent LIVE limit reached" } } }
    }
  }
}
