---
title: "OAuth2.0 authentication"
slug: "oauth20"
updated: 2026-07-02T08:54:37Z
published: 2026-07-02T08:54:37Z
canonical: "docs.xtremepush.com/oauth20"
stale: true
---

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

# OAuth2.0 authentication

Use OAuth 2.0 authentication to make secure calls to the Xtremepush External API. You can create, manage, and delete tokens independently for different connections.

The `/api/oauth/token` endpoint supports the following grant types:

- **JWT Bearer Authentication** (`urn:ietf:params:oauth:grant-type:jwt-bearer`): Exchange a signed JWT token for an access token.
- **Client Secret Authentication** (`client_credentials`): Authenticate using a client ID and client secret.

Only `POST` requests are accepted on the `/api/oauth/token` endpoint.

## JWT Bearer Authentication

To authenticate using the `jwt-bearer` grant type:

1. You generate a public/private key pair.
2. Create your client ID and upload your public key to Xtremepush.
3. Sign a JWT token with your private key and exchange it for an access token.
4. Use the access token in your API requests.

### Generate a public/private key pair

To use JWT bearer authentication, you must generate a public/private key pair and upload the public key to Xtremepush. Two public key formats are supported:

- **X.509 Certificate**: Contains the public key and an expiry date. The expiry is read from the certificate and displayed in the UI. Xtremepush validates the certificate for expiry (`exp`) and valid from (`iat`) on upload and on each request. If your certificate has expired, API requests will fail.
- **Public Key (SPKI format)**: Contains only the public key with no expiry. You must set the token expiry manually in the **API Integrations** page.

The key pair you generate must use one of the following algorithms. Xtremepush enforces minimum key lengths for FIPS 140 compliance:

| Algorithm | Minimum key length |
| --- | --- |
| `RS256` | RSA 2048-bit |
| `RS384` | RSA 4096-bit |
| `RS512` | RSA 8192-bit |
| `ES256` | EC, SECG secp256r1 / X9.62 prime256v1 / NIST P-256 |
| `ES384` | EC, SECG secp384r1 / X9.63 ansip384r1 / NIST P-384 |
| `ES512` | EC, SECG secp521r1 / X9.63 ansip521r1 / NIST P-521 |

The following shows examples of how to create a public/private key pair using RSA 2048:

**SPKI public key**

**OpenSSL (RSA)**

```shell
#generate a private RSA key with the correct length 2048 (RS256)
openssl genrsa -out privatekey.pem 2048
#output public RSA key
openssl rsa -pubout -in privatekey.pem -out publickey.pem
```

**OpenSSL (EC)**

```shell
# generate a private EC key (ES256)
openssl ecparam -name prime256v1 -genkey -noout -out privatekey.pem
# output public EC key
openssl ec -in privatekey.pem -pubout -out publickey.pem
```

**X.509 Certificate**

**OpenSSL (RSA)**

```shell
# generate a private key with the correct length
openssl genrsa -out privatekey.pem 2048

# generate corresponding public key
# Enter the maximum number of days the cerficate if valid for in MAX CERT AGE
openssl req -new -x509 -key privatekey.pem -out pubcert.pem -days <MAX_CERT_AGE>
```

**OpenSSL (EC)**

```shell
# generate a private EC key (ES256)
openssl ecparam -name prime256v1 -genkey -noout -out privatekey.pem

# generate corresponding public key
# Enter the maximum number of days the cerficate if valid for in MAX CERT AGE
openssl req -new -x509 -key privatekey.pem -out pubcert.pem -days <MAX_CERT_AGE>
```

**Java KeyStore (RSA)**

```shell
# This command will ask for additional information. In the last step type `yes` and press Enter
keytool -genkey -alias <UNIQUE_KEY_IDENTIFIER> -keyalg RSA -keysize 2048 -validity <MAX_CERT_AGE> -keystore xtremepush.jks
# Import keys from the KeyStore
keytool -importkeystore -srckeystore xtremepush.jks -destkeystore xtremepush.p12 -deststoretype PKCS12
# Export the public and private keys
openssl pkcs12 -in xtremepush.p12 -nokeys -out pubcert.pem
openssl pkcs12 -in xtremepush.p12 -nodes -nocerts -out privatekey.pem
```

**Java Keystore (EC)**

```shell
keytool -genkeypair \
  -alias <UNIQUE_KEY_IDENTIFIER> \
  -keyalg EC \
  -groupname secp256r1 \
  -sigalg SHA256withECDSA \
  -validity <MAX_CERT_AGE> \
  -keystore xtremepush.jks
keytool -importkeystore \
  -srckeystore xtremepush.jks \
  -destkeystore xtremepush.p12 \
  -deststoretype PKCS12
openssl pkcs12 -in xtremepush.p12 -nokeys -out pubcert.pem
openssl pkcs12 -in xtremepush.p12 -nodes -nocerts -out privatekey.pem
```

In MacOS/Linux, you can use the following command to copy the contents of the certificate for the next steps:

```shell
pbcopy < filename.pem
```

### Add a client ID

