# Authentication

NexterPay uses **JWT Bearer tokens**. You exchange a username and password for a token, then include that token in the `Authorization` header on every subsequent request.

Authentication follows a simple flow:

1. POST your username and password to `/security/createToken`
2. Receive a JWT Bearer token
3. Include it in the `Authorization` header on every API call
4. Refresh before the token expires

Tokens are [short-lived](#token-expiry). The patterns below show you how to handle this gracefully.

***

## Generate a token

Send a <mark style="color:$danger;">**POST**</mark> request to `/security/createToken` with your credentials in the JSON body.

**Endpoint**: <mark style="color:$danger;">**POST**</mark> `/security/createToken`

> Exchange your username and password for a JWT Bearer token.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

<table><thead><tr><th width="129.50140380859375">Name</th><th width="123.037109375">Type</th><th width="131.5228271484375">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>userName</code></td><td>string</td><td>Yes</td><td>NexterPay API Username</td></tr><tr><td><code>password</code></td><td>string</td><td>Ys</td><td>NexterPay API Password</td></tr></tbody></table>

**Request**

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST "https://api-sandbox.nexterpay.io/security/createToken" \
  -H "Content-Type: application/json" \
  -d '{
    "userName": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD"
  }'
```

{% endtab %}

{% tab title="JSON" %}

```json
{
  "userName": "YOUR_USERNAME",
  "password": "YOUR_PASSWORD"
}
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const response = await fetch("https://api-sandbox.nexterpay.io/security/createToken", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userName: "YOUR_USERNAME",
    password: "YOUR_PASSWORD"
  })
});
```

{% endtab %}
{% endtabs %}

**Response**

The response is a **plain JWT string wrapped in double quotes,** not a JSON object.

{% tabs %}
{% tab title="200" %}
{% code overflow="wrap" %}

```json
"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJJZCI6Ijc4IiwiUm9sZSI6IkNsaWVudEFQSSIsInN1YiI6IkNJbnRzQm94SGFiODY2NDU0IiwiZW1haWwiOiJDSW50c0JveEhhYjg2NjQ1NCIsImp0aSI6IjQ3ZjExZGYyLWRkZGYtNDViYy04NDljLWIwNGUzNWJkNWnvovnkdnvdlnvonvlsknvnriurioaivnbvrubvi044tu4n9038903fnmHA6Ly9jbGt0by5jbyJ9.ksa_6Dduciem0vC8omdrkwzSFx09i3EJ5xu4bExi89txXl_ZE4o07JkUMvG4LgDsFZhZDApWFoBEyLKhCIyPOw"
```

{% endcode %}
{% endtab %}

{% tab title="401" %}

```json
{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
    "title": "Unauthorized",
    "status": 401
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Strip the outer quotes before using the token.** The response body is a JSON-encoded string, so it includes the leading and trailing `"`. Your code must remove them before placing the value in the `Authorization` header.
{% endhint %}

## Use the token

Include the token on every subsequent request as a Bearer value in the `Authorization` header.

```bash
curl -X POST "https://api-sandbox.nexterpay.io/Catalog/GetCountries" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json"
```

## Token expiry

<table><thead><tr><th width="337.3642578125">Environment</th><th>Token lifetime</th></tr></thead><tbody><tr><td>Sandbox</td><td><strong>600 minutes</strong> (10 hours)</td></tr><tr><td>Production</td><td><strong>90 minutes</strong> (1.5 hours)</td></tr></tbody></table>

After expiry, requests return `401 Unauthorized`. Re-request a token and retry.

### Handling expired tokens

A robust integration handles token refresh automatically. The pattern most teams use:

1. Store the token and its expiry time in memory.
2. Before every API call, check if the token is still valid.
3. If expired (or close to expiring), call `/security/createToken` to refresh.
4. Use the new token for the upcoming request.

This avoids ever surfacing a `401` to your users and keeps your integration resilient.

{% hint style="info" %}
**Recommended pattern.** Cache the token in memory with its issuance timestamp. Refresh proactively when the token is within \~10% of its lifetime remaining (i.e., at 540 minutes in sandbox, 81 minutes in production). Do not request a new token on every API call.
{% endhint %}

### Common auth errors

<table><thead><tr><th width="186.260986328125">Status</th><th>Meaning</th><th>Fix</th></tr></thead><tbody><tr><td><code>401 Unauthorized</code></td><td>Token missing, malformed, or expired.</td><td>Re-fetch a token. Check the <code>Authorization</code> header is set correctly.</td></tr><tr><td><code>400 Bad Request</code></td><td>Wrong credentials or malformed body.</td><td>Confirm <code>userName</code> and <code>password</code> are correct and JSON is valid.</td></tr><tr><td><code>403 Forbidden</code></td><td>Account suspended or restricted.</td><td>Contact your Nexterpay representative.</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nexterpay.io/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
