{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-tutorials/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Troubleshooting Unauthorized (401) Errors","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"troubleshooting-unauthorized-401-errors","__idx":0},"children":["Troubleshooting Unauthorized (401) Errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This guide explains the most common causes of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}," responses when calling the Rhythm APIs and how to resolve them."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"1-confirm-the-authorization-header","__idx":1},"children":["1. Confirm the Authorization header"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All Rhythm APIs require a valid OAuth 2.0 access token sent using the Bearer scheme:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Authorization: Bearer <access_token>\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Ensure:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The header name is exactly ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The value starts with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Bearer"]}," (including the space)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The token has not expired"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"2-verify-the-oauth-audience-configuration","__idx":2},"children":["2. Verify the OAuth audience configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A frequent cause of 401 errors is an incorrect OAuth ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["audience"]}," value when requesting the access token."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For Client Credentials and most server-to-server flows, the audience must be:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"https://api.rhythmsoftware.com\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the audience does not match what the API expects, the token will be rejected even if it is otherwise valid."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Getting credentials"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Client ID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Secret"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Auth0 domain"]}," are available in Rhythm Console under ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Security & Settings > API Keys"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["See the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/tutorials/authentication"},"children":["Authentication"]}," tutorial for a full walkthrough of each flow."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"3-decode-the-access-token-and-validate-required-claims","__idx":3},"children":["3. Decode the access token and validate required claims"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Decode the JWT access token and confirm the following claims are present:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http://rhythmsoftware.com/tenant_id"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http://rhythmsoftware.com/customer_id"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Optional but commonly present:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http://rhythmsoftware.com/contact_id"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contact_id"]}," claim is required for most Rolodex and Membership API calls and must be used in request paths where a contact identifier is required."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Decoding JWTs"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can inspect a JWT at ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://jwt.io"},"children":["https://jwt.io"]}," — paste the raw token into the Encoded field to view all claims."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"4-first-time-login-edge-case","__idx":4},"children":["4. First-time login edge case"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the user represented by the token has ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["never logged into the Rhythm application"]},", the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contact_id"]}," claim may not yet exist. In this case:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The token may be valid"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["API calls that require a contact context will still return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Have the user log into the Rhythm UI at least once to ensure the contact record is created."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"5-validate-the-contact-using-the-rolodex-api","__idx":5},"children":["5. Validate the contact using the Rolodex API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can confirm that the token resolves to a valid contact by calling the Rolodex endpoint:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"GET https://rolodex.api.rhythmsoftware.com/contacts/current\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If this call succeeds, the token is valid and the contact is correctly associated."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"6-confirm-the-correct-api-base-url","__idx":6},"children":["6. Confirm the correct API base URL"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Different Rhythm services use different base URLs. Common examples:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Rolodex API: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://rolodex.api.rhythmsoftware.com/contacts"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Membership API: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://membership.api.rhythmsoftware.com/memberships"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Using the wrong service base URL with an otherwise valid token may result in a 401 response."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"summary-checklist","__idx":7},"children":["Summary checklist"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you receive a 401 Unauthorized error, verify:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization: Bearer"]}," header is present and correct"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The token has not expired"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The OAuth audience is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.rhythmsoftware.com"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The token contains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tenant_id"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contact_id"]}," claims"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The user has logged into the Rhythm UI at least once"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The request is sent to the correct service base URL"]}]}]},"headings":[{"value":"Troubleshooting Unauthorized (401) Errors","id":"troubleshooting-unauthorized-401-errors","depth":1},{"value":"1. Confirm the Authorization header","id":"1-confirm-the-authorization-header","depth":2},{"value":"2. Verify the OAuth audience configuration","id":"2-verify-the-oauth-audience-configuration","depth":2},{"value":"3. Decode the access token and validate required claims","id":"3-decode-the-access-token-and-validate-required-claims","depth":2},{"value":"4. First-time login edge case","id":"4-first-time-login-edge-case","depth":2},{"value":"5. Validate the contact using the Rolodex API","id":"5-validate-the-contact-using-the-rolodex-api","depth":2},{"value":"6. Confirm the correct API base URL","id":"6-confirm-the-correct-api-base-url","depth":2},{"value":"Summary checklist","id":"summary-checklist","depth":2}],"frontmatter":{"seo":{"title":"Troubleshooting Unauthorized (401) Errors"}},"lastModified":"2026-05-18T15:58:00.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/tutorials/troubleshooting-401","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}