Authentication
Panel session
Section titled “Panel session”-
POST /api/admin/v1/auth/loginwith email, password and, if two-step verification is enabled, the code:Finestra del terminale curl -i https://prenota.mio-lido.it/api/admin/v1/auth/login \-H 'Content-Type: application/json' \-c cookies.txt \-d '{"email":"owner@mio-lido.it","password":"…","totp_code":"123456"}'On success the server sets two cookies:
arenile_session:HttpOnly,Secure,SameSite=Lax, rotated at every sign-in;arenile_csrf: readable by the client, for the CSRF token.
If the TOTP code is missing the response is
401withtypetotp_required; a wrong code givesinvalid_totp. -
Requests that read send only the session cookie.
-
Requests that change data (
POST,PUT,PATCH,DELETE) must also send theX-CSRF-Tokenheader with the same value as thearenile_csrfcookie (double submit). Otherwise:403csrf_failed.Finestra del terminale CSRF=$(grep arenile_csrf cookies.txt | awk '{print $7}')curl https://prenota.mio-lido.it/api/admin/v1/auth/logout -X POST \-b cookies.txt -H "X-CSRF-Token: $CSRF" -
GET /api/admin/v1/auth/mereturns the user, their establishments, roles and permissions.
The session expires after a period of inactivity (7 days by default) and is renewed with use.
Sign-in limits
Section titled “Sign-in limits”30 attempts per 15 minutes per IP and 8 failed attempts per 15 minutes per account; beyond that, 429 rate_limited
with retry_after in seconds.
Two-step verification
Section titled “Two-step verification”POST /api/admin/v1/auth/totp/enroll returns the secret and the otpauth:// URL to show as a QR code;
POST /api/admin/v1/auth/totp/confirm with a valid code enables it. With ARENILE_REQUIRE_TOTP_FOR_OWNERS=true an
owner without TOTP gets totp_enrolment_required.
API keys
Section titled “API keys”API keys serve server-to-server integrations: they are bound to an establishment, have the permissions as scopes
(except users.manage) and an optional expiry:
Authorization: Bearer ar_live_<prefix>_<secret>With an API key no cookies or CSRF are needed. The owner creates, edits and revokes keys from the panel (see
API keys and webhooks); the full key is shown only once and Arenile keeps only
its fingerprint. A key can never manage users, keys or webhooks; bookings created with a key have the api
channel; every key is limited to 300 requests per minute (beyond that, 429 with Retry-After); revocation takes
effect from the next request.
Permissions
Section titled “Permissions”Each operation requires a permission, checked in the domain service (not just in the handler). The values are stable and are also the scopes of API keys.
| Permission | Meaning | Roles |
|---|---|---|
establishment.configure |
Configuration, prices, policies, public page, email | owner, manager |
users.manage |
Users, roles, API keys | owner |
payments.configure |
Payment providers and credentials | owner |
bookings.write |
Create and edit bookings | owner, manager, cashier |
cash.operate |
Payments and cash desk | owner, manager, cashier |
refunds.issue |
Refunds | owner, manager |
operations.run |
Check-in, releases, blocks | owner, manager, cashier, beach_staff |
bookings.read |
Map and bookings | everyone |
reports.read |
Reports and exports | owner, manager, viewer |
Without the permission: 403 forbidden. A resource of another establishment answers 404, without revealing that
it exists.
Public API
Section titled “Public API”The public API has no sign-in. A booking’s personal data can be read only with:
- the checkout session token (
X-Arenile-Checkoutheader), during the booking; - the magic link token (in the
/manage/{token}path), afterwards.

