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

# Authentication

> JWT access and refresh tokens delivered as cookies.

Authentication uses a JWT access token and a refresh token, both delivered as **cookies** by the [login](https://docs.tunimobile.com/api/auth/login.md) call:

| Cookie | Content | Lifetime | Flags |
| - | - | - | - |
| `BEARER` | JWT access token | 1 hour | `HttpOnly`, `Secure`, `SameSite=None` |
| `refresh_token` | Refresh token (single use) | 30 days, extended each time it is used | `HttpOnly`, `Secure`, `SameSite=None` |

The tokens are **not** in the response body.

## Sending the tokens

**Cookie store (recommended)**

Store the cookies from every response and send them back on every request. On Android with OkHttp, use a persistent `CookieJar` (for example `PersistentCookieJar`).

The refresh call needs the `refresh_token` cookie, so a cookie store is the simplest option.

```bash theme={null}
curl -c cookies.txt -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"action":"get_credit"}' \
  https://apitest.tunimobile.com/v1/user/do_action
```

**Authorization header**

For the access token only: read the JWT from the `Set-Cookie: BEARER=...` header of the login response and send it as a bearer token.

```bash theme={null}
curl -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{"action":"get_credit"}' \
  https://apitest.tunimobile.com/v1/user/do_action
```

## Expired tokens

When the access token expires, any call that carries it returns:

```json 401 theme={null}
{ "code": 401, "message": "Expired JWT Token" }
```

**1. Refresh**

Call [Refresh the session](https://docs.tunimobile.com/api/auth/refresh.md).

**2. Retry once**

Retry the original request once.

**3. Fall back to login**

If the refresh also fails, send the user back to the login screen.

> [!WARNING]
>
> This also applies to the voucher and session calls: a valid `api-key` does not help if the request carries an expired token. Either refresh first, or don't send the cookie on calls that only need the API key.

> [!TIP]
>
> If several requests fail with `401` at the same time, refresh **once** and retry them all after it completes. The refresh token is single use, so two parallel refresh calls would make the second one fail.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.