Skip to content

OAuth returns invalid_scope for user:read and webhook API reports webhooks disabled despite enabled dashboard settings #405

Description

@saxblax

Describe the bug

Our newly created Kick developer application cannot complete OAuth authorization or create webhook event subscriptions.

Kick returns invalid_scope even when the OAuth request contains only the mandatory user:read scope. Separately, the Kick API returns webhook not enabled for app, despite webhooks being enabled in the Developer dashboard and a bot existing for the application.

Application details:

  • Application name: wcez
  • Client ID: 01KZBSFZ5E64EJXFRNVCJFBRJG
  • Kick channel: https://kick.com/wcez
  • Redirect URI: https://api.wcez.app/auth/kick/callback
  • Webhook URL: https://api.wcez.app/webhooks/kick
  • Public API health endpoint: https://api.wcez.app/health
  • Bot status: A bot already exists for this application
  • Webhook setting: Enabled in the Kick Developer dashboard
  • Date tested: August 7, 2026
  • Server region: United Kingdom

There appear to be two related problems:

  1. The OAuth authorization endpoint rejects the application's permitted scopes.
  2. The Events API does not recognise the application's enabled webhook status.

The Developer dashboard displays these capabilities as enabled, but Kick’s backend rejects both of them.

To Reproduce

Problem 1: OAuth returns invalid_scope

  1. Create a Kick developer application.

  2. Enable Read user information (including email address) in the application’s requested scopes.

  3. Configure this redirect URI:

    https://api.wcez.app/auth/kick/callback

  4. Generate an OAuth Authorization Code Flow request with PKCE.

  5. Initially request the application’s core permissions:

    • user:read
    • channel:read
    • chat:write
    • events:subscribe
  6. Sign in to Kick and approve access.

  7. Observe that Kick redirects to the registered callback with:

    error=invalid_scope

  8. To rule out an unsupported combination, repeat authorization while requesting only:

    user:read

  9. Sign in and approve access again.

  10. Observe that the same error is returned:

https://api.wcez.app/auth/kick/callback?error=invalid_scope&state=...

The authorization request includes:

  • response_type=code
  • The correct application Client ID
  • The exact registered redirect URI
  • scope=user:read
  • A PKCE code challenge
  • code_challenge_method=S256
  • A valid state value

The failure therefore occurs even when only the mandatory user:read permission is requested.

Problem 2: Kick reports webhook not enabled for app

  1. Open the application in the Kick Developer dashboard.

  2. Enable webhooks.

  3. Enter the following webhook URL:

    https://api.wcez.app/webhooks/kick

  4. Save the changes.

  5. Create a bot for the application.

  6. Confirm that the dashboard reports:

    A bot already exists for this app.

  7. Restart the deployed application controller.

  8. Allow the controller to obtain an application access token.

  9. Attempt to create the required event subscriptions through the Kick API.

  10. Observe that Kick returns HTTP 400:

{"data":"webhook not enabled for app","message":"Bad request"}

The relevant controller output is:

Server listening at http://127.0.0.1:8080
Server listening at 
Kick app subscription setup failed Error: Kick API request failed (400):
{"data":"webhook not enabled for app","message":"Bad request"}

We also performed the following webhook-setting reset:

  1. Disabled webhooks.
  2. Saved the application.
  3. Enabled webhooks again.
  4. Confirmed the webhook URL.
  5. Saved the application again.
  6. Restarted the controller.
  7. Retried event-subscription creation.

Kick continued to return:

webhook not enabled for app

We verified that the deployed controller is using the same Client ID shown in the Developer dashboard:

01KZBSFZ5E64EJXFRNVCJFBRJG

Expected behavior

OAuth

Kick should return an authorization code to the registered callback because:

  • user:read is enabled for the application.
  • user:read is the only scope requested during the isolated test.
  • The callback URL exactly matches the registered redirect URI.
  • Authorization Code Flow with PKCE is being used.
  • The PKCE code challenge and state value are supplied.
  • The user successfully signs in and approves access.

