This is an unofficial API wrapper for TikTok LIVE written in Python. With this API you can connect to any TikTok livestream and fetch all data available to users in a stream using just a creator's @unique_id.
For enterprise-level service & greater rate limits, sign up with Euler Stream today:
![]() |
Euler Stream provides increased rate limits, TikTok LIVE alerts, JWT authentication and more for enterprise customers. It offers generous tiers starting at $0. |
Join the TikTokLive discord and visit the #py-support channel for questions, contributions and ideas.
pip install TikTokLive
from TikTokLive import TikTokLiveClient
from TikTokLive.events import ConnectEvent, CommentEvent
# Create the client
client: TikTokLiveClient = TikTokLiveClient(unique_id="@isaackogz")
# Listen to an event with a decorator!
@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
print(f"Connected to @{event.unique_id} (Room ID: {client.room_id}")
# Or, add it manually via "client.add_listener()"
async def on_comment(event: CommentEvent) -> None:
print(f"{event.user.nickname} -> {event.comment}")
client.add_listener(CommentEvent, on_comment)
if __name__ == '__main__':
# Run the client and block the main thread
# await client.start() to run non-blocking
client.run()
For more quickstart examples, see the examples folder provided in the source tree.
TikTokLive is available in several alternate programming languages:
| Param Name | Required | Default | Description |
|---|---|---|---|
| unique_id | Yes | N/A | The unique username of the broadcaster. You can find this name in the URL of the user. For example, the unique_id for https://www.tiktok.com/@isaackogz would be isaackogz. |
| web_proxy | No | None |
TikTokLive supports proxying HTTP requests. This parameter accepts an httpx.Proxy. Note that if you do use a proxy you may be subject to reduced connection limits at times of high load. |
| ws_proxy | No | None |
TikTokLive supports proxying the websocket connection. This parameter accepts an httpx.Proxy. Using this proxy will never be subject to reduced connection limits. |
| web_kwargs | No | {} |
Under the scenes, the TikTokLive HTTP client uses the httpx library. Arguments passed to web_kwargs will be forward the the underlying HTTP client. |
| ws_kwargs | No | {} |
Under the scenes, TikTokLive uses the websockets library to connect to TikTok. Arguments passed to ws_kwargs will be forwarded to the underlying WebSocket client. |
A TikTokLiveClient object contains the following methods worth mentioning:
| Method Name | Notes | Description |
|---|---|---|
| run | N/A | Connect to the livestream and block the main thread. This is best for small scripts. |
| add_listener | N/A | Adds an asynchronous listener function (or, you can decorate a function with @client.on(Type[Event])) and takes two parameters, an event name and the payload, an AbstractEvent |
| connect | async |
Connects to the tiktok live chat while blocking the current future. When the connection ends (e.g. livestream is over), the future is released. |
| start | async |
Connects to the live chat without blocking the main thread. This returns an asyncio.Task object with the client loop. |
| disconnect | async |
Disconnects the client from the websocket gracefully, processing remaining events before ending the client loop. |
A TikTokLiveClient object contains the following important properties:
| Attribute Name | Description |
|---|---|
| room_id | The Room ID of the livestream room the client is currently connected to. |
| web | The TikTok HTTP client. This client has a lot of useful routes you should explore! |
| connected | Whether you are currently connected to the livestream. |
| logger | The internal logger used by TikTokLive. You can use client.logger.setLevel(...) method to enable client debug. |
| room_info | Room information that is retrieved from TikTok when you use a connection method (e.g. client.connect) with the keyword argument fetch_room_info=True . |
| gift_info | Extra gift information that is retrieved from TikTok when you use a connection method (e.g. client.run) with the keyword argument fetch_gift_info=True. |
TikTokLive has a series of global defaults used to create the HTTP client which you can customize. For info on how to set these parameters, see the web_defaults.py example.
| Parameter | Type | Description |
|---|---|---|
| tiktok_sign_api_key | str |
A Euler Stream API key used to increase rate limits. |
| tiktok_app_url | str |
The TikTok app URL (https://www.tiktok.com) used to scrape the room. |
| tiktok_sign_url | str |
The signature server used to generate tokens to connect to TikTokLive. By default, this is Euler Stream, but you can swap your own with ease. |
| tiktok_webcast_url | str |
The TikTok livestream URL (https://webcast.tiktok.com) where livestreams can be accessed from. |
| web_client_params | dict |
The URL parameters added on to TikTok requests from the HTTP client. |
| web_client_headers | dict |
The headers added on to TikTok requests from the HTTP client. |
| web_client_cookies | dict |
Custom cookies to initialize the http client with. |
| ws_client_params | dict |
The URL parameters added to the URI when connecting to TikTok's Webcast WebSocket server. |
| ws_client_params_append_str | dict |
Extra string data to append to the TikTokLive WebSocket connection URI. |
| ws_client_headers | dict |
Extra headers to append to the TikTokLive WebSocket client. |
| ja3_impersonate | str |
The ja3 fingerprint to impersonate. This should match whatever the current version is on the Sign Server, or "privileged" methods will fail. |
Events can be listened to using a decorator or non-decorator method call. The following examples illustrate how you can listen to an event:
@client.on(LikeEvent)
async def on_like(event: LikeEvent) -> None:
...
async def on_comment(event: CommentEvent) -> None:
...
client.add_listener(CommentEvent, on_comment)
There are two types of events, CustomEvent events and ProtoEvent events. Both belong to the TikTokLive Event type and can be listened to. The following events are available:
ConnectEvent - Triggered when the Webcast connection is initiatedDisconnectEvent - Triggered when the Webcast connection closes (including the livestream ending)LiveEndEvent - Triggered when the livestream endsLivePauseEvent - Triggered when the livestream is pausedLiveUnpauseEvent - Triggered when the livestream is unpausedFollowEvent - Triggered when a user in the livestream follows the streamerShareEvent - Triggered when a user shares the livestreamWebsocketResponseEvent - Triggered when any event is received (contains the event)UnknownEvent - An instance of WebsocketResponseEvent thrown whenever an event does not have an existing definition, useful for debuggingIf you know what an event does, make a pull request and add the description.
GiftEvent - Triggered when a gift is sent to the streamerGoalUpdateEvent - Triggered when the subscriber goal is updatedControlEvent - Triggered when a stream action occurs (e.g. Livestream start, end)LikeEvent - Triggered when the stream receives a likeSubscribeEvent - Triggered when someone subscribes to the TikTok creatorPollEvent - Triggered when the creator launches a new pollCommentEvent - Triggered when a comment is sent in the streamRoomEvent - Messages broadcasted to all users in the room (e.g. "Welcome to TikTok LIVE!")EmoteChatEvent - Triggered when a custom emote is sent in the chatEnvelopeEvent - Triggered every time someone sends a treasure chestSocialEvent - Triggered when a user shares the stream or follows the hostQuestionNewEvent - Triggered every time someone asks a new question via the question featureLiveIntroEvent - Triggered when a live intro message appearsLinkMicArmiesEvent - Triggered when a TikTok battle user receives pointsLinkMicBattleEvent - Triggered when a TikTok battle is startedJoinEvent - Triggered when a user joins the livestreamLinkMicFanTicketMethodEventLinkMicMethodEventBarrageEvent - Triggered when a "VIP" viewer (based on their gifting level) joins the live chat roomCaptionEventImDeleteEvent - Triggered when a viewer's messages are deletedRoomUserSeqEvent - Current viewer count informationRankUpdateEventRankTextEvent - Triggered when gift count makes a viewer one of the top threeHourlyRankEventUnauthorizedMemberEventMessageDetectEventOecLiveShoppingEventRoomPinEvent - Triggered when a message is pinnedSystemEventLinkEventLinkLayerEventKaraokeQueueListEventGroupLiveMemberNotifyEventSubscriptionGuideEventNoticeboardReviewEventBottomEventCapsuleEventLinkMicBattleEventQuestionSelectedEventTrayEventAssetEventWalletLiveRewardsRatioEventLinkScreenChangeEventPartnershipPunishEventGiftPanelUpdateEventAnchorTaskReminderEventLinkBusinessEventMarqueeAnnouncementEventGiftDynamicRestrictionEventCommonPopupEventEcBarrageEventPromoteAdStatusEventInteractionHubGoalEventEpiEventLinkmicAnimationEventKaraokeYouSingReqEventRealTimePerformancePageEventStreamStatusEventGiftCollectionUpdateEventCommercialCustomEventGuideEventDonationEventLiveGameIntroEventPartnershipDropsCardChangeEventGameGuessWidgetsEventMiddleTouchEventUserStatsEventWallpaperReviewEventLinkMicAdEventSubTimerStickerEventGiftGalleryEventGiftUpdateEventNoticeboardEventUpgradeEventBackpackEventAvatarStyleResultEventGameSettingChangeEventPartnershipDropsUpdateEventQuestionSwitchEventLiveInfoAuditNoticeEventCommonToastEventToastEventDonationStickerModifyMethodEventPollEventHighlightFragementReadyEventGiftPromptEventForceFetchRecommendationsEventGameGuessPinCardEventLinkLayoutEventGameOcrPingEventAnchorGrowLevelEventEnvelopePortalEventCohostReserveEventBaLeadGenEventPictionaryEndEventRoomNotifyEventFansEventEventKaraokeQueueEventFollowCardEventActivityQuizUserIdentityEventLiveJourneyEventCommentsEventWeeklyRankRewardEventLinkStateEventAccessRecallEventAiSummaryEventPerceptionEventRoomVerifyEventGuideTaskEventVideoLiveCouponRcmdEventVideoLiveGoodsRcmdEventKaraokeSwitchEventPrivilegeAdvanceEventLinkMicBattlePunishFinishEventBoostedUsersEventRankToastEventCommentTrayEventAnchorReminderWordEventPaidContentLiveShoppingEventRoomEventEventRoomBottomEventDonationInfoEventGameMomentEventHashtagEventLinkMicBattleItemCardEventPrivilegeDynamicEffectEventAnchorGetSubQuotaEventOecLiveHotRoomEventAudienceReserveUserStateEventRealtimeLiveCenterMethodEventWallpaperEventSubPinEventEventLinkmicBattleTaskEventStarCommentPushEventEcTaskRefreshCouponListEventShortTouchEventEffectControlEventKaraokeRedDotEventQuestionDeleteEventInRoomBannerEventShareGuideEventEventEventInRoomBannerEventEventPlayTogetherEventSubContractStatusEventHourlyRankRewardEventPictionaryStartEventGuestInviteEventNoticeEventPartnershipDownloadCountEventGreetingEventLiveShowEventSubWaveEventGameReqSetGuessEventSpeakerEventLinkMicAnchorGuideEventCompetitionEventAvatarReportDeleteEventEffectPreloadingEventColdStartEventCountdownForAllEventGiftBroadcastEventPreviewGameMomentEventGameRecommendCreateGuessEventVideoLiveGoodsOrderEventStarCommentNotificationEventInRoomBannerRefreshEventRoomStickerEventGiftProgressEventOecLiveManagerEventDiggEventAiLiveSummaryEventAnchorToolModificationEventMgPunishCenterActionEventPictionaryExitEventCountdownEventGameServerFeatureEventPlaybookEventGiftRecordCapsuleEventQuickChatListEventPartnershipCardChangeEventScreenChatEventGameEmoteUpdateEventBoostCardEventRoomStreamAdaptationEventLinkmicBattleNoticeEventGoodyBagEventGiftEventTriggered every time a gift arrives. Extra information can be gleamed from the available_gifts client attribute.
NOTE: Users have the capability to send gifts in a streak. This increases the
event.gift.repeat_countvalue until the user terminates the streak. During this time new gift events are triggered again and again with an increasedevent.gift.repeat_countvalue. It should be noted that after the end of a streak, a final gift event is triggered, which signals the end of the streak withevent.repeat_end:1. The following handlers show how you can deal with this in your code.
Using the low-level direct proto:
@client.on(GiftEvent)
async def on_gift(event: GiftEvent):
# If it's type 1 and the streak is over
if event.gift.info.type == 1:
if event.gift.is_repeating == 1:
print(f"{event.user.unique_id} sent {event.repeat_count}x \"{event.gift.name}\"")
# It's not type 1, which means it can't have a streak & is automatically over
elif event.gift.info.type != 1:
print(f"{event.user.unique_id} sent \"{event.gift.name}\"")
Using the TikTokLive extended proto:
@client.on("gift")
async def on_gift(event: GiftEvent):
# Streakable gift & streak is over
if event.gift.streakable and not event.streaking:
print(f"{event.user.unique_id} sent {event.repeat_count}x \"{event.gift.name}\"")
# Non-streakable gift
elif not event.gift.streakable:
print(f"{event.user.unique_id} sent \"{event.gift.name}\"")
SubscribeEventThis event will only fire when a session ID (account login) is passed to the HTTP client before connecting to TikTok LIVE. You can set the session ID with client.web.set_session_id(...).
It is considered inefficient to use the connect method to check if a user is live. It is better to use the dedicated await client.is_live() method.
There is a complete example of how to do this in the examples folder.
This project is licensed under the MIT License - see the LICENSE file for details.
See also the full list of secondary contributors who have participated in this project.