> ## Documentation Index
> Fetch the complete documentation index at: https://developer.suki.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 401 Unauthorized or Invalid Partner Token

> Tell Partner Token Login failures apart from invalid_sdp_token on later Suki Token calls

A **401** can mean two different things. Suki rejected your **Partner Token** at Register or Login, or a later REST or WebSocket call sent a missing, expired, or invalid **Suki Token** (`sdp_suki_token`). Read the error message before you change credentials.

## Which 401 you have

| Symptom | Likely cause | Where it appears |
| :- | :- | :- |
| `401 Unauthorized` with "Token validation failed" | Partner Token JWT failed validation | [Register](/api-reference/authentication/register) or [Login](/api-reference/authentication/login), or SDK sign-in that exchanges the Partner Token |
| Error id `invalid_sdp_token` (message may be `invalid sdp token` or `invalid_sdp_token: …`) | Missing, expired, or invalid `sdp_suki_token` | Partner API REST or WebSocket calls after Login |
| Error id `provider_not_registered` | Clinician was never registered via `/auth/register` | Provider-scoped API calls |

<Note>
  On Partner APIs, Login returns `suki_token`. Send that value as the `sdp_suki_token` header on later REST and WebSocket calls. A Partner Token alone is not enough for session, stream, or content endpoints.
</Note>

## Partner Token validation failed

Suki validates the Partner Token (JWT) with your Partner ID and the public keys you registered (usually a JWKS URL). Validation fails when the JWT is expired, missing required claims, malformed, or signed with a key Suki cannot verify.

### Required JWT claims

Confirm these claims are present and valid before you call Suki (decode with [jwt.io](https://jwt.io/) if needed):

* **`exp`** - Token expiration time (Unix timestamp). The token must not be expired when you send it.
* **`iss`** - Token issuer (usually your identity provider URL or identifier).
* **`aud`** - Token audience (who the token is intended for).
* **User identifier** - A claim that uniquely identifies the user, such as `sub`, `email`, or a custom claim like `userId`. During onboarding you tell Suki which field is primary.

The Partner Token must be signed with **RS256** and follow standard JWT format: `header.payload.signature`.

### Fix Partner Token failures

<Steps>
  <Step title="Confirm field names for your integration">
    **Partner APIs:** Send `partner_id` and `partner_token` in the Register and Login request body. For Bearer and Single Auth Token partners, also send `provider_id` when required.

    **SDKs:** Pass `partnerId` and `partnerToken` (for example through `SukiAuthManager` or the Headless auth hook).
  </Step>

  <Step title="Decode and inspect the JWT">
    Check `exp`, `iss`, `aud`, and the user identifier claim you registered during onboarding. Fix empty or null identifier values.
  </Step>

  <Step title="Verify signing keys">
    Confirm your JWKS URL (or other public-key method) is reachable over HTTPS and that the `kid` in the JWT header matches a key in that JWKS set. After key rotation, keep old keys available during the transition.
  </Step>

  <Step title="Match Partner ID to onboarding">
    Use the Partner ID Suki issued for your account. A wrong Partner ID returns **400** with "Unknown partner identifier", not a successful token exchange.
  </Step>
</Steps>

<AccordionGroup>
  <Accordion title="Related Partner Token errors (not always 401)">
    | Error | HTTP | Fix |
    | :- | :- | :- |
    | Missing required identifier claim | 400 | Include the user identifier claim you specified during onboarding |
    | Malformed token | 400 | Use `header.payload.signature`, Base64URL encoding, and `alg` RS256 |
    | Unknown partner identifier | 400 | Use the Partner ID from onboarding |
    | JWKS endpoint not accessible | 502 or timeout | Make the JWKS URL publicly reachable over HTTPS |
  </Accordion>
</AccordionGroup>

## invalid\_sdp\_token on later calls

After Login succeeds, Partner API calls authorize with the Suki Token. The common error id is `invalid_sdp_token` (**401**): missing, expired, or invalid `sdp_suki_token`.

<Steps>
  <Step title="Confirm Login succeeded">
    Call [Login](/api-reference/authentication/login) and read `suki_token` from the response. Do not reuse a Partner Token as `sdp_suki_token`.
  </Step>

  <Step title="Send the documented header">
    Set the `sdp_suki_token` header on subsequent REST and WebSocket requests. Use the same environment host for Login and for those calls.
  </Step>

  <Step title="Refresh before or after expiry">
    The Suki Token is valid for **1 hour**. Call Login again with a valid Partner Token to refresh, then update clients with the new `sdp_suki_token`. See [Suki Token expired during a long session](/documentation/troubleshooting/suki-token-expired).
  </Step>
</Steps>

<Warning>
  `invalid_sdp_token` is not a Partner Token Login failure. Fixing only `partner_token` does not help if later calls omit or keep a stale `sdp_suki_token`.
</Warning>

## Next steps

<Icon icon="file-lines" iconType="solid" /> **[Partner authentication](/documentation/how-to/partner-authentication)** - Token exchange, JWT claims, and auth troubleshooting

<Icon icon="file-lines" iconType="solid" /> **[Login](/api-reference/authentication/login)** - Exchange `partner_id` and `partner_token` for `suki_token`

<Icon icon="file-lines" iconType="solid" /> **[Ambient and Dictation error messages](/api-reference/error-messages)** - Look up `invalid_sdp_token` and related ids

<Icon icon="file-lines" iconType="solid" /> **[Suki Token expired during a long session](/documentation/troubleshooting/suki-token-expired)** - Refresh after the 1 hour lifetime

<Icon icon="file-lines" iconType="solid" /> **[Wrong staging vs production endpoints](/documentation/troubleshooting/wrong-environment-endpoints)** - Align hosts, tokens, and SDK environment
