Authentication
YumKiosk has two distinct APIs with two different authentication models. Understanding which you're using is critical — they don't overlap and you can't mix credentials across them. This page covers both, plus how we handle CSRF, session management, and future API key support for third-party integrations.
The two APIs
- Public kiosk API (
api.yumkiosk.com) — used by tablet kiosks. Authenticated by a per-device token issued at pair time. No human user behind it. - Agent API (
agent.yumkiosk.com/api) — used by the agent dashboard. Authenticated by a standard Laravel web session after a human logs in with email + password.
There is also a future Owner API (agent.yumkiosk.com/api/owner/*) authenticated by OAuth-style API keys, intended for third-party integrations like POS systems syncing orders. As of this writing the Owner API has only a handful of endpoints (kiosk pairing code regeneration); the full public version is on the roadmap.
Public kiosk API auth
Every request must include:
X-Device-Id: <uuid-v4>
X-Device-Token: <long-lived-token>
The token is returned from POST /api/public/kiosks/pair when the tablet first pairs. It's stored in localStorage on the tablet and never expires — it's revoked only when the kiosk is unpaired by the owner. If the token is missing, invalid, or revoked, the server returns 401 Unauthorized with the error code DEVICE_TOKEN_INVALID.
Because kiosks are physical devices and not human users, we don't do CSRF on this API. Cross-origin requests are allowed (the tablet is running a PWA at kiosk.yumkiosk.com and calling api.yumkiosk.com), and CORS is configured to allow this origin.
Agent API auth
Agents log in with POST /login:
POST /login
Content-Type: application/json
X-XSRF-TOKEN: <from XSRF-TOKEN cookie>
{
"email": "maria@example.com",
"password": "super-secure-pw",
"remember": true
}
On success, the server sets a laravel_session cookie (HttpOnly, Secure, SameSite=Lax) and an XSRF-TOKEN cookie (readable by JS, used for CSRF). The dashboard then includes both cookies on every subsequent request, and the CSRF token in the X-XSRF-TOKEN header for all mutating requests.
Session cookies are valid for 30 days of inactivity. Any request resets the clock. If you're inactive for more than 30 days, you're logged out and have to re-enter credentials.
To log out: POST /logout. This invalidates the session server-side and clears the cookies.
CSRF
All mutating requests (POST, PUT, PATCH, DELETE) on the agent API must include the X-XSRF-TOKEN header. Laravel's default CSRF middleware reads the value from the header and compares it to the value in the session cookie. If they don't match, the server returns 419 Page Expired.
The dashboard handles this automatically — it reads the XSRF-TOKEN cookie on page load and attaches the header to every fetch call. If you're building your own client, you'll need to do the same.
2FA
If an agent has opted into 2FA, the POST /login response includes:
{
"status": "2fa_required",
"challenge_id": "ch_abc123"
}
Instead of a session cookie. The client then POSTs the TOTP code:
POST /login/2fa
Content-Type: application/json
{
"challenge_id": "ch_abc123",
"code": "847291"
}
On success, the normal session cookies are issued. The challenge is valid for 5 minutes.
Rate limits
See Rate limits for specifics. Short version: authenticated endpoints have generous per-user limits, and /login has aggressive per-IP limits to prevent brute force.
Future: API keys for third-party integrations
We're building out API key authentication for the Owner API so third-party tools like POS systems can integrate without going through the full OAuth dance. Keys will be created under Settings → Developers → API keys and will have scoped permissions (read-only, read-write, kiosk-only, etc.). Target ship: Q3 2026. Watch the changelog for the announcement.