---
title: Authentication
slug: devdocs/fa59-authentication
docTags: 
createdAt: 2026-10-22T08:35:58.955Z
---

The Accounting API uses a **JWT token**. You get it with a separate `POST` request to the Expressoft authentication service, then send it with every GraphQL request.

## Get a token

`POST https://sandbox.expressoft.eu/connect.services/auth/api/interop/Authentication/Token`

**Request body**

```json
{
  "applicationId": "CloudInteropApplication",
  "applicationVersion": "1.0.0.0",
  "userName": "<your API user name>",
  "password": "<your API password>"
}
```

| **Field**            | **Type** | **Required** | **Description**                                                                               |
| -------------------- | -------- | ------------ | --------------------------------------------------------------------------------------------- |
| `applicationId`      | string   | yes          | The application identifier. For ERP and interop integrations it is `CloudInteropApplication`. |
| `applicationVersion` | string   | yes          | The version of your API client, as `X.X.X.X` (for example `1.0.0.0`).                         |
| `userName`           | string   | yes          | The user name that Expressoft gave you.                                                       |
| `password`           | string   | yes          | The password of the user.                                                                     |
| `languageCode`       | string   | no           | The language code.                                                                            |

**cURL**

```bash
curl --location 'https://sandbox.expressoft.eu/connect.services/auth/api/interop/Authentication/Token' \n--header 'Content-Type: application/json' \n--data '{"applicationId": "CloudInteropApplication", "applicationVersion": "1.0.0.0", "userName": "<your API user name>", "password": "<your API password>"}'
```

**Response**

```json
{
  "token": "<JWT token>",
  "tokenExpireOn": "2026-10-20T02:19:46.24+03:00",
  "extension": {
    "apiURL": "https://sandbox.expressoft.eu/connect/api/interopgql"
  },
  "refreshToken": null,
  "errorCode": null,
  "errorMessage": null
}
```

`extension.apiURL` is the URL of the GraphQL endpoint to call. Use it, don't hardcode another URL.

## Errors

When authentication fails, the response is **400 Bad Request**. It contains a code and a message, for example:

| **Message**             | **Cause**                                    |
| ----------------------- | -------------------------------------------- |
| `InvalidCredentials`    | The user name or the password is wrong.      |
| `unknown applicationId` | The server doesn't know the `applicationId`. |

## Use the token

```text
Authorization: Bearer <token>
```

Without this header, or with an expired or invalid token, the server answers with an authorization error and returns no data.

## Renew the token

The token has a limited life: see `tokenExpireOn`. Get a new token before it expires. Don't store it permanently.

## Permission

Your user needs the **Accounting** permission (the `ConnectAccounting` claim). Without it, every query is rejected:

```json
{
  "errors": [
    {
      "message": "You are not authorized to run this query.\nRequired claim 'ConnectAccounting' is not present.",
      "extensions": {
        "code": "VALIDATION_ERROR"
      }
    }
  ]
}
```

If you see this error, ask Expressoft to add the permission to your user.

:::BlockQuote
⚠️ **WARNING**
Keep the user name, password and token private. Never store them in client-side code or in a public repository.
:::

:::BlockQuote
🔶 **TO CONFIRM (remove before publishing)**
The other API pages use the token endpoint `https://sandbox.expressoft.eu/connect/api/authentication/interop/token`. Confirm that it is equivalent to the endpoint above, and which one to publish.
:::