The expected callback should contain a code and state, rather than:

error=invalid_scope

Webhooks

Kick should allow event subscriptions to be created because:

  • Webhooks are enabled in the Developer dashboard.
  • The webhook URL is entered and saved.
  • The webhook endpoint is publicly reachable over HTTPS.
  • A bot exists for the application.
  • The controller uses the correct Client ID.
  • The controller can reach Kick’s API.
  • The application can obtain an application access token.

The Events API should recognise the application as webhook-enabled instead of returning:

webhook not enabled for app

Screenshots

Screenshots are available showing:

  1. The Kick Developer application settings.
  2. The enabled webhook toggle.
  3. The configured webhook URL.
  4. The selected application scopes.
  5. The Create a BOT for this App section.
  6. Confirmation that a bot already exists for the application.
  7. The OAuth callback page displaying invalid_scope.
  8. The controller log showing webhook not enabled for app.
  9. The deployed controller’s matching Client ID.
  10. The successful public API health response.

No screenshots containing the Client Secret, access tokens, refresh tokens, encryption keys, SSH credentials or controller administration tokens will be posted publicly.

Desktop (please complete the following information):

  • OS: Windows
  • OS version: Windows 10
  • Browser: Google Chrome
  • Browser version: Current stable version as of August 7, 2026
  • Server OS: Ubuntu 24.04 LTS
  • Server architecture: x86_64
  • Runtime: Node.js 22
  • Deployment: Docker
  • Reverse proxy/public ingress: Cloudflare Tunnel
  • Server location: United Kingdom
  • Kick channel: wcez

Additional context

We have completed the following checks:

  • Confirmed the controller is online and healthy.
  • Confirmed https://api.wcez.app/health is publicly accessible.
  • Confirmed the OAuth callback is publicly accessible.
  • Confirmed the webhook endpoint is publicly accessible over HTTPS.
  • Confirmed the redirect URI exactly matches the registered URI.
  • Confirmed the correct Client ID is deployed.
  • Confirmed user:read is enabled in the Developer dashboard.
  • Confirmed webhooks are enabled in the Developer dashboard.
  • Confirmed the webhook URL has been saved.
  • Disabled and re-enabled webhooks to force the setting to update.
  • Confirmed a bot exists for the application.
  • Restarted the controller after the settings were saved.
  • Retested after waiting for application provisioning.
  • Isolated OAuth to the single user:read scope.
  • Confirmed that no optional scope combination is required to reproduce invalid_scope.
  • Confirmed that no unregistered redirect URI is being used.
  • Confirmed that no client secret or access token is being passed through the browser.
  • Confirmed that the API remains operational despite subscription setup failing.

The Developer dashboard permits and displays the user:read permission, but the authorization endpoint rejects it as invalid.

The Developer dashboard shows webhooks enabled, but the Events API reports that webhooks are disabled.

Because the dashboard state contradicts both API responses, this appears to be an application provisioning or synchronization problem within Kick’s backend rather than an endpoint-reachability or client-configuration problem.

This may be related to the application/webhook problems reported in:

Could the Kick Engineering team please inspect application:

01KZBSFZ5E64EJXFRNVCJFBRJG

and confirm:

  1. Whether OAuth scopes are enabled for this application internally.
  2. Why the mandatory user:read scope returns invalid_scope.
  3. Whether the application is marked as webhook-enabled internally.
  4. Whether the newly created bot has been fully provisioned.
  5. Whether an additional verification or approval process is required.
  6. Whether the application is subject to an unverified-app restriction.
  7. Whether an account-level restriction is preventing OAuth or webhook subscriptions.
  8. Whether the application can be manually reprovisioned or repaired without recreating it.

We can provide sanitized authorization URLs, request timestamps, complete response bodies and additional server logs if required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions