Skip to content

Auth API

XetaSuite uses Laravel Sanctum in stateful mode (cookies) for SPA authentication.

GET /sanctum/csrf-cookie

Response: XSRF-TOKEN cookie set


POST /api/v1/auth/login

Headers:

Content-Type: application/json
Accept: application/json
X-XSRF-TOKEN: {token from cookie}

Body:

{
"email": "user@example.com",
"password": "password",
"remember": true
}

Response 200:

{
"two_factor": false
}

Response 422 (Validation):

{
"message": "The provided credentials are incorrect.",
"errors": {
"email": ["The provided credentials are incorrect."]
}
}

If two_factor: true in the login response:

POST /api/v1/auth/two-factor-challenge

Body:

{
"code": "123456"
}

Or with a recovery code:

{
"recovery_code": "abcd-efgh-ijkl"
}

POST /api/v1/auth/logout

Response 204: No Content


GET /api/v1/user

Response:

{
"data": {
"id": 1,
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe",
"email": "john@example.com",
"username": "jdoe",
"locale": "en",
"current_site_id": 1,
"roles": ["admin"],
"permissions": ["company.viewAny", "company.view", "..."],
"sites": [
{
"id": 1,
"name": "Headquarters",
"is_headquarters": true
}
]
}
}

PATCH /api/v1/user/site

Body:

{
"site_id": 2
}

Response: Updated user with new permissions for the selected site.


PATCH /api/v1/user/locale

Body:

{
"locale": "fr"
}
httpClient.ts
const httpClient = axios.create({
baseURL: import.meta.env.VITE_API_URL || '',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
withCredentials: true, // Required for Sanctum cookies
withXSRFToken: true, // Auto-include XSRF-TOKEN header
});
// AuthRepository.ts
export const AuthRepository = {
login: async (credentials: LoginCredentials): Promise<void> => {
await httpClient.get('/sanctum/csrf-cookie');
await httpClient.post('/api/v1/auth/login', credentials);
},
logout: async (): Promise<void> => {
await httpClient.get('/sanctum/csrf-cookie');
await httpClient.post('/api/v1/auth/logout');
},
};