1. Go to **Settings > Integrations > API Integration**.
2. Click **Add Client ID**.
3. Enter a name in the **Name** field to identify your client ID.
4. In the **Type** dropdown, select **Public Key**.
5. (Optional) If you are uploading a public key in SPKI format, set an expiration date in the **Expires At** field.
6. Click **Save**.
7. In the row for your new client ID, click **Add Key**.
8. Paste the contents of your X.509 certificate or SPKI public key into the text area, then click **Add**.
9. (Optional) Click **Set Scopes** in the row to restrict the permissions for this client ID. All scopes are selected by default. See [API Access and Permissions](/documentation/docs/set-scopes) for more details on setting scopes.

### Obtain a JWT token

Sign a JWT token with your private key using the payload structure below, then exchange it for an access token.

```json
{
    "iss": "<UNIQUE_KEY_IDENTIFIER>",
    "sub": "<UNIQUE_KEY_IDENTIFIER>",
    "aud": "<ENDPOINT_URL>",
    "exp": 1541054464,
    "iat": 1521054464,
    "nbf": 1521054464,
    "jti": "example1234",
    "lifetime": 86400
}
```

| Field | Required | Description |
| --- | --- | --- |
| `iss` | Required | Your client ID from the **API Integrations** page |
| `sub` | Required | Your client ID from the **API Integrations** page |
| `aud` | Required | The URL of the `/api/oauth/token` endpoint you are sending the request to. For example, `https://api.eu.xtremepush.com/api/oauth/token` |
| `exp` | Required | Expiry timestamp (epoch). Keep this short as access tokens cannot be revoked once issued |
| `iat` | Required | The time this JWT was created (epoch) |
| `nbf` | Optional | Timestamp (epoch) that defines when the token becomes valid. The server will reject requests made before this time. Useful if you want to issue a token in advance but delay when it can be used. |
| `jti` | Optional | A unique one-time identifier for this token. Use a UUIDv4 or equivalent. Each `jti` value can only be used once to prevent replay attacks. |
| `lifetime` | Optional | Sets how long the returned access token remains valid, in seconds, calculated from the time of the request. The maximum value is `86400` seconds, and cannot extend past the expiration of the Client ID configured in the UI. |

### Exchange the JWT token for an access token

Send the following request to exchange your JWT token for an access token:

**Shell**

```shell
POST /api/oauth/token HTTP/1.1
Host: <your-instance>
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<jwt_token>
```

**JSON**

```json
POST /api/oauth/token
Content-Type: application/json
{
  "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
  "assertion": "<jwt_token>"
}
```

> [!WARNING]
> **Legacy authentication method deprecated**
> 
> The previous method of passing the JWT directly as `Authorization: Bearer &lt;jwt_token&gt;` is deprecated and will be removed in a future release. Migrate to the `grant_type` method above.

The endpoint returns the following response:

```json
{
    "access_token": "<ACCESS_TOKEN>",
    "token_type": "Bearer",
    "expires_in": 86400
}
```

> [!TIP]
> **Access token lifetime**
> 
> You can set the access token lifetime up to `86400` seconds by including a `lifetime` claim in your JWT token. The lifetime cannot extend past the expiration of the **Client ID** configured in the UI.
> 
> 
> 
> The default may be reduced in future, so always adhere to the lifetime indicated in the response from the `/oauth/token` endpoint. Access tokens cannot be revoked once issued. Use short expiry times and rotate keys regularly.
> 
> 
> 
> If you receive a `401` response, request a new token even if the current token has not yet expired.

### Use the token in your API Requests

Add the `Authorization` header to all External API requests:

```shell
Authorization: Bearer <access_token>
```

## Client Secret Authentication

Use this method with the `client_credentials` grant type. Xtremepush generates a client secret for you when you create a client ID. No key pair is required.

To authenticate using the `client_credentials` grant type:

1. Create a client ID in Xtremepush to generate a client secret.
2. Exchange your client ID and secret for an access token.
3. Use the access token in your API requests.

### Add a client ID

1. Go to **Settings > Integrations > API Integration**.
2. Click **Add Client ID**.
3. Enter a name in the **Name** field as an internal reference.
4. In the **Type** dropdown, select **Secret**.
5. (Optional) Set an expiration date in the **Expires At** field.
6. Click **Save**.
7. A **Client Secret Generated** dialog appears displaying your client secret. Copy and store it securely, as it will not be shown again.
8. (Optional) Click **Set Scopes** in the row to restrict the permissions for this client ID. All scopes are selected by default. See [API Access and Permissions](/documentation/docs/set-scopes) for more details on setting scopes.

### Obtain a token

Send the following request to exchange your client credentials for an access token:

```shell
POST /api/oauth/token HTTP/1.1
Host: <your-instance>
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&lifetime=86400
```

The endpoint returns the following response:

```json
{
    "access_token": "<ACCESS_TOKEN>",
    "token_type": "Bearer",
    "expires_in": 86400
}
```

> [!TIP]
> **Access Token Lifetime**
> 
> You can set the access token lifetime up to `86400` seconds by including a `lifetime` claim in your JWT token. The lifetime cannot extend past the expiration of the **Client ID** configured in the UI.
> 
> 
> 
> The default may be reduced in future, so always adhere to the lifetime indicated in the response from the `/oauth/token` endpoint. Access tokens cannot be revoked once issued. Use short expiry times and rotate keys regularly.
> 
> 
> 
> If you receive a `401` response, request a new token even if the current token has not yet expired.

### Use the token in your API requests

Add the `Authorization` header to all External API requests:

```shell
Authorization: Bearer <access_token>
```
