### Authorization Endpoint Example Request Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Example GET request to the authorization endpoint for initiating the OAuth 2.1 Authorization Grant flow. Ensure all parameters are correctly populated. ```uri GET https://id.kick.com/oauth/authorize? response_type=code& client_id=& redirect_uri=& scope=& code_challenge=& code_challenge_method=S256& state= ``` -------------------------------- ### Authorization Endpoint 400 Response Example Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Example of an error response from the authorization endpoint when the request is invalid. Check the parameters for correctness. ```json { "error": "Invalid request" } ``` -------------------------------- ### Authorization Endpoint 200 Response Example Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Example of a successful redirect URI after user authorization, containing the authorization code. This is the callback to your application. ```uri https://yourapp.com/callback?code=&state=random-state ``` -------------------------------- ### Webhook Payload Example Source: https://github.com/kickengineering/kickdevdocs/blob/main/drops/drops-guide.md This is an example of the JSON payload received when a viewer claims a reward. Your endpoint should be prepared to receive and process this data. ```json { "claim_id": "string", // ULID "user_id": "integer", // uint64 "campaign_id": "string", // ULID "reward_id": "string", // ULID "external_id": "string" // Optional - external reward reference } ``` -------------------------------- ### Introspect Token Response Example Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Example of a successful response from the Token Introspect endpoint, showing token activity, client ID, type, scope, and expiration. ```json { "data": { "active": true, "client_id": "", "token_type": "user", // "app" or "user" "scope": "user:read channel:read", "exp": 1771046347 }, "message": "OK" } ``` -------------------------------- ### Golang Full Signature Verification Example Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md Demonstrates parsing the public key, creating the signature string, and then verifying the incoming webhook signature. ```go // Parse the Public Key pubkey, err := keysx.ParsePublicKey([]byte(` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/+l1WnlRrGSolDMA+A8 6rAhMbQGmQ2SapVcGM3zq8ANXjnhDWocMqfWcTd95btDydITa10kDvHzw9WQOqp2 MZI7ZyrfzJuz5nhTPCiJwTwnEtWft7nV14BYRDHvlfqPUaZ+1KR4OCaO/wWIk/rQ L/TjY0M70gse8rlBkbo2a8rKhu69RQTRsoaf4DVhDPEeSeI5jVrRDGAMGL3cGuyY 6CLKGdjVEM78g3JfYOvDU/RvfqD7L89TZ3iN94jrmWdGz34JNlEI5hqK8dd7C5EF BEbZ5jgB8s8ReQV8H+MkuffjdAj3ajDDX3DOJMIut1lBrUVD1AaSrGCKHooWoL2e twIDAQAB -----END PUBLIC KEY----- `)) // Create the Signature to compare signature := []byte(fmt.Sprintf("%s.%s.%s", messageID, timestamp, body)) // Verify the Header err := Verify(pubkey, signature, headers["Kick-Event-Signature"]) ``` -------------------------------- ### Get All Categories (v1) Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/categories.md Retrieves a list of all available categories using version 1 of the API. ```APIDOC ## GET /public/v1/categories ### Description Retrieves a list of all available categories. ### Method GET ### Endpoint /public/v1/categories ### Response #### Success Response (200) - **categories** (array) - A list of category objects. ``` -------------------------------- ### Get All Categories (v2) Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/categories.md Retrieves a list of all available categories using version 2 of the API. ```APIDOC ## GET /public/v2/categories ### Description Retrieves a list of all available categories. ### Method GET ### Endpoint /public/v2/categories ### Response #### Success Response (200) - **categories** (array) - A list of category objects. ``` -------------------------------- ### Get Public Key Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/public-key.md Retrieves the public key used for signature verification. ```APIDOC ## GET /public/v1/public-key ### Description Retrieves the public key used for signature verification. ### Method GET ### Endpoint /public/v1/public-key ### Response #### Success Response (200) - **publicKey** (string) - The public key in PEM format. ``` -------------------------------- ### Livestream Status Updated Event (Stream Started) Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when a livestream's status is updated, specifically when a stream starts. It includes broadcaster information and stream details. ```APIDOC ## Livestream Status Updated Event (Stream Started) ### Description This event is triggered when a livestream's status is updated, specifically when a stream starts. It includes broadcaster information and stream details. ### Headers - Kick-Event-Type: "livestream.status.updated" - Kick-Event-Version: “1” ### Body ```json { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "is_live": true, "title": "Stream Title", "started_at": "2025-01-01T11:00:00+11:00", "ended_at": null } ``` ``` -------------------------------- ### Get Leaderboard Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/kicks.md Retrieves the leaderboard data. This endpoint allows applications to fetch the current ranking information. ```APIDOC ## GET /public/v1/kicks/leaderboard ### Description Retrieves the leaderboard data. ### Method GET ### Endpoint /public/v1/kicks/leaderboard ### Parameters #### Query Parameters - **spec** (string) - Required - The OpenAPI specification to use. - **path** (string) - Required - The path to the OpenAPI operation. ### Request Example ``` GET /public/v1/kicks/leaderboard?spec=kick-dev-api&path=/public/v1/kicks/leaderboard ``` ### Response #### Success Response (200) - **data** (object) - Contains the leaderboard information. - **message** (string) - A message indicating the status of the request. ``` -------------------------------- ### Get Livestreams Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/livestreams.md Retrieves a list of livestreams. The data returned depends on the scopes of the authorization token. ```APIDOC ## GET /public/v1/livestreams ### Description Retrieves a list of livestreams. ### Method GET ### Endpoint /public/v1/livestreams ``` -------------------------------- ### Get Users Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/users.md Retrieves a list of users. Access to sensitive data depends on the scopes of the User Access Token. ```APIDOC ## GET /public/v1/users ### Description Retrieves a list of users. Access to sensitive data depends on the scopes of the User Access Token. ### Method GET ### Endpoint /public/v1/users ``` -------------------------------- ### Livestream Status Updated Event (Stream Started) Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when a livestream's status is updated, specifically when a stream starts. It includes broadcaster information and the stream title. ```json Headers - Kick-Event-Type: "livestream.status.updated" - Kick-Event-Version: “1” { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "is_live": true, "title": "Stream Title", "started_at": "2025-01-01T11:00:00+11:00", "ended_at": null } ``` -------------------------------- ### Get Category by ID (v1) Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/categories.md Retrieves a specific category by its unique identifier using version 1 of the API. ```APIDOC ## GET /public/v1/categories/{category_id} ### Description Retrieves a specific category by its ID. ### Method GET ### Endpoint /public/v1/categories/{category_id} ### Parameters #### Path Parameters - **category_id** (string) - Required - The unique identifier of the category. ``` -------------------------------- ### Create Event Subscription Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/subscribe-to-events.md Creates a new event subscription. ```APIDOC ## POST /public/v1/events/subscriptions ### Description Creates a new event subscription. ### Method POST ### Endpoint /public/v1/events/subscriptions ### Parameters #### Request Body - **event** (string) - Required - The type of event to subscribe to. Corresponds to Event names defined in the [Events table](https://docs.kick.com/events/event-types#events). - **condition** (string) - Optional - The condition for the subscription. - **transport** (object) - Required - The transport details for the subscription. - **type** (string) - Required - The type of transport (e.g., "webhook"). - **url** (string) - Required - The URL for the transport. ### Request Example { "event": "stream.offline", "condition": "", "transport": { "type": "webhook", "url": "https://example.com/webhook" } } ### Response #### Success Response (200) - **subscription** (object) - The newly created subscription object. - **event** (string) - The type of event subscribed to. - **condition** (string) - The condition for the subscription. - **transport** (object) - The transport details for the subscription. - **type** (string) - The type of transport (e.g., "webhook"). - **url** (string) - The URL for the transport. #### Response Example { "subscription": { "event": "stream.offline", "condition": "", "transport": { "type": "webhook", "url": "https://example.com/webhook" } } } ``` -------------------------------- ### Authorization Endpoint Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Directs the user to the authorization server where they can log in and approve the application's access request. ```APIDOC ## GET /oauth/authorize ### Description Directs the user to the authorization server where they can log in and approve the application's access request. ### Method GET ### Endpoint /oauth/authorize ### Parameters #### Query Parameters - **client_id** (string) - Required - Your application's client ID - **response_type** (string) - Required - `code` - **redirect_uri** (uri) - Required - The URI to redirect users to after authorization. If your redirect URI host is 127.0.0.1, see this [workaround](generating-tokens-oauth2-flow.md#workaround-for-127.0.0.1-host-redirect-uri) - **state** (string) - Required (at the moment) - A random string to maintain state between the request and callback - **scope** (string) - Required - Scopes for request - **code_challenge** (string) - Required - OAuth code challenge - **code_challenge_method** (string) - Required - `S256` ### Request Example ```uri GET https://id.kick.com/oauth/authorize? response_type=code& client_id=& redirect_uri=& scope=& code_challenge=& code_challenge_method=S256& state= ``` ### Response #### Success Response (200) Redirects to the `redirect_uri` with `code` and `state` query parameters. #### Response Example ```uri https://yourapp.com/callback?code=&state=random-state ``` #### Error Response (400) ```json { "error": "Invalid request" } ``` ``` -------------------------------- ### Workaround for 127.0.0.1 Redirect URI Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md When using 127.0.0.1 as a redirect URI in local development, add a sacrificial 'redirect' query parameter before 'redirect_uri' to avoid issues with NextJS URL rewriting. ```http GET https://id.kick.com/oauth/authorize? response_type=code& client_id=& redirect=127.0.0.1 redirect_uri=& scope=& code_challenge=& code_challenge_method=S256& state= ``` -------------------------------- ### Create Channel Reward Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/channel-rewards.md Creates a new channel point reward for a given channel. ```APIDOC ## POST /public/v1/channels/rewards ### Description Creates a new channel point reward for a given channel. ### Method POST ### Endpoint /public/v1/channels/rewards ``` -------------------------------- ### Channel Subscription Created Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is fired when a new subscription is created for a channel. It provides details about the broadcaster, the new subscriber, and the subscription duration. ```json Headers - Kick-Event-Type: “channel.subscription.new” - Kick-Event-Version: “1” { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "subscriber": { "is_anonymous": false, "user_id": 987654321, "username": "subscriber_name", "is_verified": false, "profile_picture": "https://example.com/sender_avatar.jpg", "channel_slug": "subscriber_channel", "identity": null }, "duration": 1, "created_at": "2025-01-14T16:08:06Z", "expires_at": "2025-02-14T16:08:06Z" } ``` -------------------------------- ### Fetch Public Key Endpoint Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md The Kick public key can be fetched from this API endpoint. ```url https://api.kick.com/public/v1/public-key ``` -------------------------------- ### Get Livestreams Stats Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/livestreams.md Retrieves statistics for livestreams. The data returned depends on the scopes of the authorization token. ```APIDOC ## GET /public/v1/livestreams/stats ### Description Retrieves statistics for livestreams. ### Method GET ### Endpoint /public/v1/livestreams/stats ``` -------------------------------- ### Generate App Access Token (Client Credentials Flow) Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Obtain an app access token using your client ID and secret. This token is suitable for accessing public data. The request must be form-urlencoded. ```http POST https://id.kick.com/oauth/token Headers: Content-Type: application/x-www-form-urlencoded Body: { grant_type=client_credentials client_id= client_secret= } ``` ```json { "access_token": "", "token_type": "", "expires_in": "", } ``` -------------------------------- ### Workaround for 127.0.0.1 Host Redirect URI Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Provides a workaround for a bug in NextJS that affects local development redirect URIs using 127.0.0.1. ```APIDOC ## Notes ### Workaround for 127.0.0.1 Host Redirect URI If developing your authorization to only happen on an app running locally, we recommend using `localhost` as your redirect URI/callback URL e.g. `http://localhost/auth/callback`. But if you're unable to change your callback URL to use `localhost` instead of `127.0.0.1`, you will need to perform a workaround due to a [bug in our frontend framework, NextJS](https://github.com/vercel/next.js/issues/79182). NextJS will change the first occurrence of `127.0.0.1` in a URL to `localhost`, and as the redirect URI needs to match exactly to your callback URL specified in your app settings, this will cause authorization to fail. When performing the Authorize GET request, you will need to add a sacrificial query parameter that sits before the `redirect_uri` parameter that contains "127.0.0.1". This parameter can be named anything but from testing it's best to call it `redirect`. This will cause NextJS to change that first parameter and leave the second parameter untouched. See an example request below: ``` GET https://id.kick.com/oauth/authorize? response_type=code& client_id=& redirect=127.0.0.1 redirect_uri=& scope=& code_challenge=& code_challenge_method=S256& state= ``` ``` -------------------------------- ### Stream Ended Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when a livestream is no longer live. It includes details about the broadcaster and the stream's start and end times. ```json Headers - Kick-Event-Type: "livestream.status.updated" - Kick-Event-Version: “1” { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "is_live": false, "title": "Stream Title", "started_at": "2025-01-01T11:00:00+11:00", "ended_at": "2025-01-01T15:00:00+11:00" } ``` -------------------------------- ### Retrieve Claims with Filters Source: https://github.com/kickengineering/kickdevdocs/blob/main/drops/public-api.md Use this endpoint to fetch reward claims, filtering by campaign ID, claim ID, user ID, or external status. Supports pagination with a cursor and limits the number of results. ```HTTP GET /public/v1/drops/claims?campaign_id=01JAXK8N4QWRTY5PM7ZEBVJDS8S&limit=10&cursor=01K0TDDR08Q5ZNWXK92VRXD7GW&user_id=1234 ``` ```HTTP GET /public/v1/drops/claims?claim_id=01JAXK8N4QWRTY5PM7ZEBVGH2S ``` -------------------------------- ### Golang Signature Verification Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md Verifies a signature against a public key, body, and the provided signature. It decodes the base64 signature and uses SHA256 hashing. ```go import ( "crypto" "crypto/rsa" "crypto/sha256" "encoding/base64" ) func Verify(publicKey *rsa.PublicKey, body []byte, signature []byte) error { decoded := make([]byte, base64.StdEncoding.DecodedLen(len(signature))) n, err := base64.StdEncoding.Decode(decoded, signature) if err != nil { return err } signature = decoded[:n] hashed := sha256.Sum256(body) return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature) } ``` -------------------------------- ### Channel Follow Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when a user follows a channel. It includes details about the broadcaster and the follower. ```json Headers - Kick-Event-Type: “channel.followed” - Kick-Event-Version: “1” { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "follower": { "is_anonymous": false, "user_id": 987654321, "username": "follower_name", "is_verified": false, "profile_picture": "https://example.com/sender_avatar.jpg", "channel_slug": "follower_channel", "identity": null } } ``` -------------------------------- ### Channel Follow Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when a user follows a channel. It includes information about the broadcaster and the follower. ```APIDOC ## Channel Follow Event ### Description This event is triggered when a user follows a channel. It includes information about the broadcaster and the follower. ### Headers - Kick-Event-Type: "channel.followed" - Kick-Event-Version: "1" ### Body ```json { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "follower": { "is_anonymous": false, "user_id": 987654321, "username": "follower_name", "is_verified": false, "profile_picture": "https://example.com/sender_avatar.jpg", "channel_slug": "follower_channel", "identity": null } } ``` ``` -------------------------------- ### List Channels Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/channels.md Retrieves a list of channels. The data returned depends on the scopes of the authorization token. ```APIDOC ## GET /public/v1/channels ### Description Retrieves a list of channels. ### Method GET ### Endpoint /public/v1/channels ``` -------------------------------- ### App Access Token Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Uses client credentials to generate an app access token for obtaining public data. ```APIDOC ## App Access Token Endpoint ### Description Uses a client_id and client_secret to generate an app access token which can be used to obtain public data on Kick. ### Method POST ### Endpoint /oauth/token ### Headers - **Content-Type** (string) - Required - application/x-www-form-urlencoded ### Parameters #### Request Body - **client_id** (string) - Required - Your application's client ID - **client_secret** (string) - Required - Your application's client secret - **grant_type** (string) - Required - `client_credentials` ### Request Example ``` POST https://id.kick.com/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&client_id=&client_secret= ``` ### Response #### Success Response (200) - **access_token** (string) - Description - **token_type** (string) - Description - **expires_in** (string) - Description #### Response Example ```json { "access_token": "", "token_type": "", "expires_in": "" } ``` ``` -------------------------------- ### List Channel Rewards Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/channel-rewards.md Retrieves a list of all channel point rewards for a given channel. ```APIDOC ## GET /public/v1/channels/rewards ### Description Retrieves a list of all channel point rewards for a given channel. ### Method GET ### Endpoint /public/v1/channels/rewards ``` -------------------------------- ### List Event Subscriptions Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/subscribe-to-events.md Retrieves a list of all current event subscriptions. ```APIDOC ## GET /public/v1/events/subscriptions ### Description Retrieves a list of all current event subscriptions. ### Method GET ### Endpoint /public/v1/events/subscriptions ### Parameters #### Query Parameters - **event** (string) - Optional - The specific event type to filter subscriptions by. Corresponds to Event names defined in the [Events table](https://docs.kick.com/events/event-types#events). ### Response #### Success Response (200) - **subscriptions** (array) - A list of subscription objects. - **event** (string) - The type of event subscribed to. - **condition** (string) - The condition for the subscription. - **transport** (object) - The transport details for the subscription. - **type** (string) - The type of transport (e.g., "webhook"). - **url** (string) - The URL for the transport. #### Response Example { "subscriptions": [ { "event": "stream.online", "condition": "", "transport": { "type": "webhook", "url": "https://example.com/webhook" } } ] } ``` -------------------------------- ### Signature Creation String Concatenation Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md The signature is created by concatenating the message ID, timestamp, and raw request body, separated by a dot. ```go signature := []byte(fmt.Sprintf("%s.%s.%s", messageID, timestamp, body)) ``` -------------------------------- ### List Reward Redemptions Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/channel-rewards.md Retrieves a list of redemptions for channel point rewards. ```APIDOC ## GET /public/v1/channels/rewards/redemptions ### Description Retrieves a list of redemptions for channel point rewards. ### Method GET ### Endpoint /public/v1/channels/rewards/redemptions ``` -------------------------------- ### Golang Public Key Parsing Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md Parses a PEM-encoded public key into an rsa.PublicKey struct. Ensure the input is a valid PEM-encoded public key. ```go import ( "crypto/rsa" "crypto/x509" "encoding/pem" "errors" ) func ParsePublicKey(bs []byte) (rsa.PublicKey, error) { block, _ := pem.Decode(bs) if block == nil { return rsa.PublicKey{}, errors.New("not decodable key") } if block.Type != "PUBLIC KEY" { return rsa.PublicKey{}, errors.New("not public key") } parsed, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return rsa.PublicKey{}, err } publicKey, ok := parsed.(*rsa.PublicKey) if !ok { return rsa.PublicKey{}, errors.New("not expected public key interface") } return *publicKey, nil } ``` -------------------------------- ### Channel Subscription Created Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when a new channel subscription is created. It includes details about the broadcaster, subscriber, and subscription duration. ```APIDOC ## Channel Subscription Created Event ### Description This event is triggered when a new channel subscription is created. It includes details about the broadcaster, subscriber, and subscription duration. ### Headers - Kick-Event-Type: "channel.subscription.new" - Kick-Event-Version: "1" ### Body ```json { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "subscriber": { "is_anonymous": false, "user_id": 987654321, "username": "subscriber_name", "is_verified": false, "profile_picture": "https://example.com/sender_avatar.jpg", "channel_slug": "subscriber_channel", "identity": null }, "duration": 1, "created_at": "2025-01-14T16:08:06Z", "expires_at": "2025-02-14T16:08:06Z" } ``` ``` -------------------------------- ### Accept Reward Redemption Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/channel-rewards.md Accepts a redemption of a channel point reward. ```APIDOC ## POST /public/v1/channels/rewards/redemptions/accept ### Description Accepts a redemption of a channel point reward. ### Method POST ### Endpoint /public/v1/channels/rewards/redemptions/accept ``` -------------------------------- ### 200 OK Response for Retrieve Claims Source: https://github.com/kickengineering/kickdevdocs/blob/main/drops/public-api.md A successful response includes a list of claims with their details and a cursor for pagination. The 'external_status' field may be omitted if not set. ```JSON { "data": { "claims": [ { "claim_id": "string", "user_id": "integer", "campaign_id": "string", "reward_id": "string", "external_id": "string", "external_status": "string", "created_at": "datetime", "updated_at": "datetime" } ], "cursor": "01K0TDDR08Q5ZNWXK92SDH7SDH" }, "message": "OK" } ``` -------------------------------- ### Kick Public Key Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md This is the Kick public key used to decrypt signatures. It can also be fetched from the `/public/v1/public-key` endpoint. ```text -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/+l1WnlRrGSolDMA+A8 6rAhMbQGmQ2SapVcGM3zq8ANXjnhDWocMqfWcTd95btDydITa10kDvHzw9WQOqp2 MZI7ZyrfzJuz5nhTPCiJwTwnEtWft7nV14BYRDHvlfqPUaZ+1KR4OCaO/wWIk/rQ L/TjY0M70gse8rlBkbo2a8rKhu69RQTRsoaf4DVhDPEeSeI5jVrRDGAMGL3cGuyY 6CLKGdjVEM78g3JfYOvDU/RvfqD7L89TZ3iN94jrmWdGz34JNlEI5hqK8dd7C5EF BEbZ5jgB8s8ReQV8H+MkuffjdAj3ajDDX3DOJMIut1lBrUVD1AaSrGCKHooWoL2e twIDAQAB -----END PUBLIC KEY----- ``` -------------------------------- ### Retrieve Claims Source: https://github.com/kickengineering/kickdevdocs/blob/main/drops/public-api.md Fetches a list of reward claims for Drops campaigns. Supports filtering by campaign ID, user ID, claim ID, external status, and includes pagination. ```APIDOC ## GET /public/v1/drops/claims ### Description Retrieves reward claims associated with Drops campaigns. This endpoint allows filtering by various parameters and supports pagination. ### Method GET ### Endpoint /public/v1/drops/claims ### Parameters #### Query Parameters - **campaign_id** (String) - Optional - Filter by campaign_id - **limit** (Integer) - Optional - Number of results (default: 10), Max=1000 - **cursor** (String) - Optional - Pagination cursor – pass claim_id - **user_id** (Integer) - Optional - Filter by user ID - **claim_id** (String) - Optional - Filter by claim ID - **external_status** (String) - Optional - Filter by external status ### Response #### Success Response (200 OK) { "data": { "claims": [ { "claim_id": "string", "user_id": "integer", "campaign_id": "string", "reward_id": "string", "external_id": "string", "external_status": "string", "created_at": "datetime", "updated_at": "datetime" } ], "cursor": "string" }, "message": "OK" } ### Error Responses #### Error Response (401 Unauthorized) { "data": null, "message": "Unauthorized" } #### Error Response (500 Internal Server Error) { "data": null, "message": "Internal server error" } ``` -------------------------------- ### Exchange Code for Token (Authorization Code Flow) Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Use this endpoint to exchange an authorization code for an access token and a refresh token. Ensure the Content-Type header is set to application/x-www-form-urlencoded. ```http POST https://id.kick.com/oauth/token Headers: Content-Type: application/x-www-form-urlencoded Body: { grant_type=authorization_code client_id= client_secret= redirect_uri= code_verifier= code= } ``` ```json { "access_token": "", "token_type": "", "refresh_token": "", "expires_in": "", "scope": "" } ``` -------------------------------- ### Send a Chat Message Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/chat.md Allows you to send a message through the chat. This can be done as a Bot account or your User account. ```APIDOC ## POST /public/v1/chat ### Description Send a message through the chat as a Bot or User account. ### Method POST ### Endpoint /public/v1/chat ``` -------------------------------- ### Refresh Access and Refresh Tokens Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Renew both access and refresh tokens by providing a valid refresh token. The request body must be form-urlencoded. ```http POST https://id.kick.com/oauth/token Headers: Content-Type: application/x-www-form-urlencoded Body: { grant_type=refresh_token client_id= client_secret= refresh_token= } ``` ```json { "access_token": "", "token_type": "", "refresh_token": "", "expires_in": "", "scope": "" } ``` -------------------------------- ### Exchange Code for Token Source: https://github.com/kickengineering/kickdevdocs/blob/main/getting-started/generating-tokens-oauth2-flow.md Exchanges the authorization code for an access token and a refresh token. ```APIDOC ## Token Endpoint ### Description Exchanges the code for a valid access token and a refresh token that can be used to make authorised requests to Kick's API. ### Method POST ### Endpoint /oauth/token ### Headers - **Content-Type** (string) - Required - application/x-www-form-urlencoded ### Parameters #### Request Body - **code** (string) - Required - Code received during the Authorization Flow - **client_id** (string) - Required - Your application's client ID - **client_secret** (string) - Required - Your application's client secret - **redirect_uri** (string) - Required - The URI to redirect users to after authorization - **grant_type** (string) - Required - `authorization_code` - **code_verifier** (string) - Required - To verify PKCE challenge code created ### Request Example ``` POST https://id.kick.com/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&client_id=&client_secret=&redirect_uri=&code_verifier=&code= ``` ### Response #### Success Response (200) - **access_token** (string) - Description - **token_type** (string) - Description - **refresh_token** (string) - Description - **expires_in** (string) - Description - **scope** (string) - Description #### Response Example ```json { "access_token": "", "token_type": "", "refresh_token": "", "expires_in": "", "scope": "" } ``` ``` -------------------------------- ### Channel Subscription Gifts Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event is triggered when subscriptions are gifted to a channel. It includes details about the broadcaster, the gifter, and the recipients of the gifts. ```APIDOC ## Channel Subscription Gifts Event ### Description This event is triggered when subscriptions are gifted to a channel. It includes details about the broadcaster, the gifter, and the recipients of the gifts. ### Headers - Kick-Event-Type: "channel.subscription.gifts" - Kick-Event-Version: "1" ### Body ```json { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "gifter": { "is_anonymous": false, "user_id": 987654321, // null if is_anonymous=true "username": "gifter_name", // null if is_anonymous=true "is_verified": false, // null if is_anonymous=true "profile_picture": "https://example.com/sender_avatar.jpg", // null if is_anonymous=true "channel_slug": "gifter_channel", // null if is_anonymous=true "identity": null // null if is_anonymous=true }, "giftees": [ { "is_anonymous": false, "user_id": 561654654, "username": "giftee_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "giftee_channel", "identity": null } ], "created_at": "2025-01-14T16:08:06Z", "expires_at": "2025-02-14T16:08:06Z" } ``` ``` -------------------------------- ### Channel Subscription Gift Event Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/event-types.md This event signifies that a user has gifted subscriptions to one or more users in a channel. It details the broadcaster, the gifter, the giftees, and the subscription period. ```json Headers - Kick-Event-Type: “channel.subscription.gifts” - Kick-Event-Version: “1” Public Gift Structure { "broadcaster": { "is_anonymous": false, "user_id": 123456789, "username": "broadcaster_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "broadcaster_channel", "identity": null }, "gifter": { "is_anonymous": false, "user_id": 987654321, // null if is_anonymous=true "username": "gifter_name", // null if is_anonymous=true "is_verified": false, // null if is_anonymous=true "profile_picture": "https://example.com/sender_avatar.jpg", // null if is_anonymous=true "channel_slug": "gifter_channel", // null if is_anonymous=true "identity": null // null if is_anonymous=true }, "giftees": [ { "is_anonymous": false, "user_id": 561654654, "username": "giftee_name", "is_verified": true, "profile_picture": "https://example.com/broadcaster_avatar.jpg", "channel_slug": "giftee_channel", "identity": null } ], "created_at": "2025-01-14T16:08:06Z", "expires_at": "2025-02-14T16:08:06Z" } ``` -------------------------------- ### Webhook Sender Validation Source: https://github.com/kickengineering/kickdevdocs/blob/main/events/webhook-security.md This section details how to validate incoming webhook requests using the `Kick-Event-Signature` header. It involves using the Kick public key to verify the signature against the request payload. ```APIDOC ## Webhook Sender Validation The `Kick-Event-Signature` header is used to validate if a request has come from the Kick servers. This is to prevent anyone who finds an app's webhook endpoint from sending fake events. ### Kick Public Key This is the Kick public key. Any request that is sent from our servers will have a signature signed by our Private Key, which can be decrypted using this Public Key. ``` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/+l1WnlRrGSolDMA+A8 6rAhMbQGmQ2SapVcGM3zq8ANXjnhDWocMqfWcTd95btDydITa10kDvHzw9WQOqp2 MZI7ZyrfzJuz5nhTPCiJwTwnEtWft7nV14BYRDHvlfqPUaZ+1KR4OCaO/wWIk/rQ L/TjY0M70gse8rlBkbo2a8rKhu69RQTRsoaf4DVhDPEeSeI5jVrRDGAMGL3cGuyY 6CLKGdjVEM78g3JfYOvDU/RvfqD7L89TZ3iN94jrmWdGz34JNlEI5hqK8dd7C5EF BEbZ5jgB8s8ReQV8H+MkuffjdAj3ajDDX3DOJMIut1lBrUVD1AaSrGCKHooWoL2e twIDAQAB -----END PUBLIC KEY----- ``` The public key can also be fetched from this endpoint: ``` https://api.kick.com/public/v1/public-key ``` ### Signature Creation The signature is created through the concatenation of the following values into a single string, separated by a `.`: * `Kick-Event-Message-Id` * `Kick-Event-Message-Timestamp` * The raw body of the request ```go signature := []byte(fmt.Sprintf("%s.%s.%s", messageID, timestamp, body)) ``` Once concatenated, the body will be signed with the Kick Private Key. ### Examples Here are some examples of verifying the signature in different languages: #### Golang ```go import ( "crypto/rsa" "crypto/x509" "encoding/pem" "errors" ) func ParsePublicKey(bs []byte) (rsa.PublicKey, error) { block, _ := pem.Decode(bs) if block == nil { return rsa.PublicKey{}, errors.New("not decodable key") } if block.Type != "PUBLIC KEY" { return rsa.PublicKey{}, errors.New("not public key") } parsed, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return rsa.PublicKey{}, err } publicKey, ok := parsed.(*rsa.PublicKey) if !ok { return rsa.PublicKey{}, errors.New("not expected public key interface") } return *publicKey, nil } import ( "crypto" "crypto/rsa" "crypto/sha256" "encoding/base64" ) func Verify(publicKey *rsa.PublicKey, body []byte, signature []byte) error { decoded := make([]byte, base64.StdEncoding.DecodedLen(len(signature))) n, err := base64.StdEncoding.Decode(decoded, signature) if err != nil { return err } signature = decoded[:n] hashed := sha256.Sum256(body) return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature) } // Parse the Public Key pubkey, err := keysx.ParsePublicKey([]byte(` ----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/+l1WnlRrGSolDMA+A8 6rAhMbQGmQ2SapVcGM3zq8ANXjnhDWocMqfWcTd95btDydITa10kDvHzw9WQOqp2 MZI7ZyrfzJuz5nhTPCiJwTwnEtWft7nV14BYRDHvlfqPUaZ+1KR4OCaO/wWIk/rQ L/TjY0M70gse8rlBkbo2a8rKhu69RQTRsoaf4DVhDPEeSeI5jVrRDGAMGL3cGuyY 6CLKGdjVEM78g3JfYOvDU/RvfqD7L89TZ3iN94jrmWdGz34JNlEI5hqK8dd7C5EF BEbZ5jgB8s8ReQV8H+MkuffjdAj3ajDDX3DOJMIut1lBrUVD1AaSrGCKHooWoL2e twIDAQAB -----END PUBLIC KEY----- `)) // Create the Signature to compare signature := []byte(fmt.Sprintf("%s.%s.%s", messageID, timestamp, body)) // Verify the Header err := Verify(pubkey, signature, headers["Kick-Event-Signature"]) ``` ``` -------------------------------- ### Reject Reward Redemption Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/channel-rewards.md Rejects a redemption of a channel point reward. ```APIDOC ## POST /public/v1/channels/rewards/redemptions/reject ### Description Rejects a redemption of a channel point reward. ### Method POST ### Endpoint /public/v1/channels/rewards/redemptions/reject ``` -------------------------------- ### 401 Unauthorized Error Response Source: https://github.com/kickengineering/kickdevdocs/blob/main/drops/public-api.md This error is returned when the request lacks valid authorization credentials. ```JSON { "data": null, "message": "Unauthorized" } ``` -------------------------------- ### 500 Internal Server Error Response Source: https://github.com/kickengineering/kickdevdocs/blob/main/drops/public-api.md This error indicates a problem on the server side. ```JSON { "data": null, "message": "Internal server error" } ``` -------------------------------- ### Unban a User Source: https://github.com/kickengineering/kickdevdocs/blob/main/apis/moderation.md This endpoint allows you to unban a user, removing their ban and allowing them to participate in the chat room again. ```APIDOC ## DELETE /public/v1/moderation/bans ### Description Allows you to unban a user from a chat room. ### Method DELETE ### Endpoint /public/v1/moderation/bans ```