Skip to content

Authentication

MendriX uses a standard two-step token flow:

  1. Create an API token in the TMS (a long-lived credential, kept secret).
  2. Exchange it for a JWT at the account service’s login endpoint. You receive a short-lived access token and a longer-lived refresh token.

Every REST request then carries the access token as a Bearer JWT:

Authorization: Bearer ACCESS_TOKEN

API tokens are created inside the TMS desktop client — there is no self-service token-creation endpoint. This page explains the full flow.

An administrator (or any user with the Manage API tokens permission) creates tokens in the TMS desktop client:

  1. Open Administration → Settings → Miscellaneous settings.
  2. Open the Custom Link dialog.
  3. Go to the Api Tokens tab.
  4. Start the create-token wizard and choose:
    • Token type
      • Single client — the token is scoped to one client’s data only.
      • All clients — a master token (ClientId 0) that can act across all clients and carries permissions.
    • Layout
      • Single token — one secret string (used as the Bearer token).
      • Username + password — a credential pair, for tools that expect basic-style fields.
  5. Enter a label. Labels must be unique; use something descriptive such as crm-sync-prod.
  6. The system generates the secret, copies it to the clipboard, and shows it only once.
  • Master token (all clients, ClientId 0) — carries permissions and can access data across every client. Use it for back-office integrations that span the whole tenant. Guard it carefully.
  • Client-scoped token (single client) — limited to exactly one client’s data. Prefer these when an integration only needs one client, to limit blast radius.
  • Tokens do not expire.
  • There is no rotation endpoint. To rotate, create a new token, switch your integration over, then delete the old one.
  • Revocation = deleting the token in the same Api Tokens tab.

Log in at the account service with your API token to obtain a token pair:

POST https://<your-client-name>.api.mendrix.cloud/api/account/login-api-token
{ "token": "YOUR_API_TOKEN" }

The response contains a short-lived access token and a refresh token (valid for 7 days):

{
"data": {
"items": [
{
"access": "eyJhbGciOi…",
"refresh": "eyJhbGciOi…"
}
]
}
}

Use the access token as the Bearer token on every API call. The endpoints in the reference accept token types planner, apitoken and service (shown as x-token-types in the OpenAPI document); tokens obtained with this login are apitoken.

Terminal window
# 1. Log in with the API token (kept in an env var; never hard-code secrets)
ACCESS_TOKEN=$(curl -s -X POST \
"https://<your-client-name>.api.mendrix.cloud/api/account/login-api-token" \
-H "Content-Type: application/json" \
-d "{\"token\": \"$MENDRIX_API_TOKEN\"}" \
| jq -r '.data.items[0].access')
# 2. Call the API with the access token
curl https://<your-client-name>.api.mendrix.cloud/api/client/clients/ \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json"
const BASE = 'https://<your-client-name>.api.mendrix.cloud/api';
const API_TOKEN = process.env.MENDRIX_API_TOKEN; // never hard-code secrets
// 1. Exchange the API token for a token pair
const login = await fetch(`${BASE}/account/login-api-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: API_TOKEN }),
});
if (!login.ok) throw new Error(`Login failed: ${login.status}`);
const { access, refresh } = (await login.json()).data.items[0];
// 2. Call the API with the short-lived access token
const res = await fetch(`${BASE}/client/clients/`, {
headers: {
Authorization: `Bearer ${access}`,
Accept: 'application/json',
},
});
if (!res.ok) {
throw new Error(`MendriX API error ${res.status}: ${await res.text()}`);
}
const clients = await res.json();
console.log(clients);

The access token is deliberately short-lived. When it expires (the JWT’s exp claim, or a 401 response), either log in again with your API token, or refresh the pair:

POST https://<your-client-name>.api.mendrix.cloud/api/account/refresh
{ "access": "EXPIRED_ACCESS_TOKEN", "refresh": "CURRENT_REFRESH_TOKEN" }

The response has the same shape as the login response and contains a new access + refresh pair.

For long-running integrations the simplest robust strategy is: log in, use the access token until a 401, then log in again. Refresh is an optimisation, not a requirement.

  • Never commit tokens. Keep them in environment variables or a secret manager. All examples in this portal use obvious placeholders such as YOUR_API_TOKEN and ACCESS_TOKEN.
  • Access and refresh tokens are secrets too. Keep them in memory (or a secret store), never in logs or exported workflow files.
  • Scope down. Prefer a client-scoped token when you only need one client.
  • One token per integration. Separate tokens make revocation and auditing painless — delete one without disturbing the others.
  • Transport security. Always call over HTTPS; the token is a bearer credential and grants access to anyone who holds it.