Skip to content

IZI API Authentication & Tokens

Published: · Updated: (12 days ago)· IZI Team

IZI API uses JWT (JSON Web Token) — a standard stateless authentication mechanism. Two tokens: a short-lived accessToken for requests and a long-lived refreshToken to renew it.

mutation Login($email: String!, $password: String!) {
loginWithEmailPassword(email: $email, password: $password) {
accessToken
refreshToken
user {
id
email
role
}
}
}
{
"email": "partner@example.com",
"password": "your_password"
}

Response:

{
"data": {
"loginWithEmailPassword": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"user": {
"id": "user_abc123",
"email": "partner@example.com",
"role": "ADMIN"
}
}
}
}

Store both tokens. Keep accessToken in process memory, refreshToken in secure storage (not in localStorage, not in a plain file).

Pass accessToken in the header of every request:

Окно терминала
curl -X POST https://api.izi.is/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-d '{"query": "query { me { id email } }"}'

In code — configure the HTTP client once:

const client = new GraphQLClient('https://api.izi.is/graphql', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});

accessToken lives 15 minutes. Refresh it proactively — don’t wait for TOKEN_EXPIRED during a critical request.

mutation RefreshToken($token: String!) {
refreshToken(token: $token) {
accessToken
refreshToken
}
}
{
"token": "eyJhbGciOiJSUzI1NiIs... (your refreshToken)"
}

After every refreshToken call, save both new tokens — the old refreshToken is immediately invalidated.

┌─────────────────────────────────┐
│ Your Service │
│ │
│ accessToken ──────────────────►│──► API requests
│ (TTL: 15 min) │
│ │
│ refreshToken ──────────────────►│──► refreshToken mutation
│ (TTL: 30 days) ◄──────────────│ → both tokens rotated
└─────────────────────────────────┘

Recommended strategy: refresh accessToken 2–3 minutes before expiry (after 12–13 minutes from issue time).

async function requestWithRetry(query, variables) {
try {
return await client.request(query, variables);
} catch (error) {
if (error.extensions?.code === 'TOKEN_EXPIRED') {
const { refreshToken: newRefresh, accessToken: newAccess } =
await refreshTokens(currentRefreshToken);
currentAccessToken = newAccess;
currentRefreshToken = newRefresh;
client.setHeader('Authorization', `Bearer ${newAccess}`);
return await client.request(query, variables);
}
throw error;
}
}
mutation Logout($refreshToken: String!) {
logout(refreshToken: $refreshToken) {
success
}
}

Both tokens (access and refresh) are invalidated immediately.

The token embeds the user’s role. IZI has one built-in staff role — Administrator — plus custom roles the organization owner creates.

RoleTypeAccess
OwnerOrg ownershipFull access to all organization clubs; not an assignable staff role
ADMIN (Administrator)Built-in staff roleAll operations within assigned clubs
Custom roles (e.g. Manager, Cashier)Created by the ownerExactly the permissions the owner selects

Custom roles are defined in IZI CRM: the owner names the role freely and selects a permission set (clubPermissions / orgPermissions). “Manager” and “Cashier” are common examples — but they are not preset tiers. The owner creates them with whatever name and permission scope fits the operation.

For server-side integrations, create a dedicated user with a custom role scoped to the minimum permissions required. Don’t use the owner’s personal account.

Frequently asked questions

How long does an accessToken last?

accessToken is valid for 15 minutes. refreshToken lasts 30 days. After the refreshToken expires, log in again via loginWithEmailPassword.

What to do if a token expires mid-request?

IZI API returns an error with code TOKEN_EXPIRED. Intercept it in middleware, refresh the token via refreshToken mutation, and retry the original request.

Can I create a token with limited access (service account)?

Yes. In IZI CRM, create a user with a custom role scoped to only the permissions your integration needs. Use this account for server-side integrations.

How do I revoke a token?

Call the logout mutation with the current refreshToken. Both tokens are immediately invalidated.