> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://help.moveworks.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://help.moveworks.com/_mcp/server.

# Set up authentication with Okta

The Conversations API is in **Controlled Availability**. Endpoints, behaviors, and configuration surfaces may change during CA. Contact your Moveworks account team to participate.

This guide walks through configuring Okta to authenticate against the Moveworks Conversations API.

## Which Okta authorization server to use

The one decision that shapes your configuration is which authorization server issues the token.

| Authorization server                          | `aud` behavior                                         | What to do with the Audience field                                                                                                                      |
| --------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Custom Authorization Server** (recommended) | You control the audience. You can set it to any value. | **Leave the Audience field blank.** Moveworks generates a unique audience, which you then set as the audience on your Okta custom authorization server. |
| **Org Authorization Server**                  | Fixed to your Okta org URL. Cannot be customized.      | **Populate the Audience field** with your Okta org URL (the fixed `aud` value your tokens carry).                                                       |

Okta's `sub` claim typically carries a usable identifier such as the user's username or email, so the default `sub` claim works for identity resolution.

## Prerequisites

Confirm the following with your Moveworks account team:

* Your Moveworks tenant is provisioned for the Conversations API and your account team has provided the **Bot Name** (used in the `Assistant-Name` header on every API call).
* You have access to the Moveworks Admin Portal (`https://{org}.moveworks.com`).
* You have admin access to your Okta org, including the authorization server you intend to use.
* The identifier your Okta `sub` claim will carry (commonly the user's email) is already resolvable against your Moveworks user roster.

## Step 1: Create the JWT OAuth credential in Moveworks

In the Moveworks Admin Portal, go to `https://{org}.moveworks.com/http-connectors/connector_studio/home` → **Credentials** → create a new credential, and set the fields as follows.

| Field                | Value for Okta                                                                                                                   | Notes                                                                                                                                                                                                                                                                                                                                              |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Credential Name**  | A descriptive label, e.g. `Okta-CAPI`                                                                                            | Free text.                                                                                                                                                                                                                                                                                                                                         |
| **Credential Type**  | `JWT OAuth`                                                                                                                      | Reveals the fields below.                                                                                                                                                                                                                                                                                                                          |
| **Public Key value** | Your authorization server's metadata URL, e.g. `https://{yourOktaDomain}/oauth2/{authServerId}/.well-known/openid-configuration` | This field accepts a **WKE (well-known endpoint) URL** in place of a PEM string. In Okta this is the **Metadata URI** under Security → API → Authorization Server → Settings. Moveworks auto-discovers the issuer and fetches the JWKS signing keys from it. For the Org Authorization Server, the URL omits the `/oauth2/{authServerId}` segment. |
| **Audience**         | **Custom Auth Server:** leave blank. **Org Auth Server:** your Okta org URL.                                                     | With a Custom Authorization Server, leave blank so Moveworks mints a unique audience for you to configure in Okta. With the Org Authorization Server, `aud` is fixed to the Okta org URL, so enter that exact value.                                                                                                                               |
| **Issuer**           | Your authorization server's issuer, e.g. `https://{yourOktaDomain}/oauth2/{authServerId}`                                        | The `iss` claim your tokens carry. Together with Audience, it uniquely identifies this credential. Org Authorization Server issuer is `https://{yourOktaDomain}`.                                                                                                                                                                                  |
| **Identifier Type**  | `IdP`                                                                                                                            | Tells Moveworks to resolve the identifier claim through an integration rather than as a raw email or record ID.                                                                                                                                                                                                                                    |
| **Integration ID**   | `conversations_rest_api`                                                                                                         | Required when Identifier Type is `IdP`. Moveworks matches the `sub` claim against the user's Conversations API channel entry on their profile.                                                                                                                                                                                                     |
| **Identifier Claim** | `sub` (default)                                                                                                                  | Leave as the default `sub`, since Okta's `sub` is a usable identifier. Set it to `email` only if your identifier lives in a different claim.                                                                                                                                                                                                       |

Save the credential. If you left Audience blank, note the unique audience value Moveworks displays; you will configure it in Okta next.

## Step 2: Configure Okta

#### Create the OAuth application

In the Okta Admin Console, create a new OIDC application. For browser-based clients use a **Single-Page Application** with the Authorization Code flow and PKCE enabled. For backend clients use a **Web Application** as appropriate.

#### Assign users or groups

Assign the users or groups that should have access to the application.

#### Add trusted origins (browser clients only)

Under **Security → API → Trusted Origins**, add your application's domain with CORS and Redirect enabled.

#### Configure the authorization server

Use (or create) a **Custom Authorization Server** under **Security → API → Authorization Servers**. If you left the Audience field blank in Moveworks, set this authorization server's audience to the unique value Moveworks generated. On the Org Authorization Server the audience is fixed to the Okta org URL and cannot be changed, which is why you register that value in Moveworks instead.

#### Confirm scopes and claims

Ensure `openid` is available at minimum, so the user's identity is present in the token. Confirm the `sub` claim carries the identifier that resolves against the Moveworks user roster.

#### Grant access via policy

On the authorization server's **Access Policies** tab, add a policy that grants the application access to the authorization server. Without this attachment, tokens for the application will be denied by the access policy at issuance time.

## Step 3: Validate

The examples below use `https://api.moveworks.ai`, which is only correct for orgs on the US Production data center. Replace it with the base URL for your data center from the [Base URLs table](/api-reference/overview#base-urls) (for example, `https://api.am-eu-central.moveworks.ai` for EU). Requests to the wrong host return 404 or `invalid_audience`.

### 3.1 Inspect a token

Obtain an access token from Okta for a test user (via the Okta SDK or the `/v1/token` endpoint with PKCE) and decode it (for example, at [jwt.io](https://jwt.io/)). Confirm:

* `iss` matches the Issuer you registered.
* `aud` matches what you registered (the Moveworks-generated audience for a Custom Auth Server, or the Okta org URL for the Org Auth Server).
* `sub` is present and matches the identifier your Moveworks user roster expects.

### 3.2 Exchange for a Moveworks token

```bash
curl -X POST "https://api.moveworks.ai/oauth/v1/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
  --data-urlencode "assertion=<OKTA_ACCESS_TOKEN>"
```

A successful response returns a Moveworks access token (valid \~1 hour).

### 3.3 Test the API

```bash
curl -X POST "https://api.moveworks.ai/assistant/v1/conversations" \
  -H "Content-Type: application/json" \
  -H "Assistant-Name: <YOUR_BOT_NAME>" \
  -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
  -d '{"title": "Test conversation"}'
```

A `201` with a `conversation_id` confirms the integration works end to end.

## Summary

| Credential field | Okta value                                                                                               |
| ---------------- | -------------------------------------------------------------------------------------------------------- |
| Public Key value | WKE URL: `https://{yourOktaDomain}/oauth2/{authServerId}/.well-known/openid-configuration`               |
| Audience         | Custom Auth Server: blank (Moveworks mints it). Org Auth Server: Okta org URL.                           |
| Issuer           | `https://{yourOktaDomain}/oauth2/{authServerId}`                                                         |
| Identifier Type  | `IdP`                                                                                                    |
| Integration ID   | `conversations_rest_api`                                                                                 |
| Identifier Claim | `sub` (default)                                                                                          |
| Okta side        | Set the custom auth server audience to the Moveworks-generated value (if used). No custom claims needed. |

For interaction patterns (polling and streaming) and the full API contract, see the [Conversations API reference](/api-reference/beta-conversations-api).