{
  "openapi": "3.1.0",
  "info": {
    "title": "TTCore LINE API",
    "version": "3.22.0",
    "description": "Unofficial persistent SelfBot API with QR/PIN login, encrypted sessions, SYNC4, reactions, reader ranges, legacy rooms, group-call URLs, OBS media and LIFF Flex. Use only with accounts and chats you own or are authorized to access."
  },
  "servers": [{"url": "https://ttcoreweb.com"}],
  "paths": {
    "/line-api/v1/sessions": {
      "post": {
        "summary": "Create an isolated QR login session",
        "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"bot_enabled": {"type": "boolean", "default": false, "description": "External clients should keep this false. Set true only to run the API's optional built-in bot."}, "proxy_mode": {"type": "string", "enum": ["auto", "none"], "default": "auto", "description": "auto assigns one encrypted, sticky server-side proxy to this LINE session. Proxy credentials are never returned."}}, "additionalProperties": false}}}},
        "responses": {
          "201": {"description": "Session created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreatedSession"}}}},
          "429": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/line-api/v1/proxies/status": {
      "get": {
        "summary": "Get the sanitized server-side proxy pool status",
        "description": "Returns aggregate capacity and health only. Proxy addresses, usernames, passwords and provider credentials are never exposed.",
        "responses": {"200": {"description": "Sanitized proxy pool status", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProxyPoolStatus"}}}}}
      }
    },
    "/line-api/v1/me": {
      "get": {"summary": "Read the current HttpOnly browser session", "responses": {"200": {"description": "Current session"}, "401": {"$ref": "#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary": "Read QR, PIN and authentication status", "security": [{"SessionToken": []}], "responses": {"200": {"description": "Session status"}, "401": {"$ref": "#/components/responses/Error"}}},
      "delete": {"summary": "Destroy the in-memory session", "security": [{"SessionToken": []}], "responses": {"200": {"description": "Deleted"}, "401": {"$ref": "#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/proxy": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {
        "summary": "Get this session's sanitized sticky proxy assignment",
        "security": [{"SessionToken": []}],
        "responses": {"200": {"description": "Sanitized proxy assignment"}, "401": {"$ref": "#/components/responses/Error"}}
      }
    },
    "/line-api/v1/sessions/{session_id}/qr.svg": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary": "Download the current QR as SVG", "security": [{"SessionToken": []}], "responses": {"200": {"description": "QR image", "content": {"image/svg+xml": {}}}, "409": {"$ref": "#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/qr.png": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary": "Download the current QR as PNG", "security": [{"SessionToken": []}], "responses": {"200": {"description": "QR image", "content": {"image/png": {}}}, "409": {"$ref": "#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/profile": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary": "Get the authenticated LINE profile", "security": [{"SessionToken": []}], "responses": {"200": {"description": "Profile"}, "409": {"$ref": "#/components/responses/Error"}}},
      "post": {"summary": "Update display name or status message", "security": [{"SessionToken": []}], "responses": {"200": {"description": "Updated profile"}, "422": {"$ref": "#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/chats": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary": "List chats", "security": [{"SessionToken": []}], "responses": {"200": {"description": "Chat list"}, "409": {"$ref": "#/components/responses/Error"}}},
      "post": {"summary":"Create a group chat","security":[{"SessionToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","member_mids"],"properties":{"name":{"type":"string"},"member_mids":{"type":"array","items":{"type":"string"}},"picture_path":{"type":"string"}}}}}},"responses":{"201":{"description":"Chat created"}}}
    },
    "/line-api/v1/sessions/{session_id}/chats/{chat_mid}": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Update group name or LINE picture path","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Chat updated"}}}
    },
    "/line-api/v1/sessions/{session_id}/chats/{chat_mid}/members": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Invite or remove chat members","security":[{"SessionToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["operation","member_mids"],"properties":{"operation":{"enum":["invite","remove"]},"member_mids":{"type":"array","minItems":1,"items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Member operation completed"},"422":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/chats/{chat_mid}/membership": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Accept, reject or leave a chat","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Membership updated"},"422":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/chats/{chat_mid}/ticket": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Open, close or reissue a group ticket","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Ticket state or value"},"422":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/sync": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary": "Fetch one SYNC4 operation batch", "security": [{"SessionToken": []}], "responses": {"200": {"description": "Operation batch"}, "409": {"$ref": "#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/messages": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {
        "summary": "Send a text or reply message",
        "security": [{"SessionToken": []}],
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["to", "text"], "properties": {"to": {"type": "string"}, "text": {"type": "string", "minLength": 1, "maxLength": 5000}, "reply_to": {"type": "string"}, "mentions": {"type":"array","maxItems":20,"items":{"type":"object","required":["mid","start","end"]}}}}}}},
        "responses": {"201": {"description": "Sent message"}, "409": {"$ref": "#/components/responses/Error"}, "502": {"$ref": "#/components/responses/Error"}}
      }
    },
    "/line-api/v1/sessions/{session_id}/messages/silent-unsend": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Silently unsend an owned message","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Message silently unsent"}}}
    },
    "/line-api/v1/sessions/{session_id}/messages/{chat_mid}": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],
      "get":{"summary":"Get recent chat messages","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Recent messages"}}}
    },
    "/line-api/v1/sessions/{session_id}/messages/read": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Mark a message as read","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Read marker sent"}}}
    },
    "/line-api/v1/sessions/{session_id}/messages/unsend": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Unsend an owned message","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Message unsent"}}}
    },
    "/line-api/v1/sessions/{session_id}/messages/contact": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Send a LINE contact card","security":[{"SessionToken":[]}],"responses":{"201":{"description":"Contact card sent"}}}
    },
    "/line-api/v1/sessions/{session_id}/reactions": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Add or cancel a message reaction","security":[{"SessionToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message_id"],"properties":{"message_id":{"type":"string"},"reaction":{"enum":["nice","love","fun","amazing","sad","omg"]},"cancel":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Reaction updated"}}}
    },
    "/line-api/v1/sessions/{session_id}/read-ranges": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "get":{"summary":"Get message read ranges for up to 100 chats","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Read ranges"}}},
      "post":{"summary":"Get message read ranges for selected chats","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Read ranges"}}}
    },
    "/line-api/v1/sessions/{session_id}/rooms": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Create a legacy room","security":[{"SessionToken":[]}],"responses":{"201":{"description":"Room created"}}}
    },
    "/line-api/v1/sessions/{session_id}/rooms/{room_mid}": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"room_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "get":{"summary":"Get a legacy room","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Room information"}}},
      "delete":{"summary":"Leave a legacy room","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Room left"}}}
    },
    "/line-api/v1/sessions/{session_id}/rooms/{room_mid}/invite": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"room_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Invite members into a legacy room","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Invited"}}}
    },
    "/line-api/v1/sessions/{session_id}/call-urls": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "get":{"summary":"List group-call URLs","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Call URLs"}}},
      "post":{"summary":"Create a group-call URL","security":[{"SessionToken":[]}],"responses":{"201":{"description":"Call URL created"}}}
    },
    "/line-api/v1/sessions/{session_id}/call-urls/{url_id}": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"url_id","in":"path","required":true,"schema":{"type":"string"}}],
      "get":{"summary":"Get group-call URL information","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Call URL"}}},
      "post":{"summary":"Update group-call URL title","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Call URL updated"}}},
      "delete":{"summary":"Delete a group-call URL","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Call URL deleted"}}}
    },
    "/line-api/v1/sessions/{session_id}/call-urls/{url_id}/join": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"url_id","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Join a chat through a group-call URL","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Joined"}}}
    },
    "/line-api/v1/sessions/{session_id}/active-call/{chat_mid}": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "get":{"summary":"Get active group-call information","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Active call"}}}
    },
    "/line-api/v1/sessions/{session_id}/active-call/{chat_mid}/kick": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Remove members from an active group call","security":[{"SessionToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["member_mids"],"properties":{"member_mids":{"type":"array","minItems":1,"items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Members removed from active call"}}}
    },
    "/line-api/v1/sessions/{session_id}/active-call/{chat_mid}/invite": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"},{"name":"chat_mid","in":"path","required":true,"schema":{"type":"string"}}],
      "post":{"summary":"Invite members to an active group call","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Members invited"}}}
    },
    "/line-api/v1/sessions/{session_id}/reports": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Submit a LINE message abuse report","description":"Requires message_id, sender_mid and a reason: advertising, harassment, impersonation, scam or other.","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Report submitted"}}}
    },
    "/line-api/v1/sessions/{session_id}/media": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {"summary": "Upload and send binary image, GIF, video, audio or file", "security": [{"SessionToken": []}], "parameters": [{"name":"X-Line-To","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Media-Type","in":"header","required":true,"schema":{"enum":["image","gif","video","audio","file"]}},{"name":"X-Filename","in":"header","schema":{"type":"string"}}], "requestBody":{"required":true,"content":{"application/octet-stream":{}}}, "responses":{"201":{"description":"Media sent"},"429":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/media-url": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {"summary":"Fetch a bounded public HTTPS object and send it","security":[{"SessionToken":[]}],"responses":{"201":{"description":"Media sent"},"422":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/media/{message_id}": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary":"Download message media","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Binary media"}}}
    },
    "/line-api/v1/sessions/{session_id}/youtube": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {"summary":"Download and send one bounded YouTube video (no playlists)","security":[{"SessionToken":[]}],"responses":{"201":{"description":"Video sent"},"422":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/profile-image": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {"summary":"Update profile image","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Updated"}}}
    },
    "/line-api/v1/sessions/{session_id}/profile-cover": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {"summary":"Update profile cover","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Updated"}}}
    },
    "/line-api/v1/sessions/{session_id}/contacts/{mid}": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary":"Get detailed contact data","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Contact"}}}
    },
    "/line-api/v1/sessions/{session_id}/contacts": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary":"List friend contact MIDs","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Friend MID list"}}}
    },
    "/line-api/v1/sessions/{session_id}/contacts/add": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {
        "summary": "Add an eligible LINE friend",
        "description": "The target must either be a member of a shared group or currently appear in LINE friend recommendations. LINE protocol details are handled internally and are not part of the public API contract.",
        "security": [{"SessionToken":[]}],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": ["mid", "source", "chat_mid"],
                    "properties": {
                      "mid": {"type": "string", "pattern": "^u[0-9a-fA-F]{32}$"},
                      "source": {"type": "string", "const": "group"},
                      "chat_mid": {"type": "string", "pattern": "^c[0-9a-fA-F]{32}$"}
                    },
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "required": ["mid", "source"],
                    "properties": {
                      "mid": {"type": "string", "pattern": "^u[0-9a-fA-F]{32}$"},
                      "source": {"type": "string", "const": "recommendation"}
                    },
                    "additionalProperties": false
                  }
                ]
              },
              "examples": {
                "sharedGroup": {"summary": "Shared group member", "value": {"mid": "u0123456789abcdef0123456789abcdef", "source": "group", "chat_mid": "c0123456789abcdef0123456789abcdef"}},
                "recommendation": {"summary": "Friend recommendation", "value": {"mid": "u0123456789abcdef0123456789abcdef", "source": "recommendation"}}
              }
            }
          }
        },
        "responses": {
          "201": {"description": "Friend added"},
          "422": {"$ref": "#/components/responses/Error"},
          "502": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/line-api/v1/sessions/{session_id}/liff-token": {
      "parameters": [{"$ref":"#/components/parameters/SessionId"}],
      "post":{"summary":"Issue a scoped LIFF token for a chat","security":[{"SessionToken":[]}],"responses":{"200":{"description":"Short-lived LIFF access token"},"409":{"$ref":"#/components/responses/Error"}}}
    },
    "/line-api/v1/sessions/{session_id}/flex": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {"summary":"Send a validated LIFF Flex bubble or carousel","security":[{"SessionToken":[]}],"responses":{"201":{"description":"Flex sent"}}}
    },
    "/line-api/v1/sessions/{session_id}/flex/templates": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "get": {"summary":"List built-in Flex templates","security":[{"SessionToken":[]}],"responses":{"200":{"description":"menu, profile, group and api templates"}}}
    },
    "/line-api/v1/sessions/{session_id}/bot": {
      "parameters": [{"$ref": "#/components/parameters/SessionId"}],
      "post": {
        "summary": "Start or stop the persistent SelfBot",
        "security": [{"SessionToken": []}],
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}}}}}},
        "responses": {"200": {"description": "Updated bot state"}, "409": {"$ref": "#/components/responses/Error"}}
      }
    }
  },
  "components": {
    "securitySchemes": {
      "SessionToken": {"type": "http", "scheme": "bearer"}
    },
    "parameters": {"SessionId": {"name": "session_id", "in": "path", "required": true, "schema": {"type": "string"}}},
    "schemas": {
      "CreatedSession": {"type": "object", "required": ["session_id", "session_token", "status_url", "qr_url", "qr_png_url", "expires_at"], "properties": {"session_id": {"type": "string"}, "session_token": {"type": "string"}, "status_url": {"type": "string"}, "qr_url": {"type": "string"}, "qr_png_url": {"type": "string"}, "expires_at": {"type": "integer"}}},
      "ProxyPoolStatus": {"type": "object", "properties": {"enabled": {"type": "boolean"}, "total": {"type": "integer"}, "healthy": {"type": "integer"}, "available": {"type": "integer"}, "leased": {"type": "integer"}, "degraded": {"type": "integer"}, "last_refresh": {"type": "integer"}, "refresh_ok": {"type": "boolean"}}}
    },
    "responses": {
      "Error": {
        "description": "Error response",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {"type": "object"}
              }
            }
          }
        }
      }
    }
  }
}
