# Server-to-Server OAuth app always returns invalid\_client when requesting access token

**URL:** <https://devforum.zoom.us/t/server-to-server-oauth-app-always-returns-invalid-client-when-requesting-access-token/137579>\
**Category:** Authentication\
**Created:** [September 22, 2025, 5:28pm UTC](https://devforum.zoom.us/t/server-to-server-oauth-app-always-returns-invalid-client-when-requesting-access-token/137579 "2025-09-22T17:28:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kayla](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/kayla/32/71369_2.png) [@Kayla](https://devforum.zoom.us/u/Kayla)\
**Post date:** [September 22, 2025, 5:28pm UTC](https://devforum.zoom.us/t/server-to-server-oauth-app-always-returns-invalid-client-when-requesting-access-token/137579/1 "2025-09-22T17:28:51Z")

</div>

I am experiencing an issue with my **Server-to-Server OAuth app**.  
Whenever I try to request an access token, the Zoom API always responds with:

```auto
{
  "reason": "Invalid client_id or client_secret",
  "error": "invalid_client"
}

```

### What I have already tried

- Created a **brand new Server-to-Server OAuth app**

- Copied **Account ID, Client ID, Client Secret** directly from App Credentials page

- Added scope: `user:update:user:admin`

- Activated the app after adding scopes

- Verified that I am using the correct endpoint:

- Sent `Authorization: Basic base64(ClientID:ClientSecret)` in the header

- Tested both with PowerShell and Python (same result)

- Rebooted my computer, cleared browser cache/cookies, and regenerated the client secret multiple times

- I am the **account owner** of this Zoom account

### Example PowerShell snippet I used

```auto
$clientId = "xxxxxx"
$clientSecret = "yyyyyy"
$accountId = "zzzzzz"

$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${clientId}:${clientSecret}"))
$headers = @{ Authorization = "Basic $auth" }
$uri = "https://zoom.us/oauth/token?grant_type=account_credentials&account_id=$accountId"

Invoke-RestMethod -Uri $uri -Headers $headers -Method Post

```

### Result

Always returns:

```auto
400 Bad Request
{"reason":"Invalid client_id or client_secret","error":"invalid_client"}

```

* * *

Could you please check on the backend why my credentials are being rejected, even for a brand new Server-to-Server OAuth app?

Thank you very much for your help!

---

<div class="post-metadata">

**Author:** ![MultiplayerSession](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/multiplayersession/32/66446_2.png) [@MultiplayerSession](https://devforum.zoom.us/u/MultiplayerSession)\
**Post date:** [September 22, 2025, 9:32pm UTC](https://devforum.zoom.us/t/server-to-server-oauth-app-always-returns-invalid-client-when-requesting-access-token/137579/2 "2025-09-22T21:32:06Z")

</div>

Could you move the query string into the request body and declare a `Content-Type: application/x-www-form-urlencoded; charset=utf-8` header? Our application uses the request body and so do most of the [Server-to-Server OAuth examples, including PowerShell](https://developers.zoom.us/docs/internal-apps/s2s-oauth/#powershell). This is also better for privacy since the request URL tends to be recorded in log files.

---

<div class="post-metadata">

**Author:** ![gianni.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/gianni.zoom/32/32523_2.png) [@gianni.zoom](https://devforum.zoom.us/u/gianni.zoom)\
**Post date:** [September 29, 2025, 5:24pm UTC](https://devforum.zoom.us/t/server-to-server-oauth-app-always-returns-invalid-client-when-requesting-access-token/137579/3 "2025-09-29T17:24:23Z")

</div>

@Kayla please let us know if @MultiplayerSession was helpful in resolving 🙂
