A native Kotlin library for interacting with the Kick.com streaming platform API. Kick4k provides easy-to-use clients for major Kick endpoints, OAuth 2.0 authentication with PKCE support, and a lightweight event dispatcher for real-time style workflows.
- Complete API Coverage: Support for all official Kick.com API endpoints
- User management and authentication
- Channel operations and metadata
- Chat messaging
- Livestream management
- Moderation tools
- Categories and discovery
- Event subscriptions
- OAuth 2.0 with PKCE: Secure authentication flow implementation
- Webhook Support: Built-in webhook receiver with signature verification, for demonstration purposes
- Event System: Type-safe event handling for real-time notifications
- Flexible Configuration: Customizable endpoints and settings
- Stateless Auth: Bring your own tokens per call; helpers for code exchange and refresh
Add the dependency to your build.gradle.kts (or Groovy equivalent):
dependencies {
implementation("com.github.mbayou:kick4k:1.4.4")
}Kick4k is distributed through JitPack. Add the repository and depend on a tag or branch build as shown below:
repositories {
maven { url = uri("https://jitpack.io") }
}
dependencies {
implementation("com.github.mbayou:kick4k:1.4.4")
// or use a specific git tag / commit
}Every push to GitHub can be built on JitPack; tagging a release (for example 1.4.4) gives you a stable coordinate
com.github.mbayou:kick4k:1.4.4. See docs/PUBLISHING.md for the release checklist.
Looking for a deeper walkthrough of OAuth, webhooks, and the major APIs? Check the Usage Guide.
import com.mbayou.kick4k.KickClient
import com.mbayou.kick4k.KickConfiguration
val config = KickConfiguration.builder()
.clientId("your-client-id")
.clientSecret("your-client-secret")
.redirectUri("http://localhost:8080/callback")
.build()
val client = KickClient(config)import com.mbayou.kick4k.authorization.Scope
// Generate PKCE codes
val codeVerifier = client.authorization().generateCodeVerifier()
val codeChallenge = client.authorization().generateCodeChallenge(codeVerifier)
// Get authorization URL
val authUrl = client.authorization().getAuthorizationUrl(
scopeList = listOf(Scope.USER_READ, Scope.CHANNEL_READ, Scope.CHAT_WRITE),
codeChallenge = codeChallenge,
redirectUri = "http://localhost:8080/callback" // Optional override per flow
)
println("Visit: $authUrl")
// After user authorization, exchange code for tokens
val tokenResponse = client.authorization().exchangeCodeForToken(
code = "code-from-callback",
codeVerifier = codeVerifier,
redirectUri = "http://localhost:8080/callback"
)
val accessToken = tokenResponse.accessToken
val refreshToken = tokenResponse.refreshToken
// Later, refresh explicitly when you need a new access token
val refreshed = client.authorization().refreshWithToken(refreshToken)
val newAccessToken = refreshed.accessTokenIf your Kick application is configured with multiple redirect URIs (for example dev/staging/prod),
store the URI you used when generating the authorization URL and provide it to
getAuthorizationUrl and exchangeCodeForToken. When omitted those methods fall back to the
redirectUri defined in KickConfiguration.
// Get current user
val currentUser = client.users().getCurrentUser(accessToken)
println("Hello, ${currentUser.displayName}")
// Get current channel
val channel = client.channels().getCurrentChannel(accessToken)
println("Channel: ${channel.slug}")
// Send a chat message
client.chat().postChatMessage(accessToken, PostChatMessageRequest.builder()
.broadcasterUserId(channel.broadcasterUserId)
.content("Hello from Kick4k!")
.build())
// Update channel information
val updated = client.channels().updateChannel(accessToken, UpdateChannelRequest.builder()
.streamTitle("New Stream Title")
.build())
println("Stream title updated to ${updated.streamTitle}")Kick4k provides built-in webhook support for handling real-time events:
import com.mbayou.kick4k.events.EventSubscriptionRequest
import com.mbayou.kick4k.events.handler.KickEventListener
import com.mbayou.kick4k.events.type.ChannelFollowedEvent
import com.mbayou.kick4k.events.type.ChatMessageSentEvent
// Register event listeners
client.eventDispatcher().registerListener(
ChatMessageSentEvent::class.java,
KickEventListener { event ->
println("${event.sender.username} said: ${event.content}")
},
)
client.eventDispatcher().registerListener(
ChannelFollowedEvent::class.java,
KickEventListener { event ->
println("New follower: ${event.follower.username}")
},
)
// Start webhook receiver
client.startWebhookReceiver("/webhooks", 8080)
// Subscribe to events
val subscription = EventSubscriptionRequest.builder()
.broadcasterUserId(currentUser.userId)
.addEvent(EventSubscriptionRequest.Event("chat.message.sent", 1))
.addEvent(EventSubscriptionRequest.Event("channel.followed", 1))
.method(EventSubscriptionRequest.Method.WEBHOOK)
.build()
client.events().postEventsSubscription(accessToken, subscription)Huge thanks to teksusik for creating the original Kick4J project that inspired this Kotlin rewrite.
chat.message.sent- New chat messageschannel.followed- New followerschannel.subscription.new- New subscriptionschannel.subscription.renewal- Subscription renewalschannel.subscription.gifts- Gift subscriptionslivestream.status.updated- Stream start/stoplivestream.metadata.updated- Stream title/category changesmoderation.banned- User bans/timeoutskicks.gifted- Kicks currency gifts
// Ban a user
val banRequest = PostModerationBansRequest.builder()
.broadcasterUserId(channel.broadcasterUserId)
.userId(123456)
.duration(3600)
.reason("Spam")
.build()
client.moderation().postModerationBans(banRequest)
// Unban a user
client.moderation().deleteModerationBans(
channel.broadcasterUserId,
123456,
)val stream = client.livestreams()
.getLivestream(accessToken, channel.broadcasterUserId)
stream?.let {
println("Currently streaming: ${it.streamTitle}")
println("Viewers: ${it.viewerCount}")
}
val searchRequest = GetLivestreamsRequest.builder()
.category(12) // Gaming
.language("en")
.limit(10)
.sort(GetLivestreamsRequest.Sort.VIEWER_COUNT)
.build()
val streams = client.livestreams().getLivestreams(accessToken, searchRequest)// Search categories
val categories = client.categories().getCategories(accessToken, "gaming")
// Get specific category
val category = client.categories().getCategory(accessToken, 12)
println("Category: ${category.name}")Releases are delivered through JitPack. Tag a commit (for example v1.2.0), ensure ./gradlew clean build passes, and
JitPack will build and serve the artifact as com.github.mbayou:kick4k:1.2.0. Refer to docs/PUBLISHING.md
for the full checklist.
val config = KickConfiguration.builder()
.clientId("your-client-id")
.clientSecret("your-client-secret")
.redirectUri("https://your-app.com/callback")
.baseUrl("https://api.kick.com/public/v1") // Custom API base URL
.oAuthHost("https://id.kick.com") // Custom OAuth host
.build()Kick4k throws specific exceptions for different error conditions:
try {
val user = client.users().getCurrentUser(accessToken)
println("Fetched ${user.displayName}")
} catch (apiException: ApiException) {
System.err.println("API error ${apiException.statusCode}: ${apiException.message}")
} catch (tokenException: OAuthTokenException) {
System.err.println("Auth error ${tokenException.errorCode}: ${tokenException.payload}")
// Handle token refresh or re-authentication
}- JDK 21 or higher (Kick4k targets Kotlin/JVM 21)
- Valid Kick.com application credentials
- Jackson (JSON processing)
- Java HTTP Client (built-in)
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Diamond Sponsor: ai_licia
Interested in sponsoring Kick4k? Open a sponsorship inquiry and we will get back to you quickly.
For questions, issues, or feature requests, please open an issue on the GitHub repository.
This library is not officially affiliated with Kick.com. Use at your own risk and ensure compliance with Kick.com's Terms of Service and API usage guidelines.
