PHP 8.3+ SDK for the Trovo.live API.
composer require notwonderful/trovo-sdkuse Notwonderful\TrovoSdk\TrovoClient;
use Notwonderful\TrovoSdk\Config;
use Notwonderful\TrovoSdk\Enum\Scope;
$trovo = new TrovoClient(new Config(
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
redirectUri: 'https://example.com/callback',
));// 1. Redirect user to Trovo login
$url = $trovo->getAuthorizationCodeUrl(
scopes: [Scope::UserDetailsSelf, Scope::ChannelDetailsSelf],
state: 'random_csrf_token',
);
// 2. After redirect, exchange code for tokens
$token = $trovo->exchangeCode($_GET['code']);
// $token->accessToken, $token->refreshToken, $token->expiresIn
// 3. Set the token for subsequent API calls
$trovo->setAccessToken($token->accessToken);$url = $trovo->getImplicitFlowUrl(
scopes: [Scope::UserDetailsSelf],
state: 'random_csrf_token',
);
// Access token will be in the URL fragment after redirect// Refresh
$newToken = $trovo->refreshToken($token->refreshToken);
// Validate
$info = $trovo->validateToken($token->accessToken);
// $info->uid, $info->scopes, $info->expireTs, $info->isExpired()
// Revoke
$trovo->revokeToken($token->accessToken);// Top categories (sorted by popularity)
$categories = $trovo->categories()->getTopCategories();
// returns Category[] — id, name, shortName, iconUrl, desc
// Search
$result = $trovo->categories()->search(query: 'apex', limit: 10);
// $result->items (Category[]), $result->hasMore// Top live channels with pagination
$page = $trovo->channels()->getTopChannels(limit: 20);
// $page->items (Channel[]), $page->totalPage, $page->cursor, $page->token
// Next page
$page2 = $trovo->channels()->getTopChannels(
limit: 20,
after: true,
token: $page->token,
cursor: $page->cursor,
);
// Channel info by ID or username
$channel = $trovo->channels()->getById(channelId: 100000031);
$channel = $trovo->channels()->getById(username: 'username');
// Own channel with stream key (requires channel_details_self)
$my = $trovo->channels()->getMy();
// $my->streamKey, $my->isLive, $my->title, ...
// Update channel (requires channel_update_self)
use Notwonderful\TrovoSdk\Enum\AudienceType;
$trovo->channels()->update(
channelId: 100000031,
liveTitle: 'New title',
categoryId: '10023',
languageCode: 'EN',
audiType: AudienceType::Teen,
);
// Followers
$followers = $trovo->channels()->getFollowers(channelId: 100000031, limit: 50);
// $followers->items (Follower[]), $followers->total, $followers->totalPage
// Viewers (grouped by role)
$viewers = $trovo->channels()->getViewers(channelId: 100000031);
// $viewers['chatters']['moderators']['viewers'], $viewers['total'], ...// Lookup by usernames
$users = $trovo->users()->getByUsernames(['user1', 'user2']);
// returns User[] — userId, userName, nickName, channelId
// Authenticated user info (requires user_details_self)
$me = $trovo->users()->getUserInfo();
// $me->userId, $me->userName, $me->email, $me->profilePicuse Notwonderful\TrovoSdk\Enum\SortDirection;
// Requires channel_subscriptions scope
$subs = $trovo->subscribers()->get(
channelId: 100000031,
limit: 50,
offset: 0,
direction: SortDirection::Desc,
);
// $subs->items (Subscriber[]), $subs->total
// Subscriber: userId, username, displayName, subCreatedAt, subLv, subTieruse Notwonderful\TrovoSdk\Enum\EmoteType;
$emotes = $trovo->emotes()->get(
emoteType: EmoteType::All,
channelIds: [100000031],
);
// Raw array: globalEmotes, eventEmotes, customizedEmotes// Live stream URLs (restricted access)
$urls = $trovo->streams()->getLiveStreamUrls(channelId: 100000031);
// returns StreamUrl[] — playUrl, desc (resolution)
// Past streams
use Notwonderful\TrovoSdk\Enum\Period;
$past = $trovo->streams()->getPastStreams(
channelId: 100000031,
period: Period::Month,
limit: 10,
);
// $past->items (PastStream[]), $past->total, $past->totalPage$clips = $trovo->clips()->get(
channelId: 100000031,
period: Period::Week,
limit: 20,
);
// $clips->items (Clip[]) — clipId, title, url, thumbnail, duration, views, likes// Send to own channel (requires chat_send_self)
$trovo->chat()->sendToMyChannel('Hello!');
// Send to another channel (requires chat_send_self + send_to_my_channel)
$trovo->chat()->sendToChannel('Hello!', channelId: 100000031);
// Delete message (requires manage_messages)
$trovo->chat()->deleteMessage(
channelId: '100000031',
messageId: 'msg_123',
userId: '100000021',
);
// Chat commands (requires manage_messages)
$result = $trovo->chat()->performCommand('mod @username', channelId: 100000031);
// $result->isSuccess, $result->displayMsgDrops APIs use Trovo Signature (HMAC-SHA1) automatically:
use Notwonderful\TrovoSdk\Enum\FulfillmentStatus;
$drops = $trovo->drops()->getEntitlements(
limit: 50,
fulfillmentStatus: FulfillmentStatus::Claimed,
);
// $drops->items (DropEntitlement[]), $drops->total, $drops->hasMore
$results = $trovo->drops()->updateEntitlements(
entitlementIds: ['ent_1', 'ent_2'],
fulfillmentStatus: FulfillmentStatus::Fulfilled,
);
// returns DropUpdateResult[] — entitlementId, status, isSuccess()The package auto-registers its ServiceProvider via Laravel's package discovery.
Add credentials to your .env:
TROVO_CLIENT_ID=your_client_id
TROVO_CLIENT_SECRET=your_client_secret
TROVO_REDIRECT_URI=https://example.com/callbackOptionally publish the config:
php artisan vendor:publish --tag=trovo-configThen resolve from the container:
use Notwonderful\TrovoSdk\TrovoClient;
$trovo = app(TrovoClient::class);
$categories = $trovo->categories()->getTopCategories();Or inject via constructor:
public function __construct(private TrovoClient $trovo) {}use Notwonderful\TrovoSdk\Exception\ApiException;
use Notwonderful\TrovoSdk\Exception\AuthenticationException;
use Notwonderful\TrovoSdk\Exception\RateLimitException;
try {
$user = $trovo->users()->getUserInfo();
} catch (RateLimitException $e) {
// $e->limit, $e->remaining, $e->resetsAt, $e->getSecondsUntilReset()
sleep($e->getSecondsUntilReset());
} catch (AuthenticationException $e) {
// Access token missing or not set
} catch (ApiException $e) {
// $e->statusCode (HTTP), $e->trovoErrorCode, $e->trovoError, $e->getMessage()
}Implement HttpClientInterface to use your own HTTP client or for testing:
use Notwonderful\TrovoSdk\Http\HttpClientInterface;
$trovo = new TrovoClient($config, new MyCustomHttpClient());| Enum | Value | Description |
|---|---|---|
Scope::UserDetailsSelf |
user_details_self |
View email and user profile |
Scope::ChannelDetailsSelf |
channel_details_self |
View channel details + stream key |
Scope::ChannelUpdateSelf |
channel_update_self |
Update channel settings |
Scope::ChannelSubscriptions |
channel_subscriptions |
Get subscribers list |
Scope::ChatSendSelf |
chat_send_self |
Send chat messages |
Scope::SendToMyChannel |
send_to_my_channel |
Allow others to send to your channel |
Scope::ManageMessages |
manage_messages |
Delete messages and chat commands |
If you like this package, please consider giving it a star ⭐ on GitHub!
