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

# Authentication

Users can generate new API Tokens in the User Profile/Access Tokens tab in [Phrase Platform Settings page](https://eu.phrase.com/idm-ui/settings/access-tokens).
Supported applications are:

* Phrase Connectors API
* Phrase Language AI
* Phrase Strings
* Phrase Studio
* Phrase TMS
* Quality Evaluator API
* Phrase Style Guides
* Phrase Content Groups

#### Exchanging API tokens for JWT

Exchange the generated API Token for Access Token using Phrase Platform OAuth Token endpoint with `urn:ietf:params:oauth:grant-type:token-exchange` grant type.
This is extension of OAuth basic grants which is specified in OAuth 2.0 Token Exchange ([RFC-8693](https://www.rfc-editor.org/rfc/rfc8693.html)). Supported parameters are:

| Parameter name         | Value                                             | Required |
| ---------------------- | ------------------------------------------------- | -------- |
| `grant_type`           | `urn:ietf:params:oauth:grant-type:token-exchange` | yes      |
| `subject_token`        | *API-TOKEN*                                       | yes      |
| `subject_token_type`   | `urn:phrase:params:oauth:token-type:api_token`    | no       |
| `requested_token_type` | `urn:ietf:params:oauth:token-type:access_token`   | no       |

Other fields from the Specification are not supported at the moment.

Main endpoint URLs:

* `https://eu.phrase.com/idm/oauth/token` (EU datacenter)
* `https://us.phrase.com/idm/oauth/token` (US datacenter)

##### Sample request

```http theme={null}
POST https://eu.phrase.com/idm/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=API-TOKEN
```

With [curl](https://curl.se/):

```shell theme={null}
# EU region
curl -X POST https://eu.phrase.com/idm/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
  -d 'subject_token=API-TOKEN'

# US region
curl -X POST https://us.phrase.com/idm/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
  -d 'subject_token=API-TOKEN'
```

The response is in JSON format:

```json theme={null}
{
  "access_token": "GENERATED-JWT",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 14399 
}
```

* `access_token` - the generated JWT access token
* `issued_token_type` - the type of returned token, always `urn:ietf:params:oauth:token-type:access_token`
* `token_type` - how to use the token, always `Bearer`
* `expires_in` - validity of the token in seconds

#### Machine-to-Machine authentication (Service Accounts)

For server-to-server integrations that don't involve a human user, create a Service Account in **Organization Settings → Service Accounts**. Each Service Account provisions a bot user scoped to one or more Phrase products, and authenticates using the standard OAuth 2.0 Client Credentials flow — no API token or token-exchange step needed.

Creating a Service Account generates a `client_id` and `client_secret`, shown once. Exchange them directly for an access token against the same Phrase Platform OAuth Token endpoint. Supported parameters are:

| Parameter name  | Value                                                                                                                                                                                                                                                                                             | Required |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `grant_type`    | `client_credentials`                                                                                                                                                                                                                                                                              | yes      |
| `client_id`     | *CLIENT-ID*                                                                                                                                                                                                                                                                                       | yes      |
| `client_secret` | *CLIENT-SECRET*                                                                                                                                                                                                                                                                                   | yes      |
| `resource`      | Space-separated list of product UIDs (e.g. `strings`, `tms`) to restrict the token to. Omit to cover every product configured on the Service Account.                                                                                                                                             | no       |
| `scope`         | Space-separated list of requested scopes. Must be granted by at least one of the targeted products — a product that doesn't grant any requested scope is simply left out of the resulting token rather than failing the whole request. Omit to get each targeted product's full configured scope. | no       |

##### Sample request

```http theme={null}
POST https://eu.phrase.com/idm/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=CLIENT-ID&client_secret=CLIENT-SECRET
```

With [curl](https://curl.se/):

```shell theme={null}
# EU region
curl -X POST https://eu.phrase.com/idm/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d 'client_id=CLIENT-ID' \
  -d 'client_secret=CLIENT-SECRET'

# US region
curl -X POST https://us.phrase.com/idm/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d 'client_id=CLIENT-ID' \
  -d 'client_secret=CLIENT-SECRET'
```

The response is in JSON format:

```json theme={null}
{
  "access_token": "GENERATED-JWT",
  "token_type": "Bearer",
  "expires_in": 14399,
  "scope": "strings:read strings:write tms:default"
}
```

* `access_token` - the generated JWT access token
* `token_type` - how to use the token, always `Bearer`
* `expires_in` - validity of the token in seconds
* `scope` - space-separated, prefixed by product UID (e.g. `strings:read`); a product with no requested/configured scope still appears in the token's audience without contributing to this claim

##### Good to know

* Bot users show up in product UIs with a bot badge but can't log in interactively. They can read/write content, run analyses, and work with translation memories — but can't create or modify human users, or be assigned as project owners. They don't count toward seat quotas. The only way to remove a bot user is to delete its Service Account.

#### Using JWT in APIs

Use the token to access Platform APIs of specific application - passing it in HTTP Authorization Header:

```
Authorization: Bearer GENERATED-JWT
```
