Skip to main content

Authentication

Olympus Cloud uses JWT (JSON Web Token) authentication exclusively. There are no API keys, no OAuth client credentials flow, and no service accounts — all API access is session-based through JWT tokens.

Authentication Methods

MethodEndpointUse Case
Email + PasswordPOST /v1/auth/loginStandard web/mobile login
Staff PINPOST /v1/auth/login/pinQuick POS terminal login
OAuth (Google, Microsoft)GET /v1/auth/oauth/:providerSocial login / SSO
SSO (SAML/OIDC)POST /v1/auth/sso/initEnterprise SSO
Token RefreshPOST /v1/auth/refreshExtend session

Email + Password Login

Request

curl -X POST https://dev.api.olympuscloud.ai/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "manager@demo-restaurant.com",
"password": "DevPassword123!",
"tenant_slug": "demo-restaurant"
}'

Fields:

  • email (required) — User's email address
  • password (required) — User's password
  • tenant_slug (optional) — Required if user belongs to multiple tenants
  • device_id, device_name (optional) — For device tracking

Success Response

{
"status": {
"type": "success",
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": "550e8400-e29b-41d4-a716-446655449120",
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"email": "manager@demo-restaurant.com",
"roles": ["manager"]
}
}
}

MFA Challenge Response

If the user has MFA enabled, you'll receive a challenge instead:

{
"status": {
"type": "mfa_required",
"challenge_id": "a1b2c3d4-...",
"challenge_code": "...",
"factors": [
{
"id": "f1a2b3c4-...",
"label": "Authenticator App",
"factor_type": "totp",
"enabled": true
}
]
}
}

Complete MFA with:

curl -X POST https://dev.api.olympuscloud.ai/v1/auth/mfa/verify \
-H "Content-Type: application/json" \
-d '{
"challenge_id": "a1b2c3d4-...",
"code": "123456"
}'

Token Refresh

Access tokens expire after 1 hour. Use the refresh token to get a new pair without re-authenticating:

curl -X POST https://dev.api.olympuscloud.ai/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "eyJhbGciOiJSUzI1NiIs..."}'

Returns the same LoginResponse structure with new tokens.

Automatic Refresh Pattern

import requests

class OlympusAPI:
def __init__(self, base_url, email, password):
self.base_url = base_url
self.email = email
self.password = password
self.access_token = None
self.refresh_token = None
self.login()

def login(self):
resp = requests.post(f"{self.base_url}/auth/login", json={
"email": self.email,
"password": self.password,
})
status = resp.json()["status"]
self.access_token = status["access_token"]
self.refresh_token = status["refresh_token"]

def request(self, method, path, **kwargs):
resp = requests.request(
method, f"{self.base_url}{path}",
headers={"Authorization": f"Bearer {self.access_token}"},
**kwargs,
)
if resp.status_code == 401:
self._refresh()
resp = requests.request(
method, f"{self.base_url}{path}",
headers={"Authorization": f"Bearer {self.access_token}"},
**kwargs,
)
return resp

def _refresh(self):
resp = requests.post(f"{self.base_url}/auth/refresh", json={
"refresh_token": self.refresh_token,
})
if resp.status_code == 200:
status = resp.json()["status"]
self.access_token = status["access_token"]
self.refresh_token = status["refresh_token"]
else:
self.login() # Re-authenticate if refresh fails

Staff PIN Login

For POS terminals and touchscreen devices. Staff authenticate with a username/email and numeric PIN instead of a password.

curl -X POST https://dev.api.olympuscloud.ai/v1/auth/login/pin \
-H "Content-Type: application/json" \
-d '{
"identifier": "mgr01",
"pin": "123456",
"tenant_slug": "demo-restaurant",
"location_id": "550e8400-e29b-41d4-a716-446655449110",
"device_id": "pos-terminal-01"
}'

Fields:

  • identifier (required) — Username or email (also accepts email field name)
  • pin (required) — 6-digit PIN (also accepts code field name)
  • tenant_slug (optional)
  • location_id (optional) — Associates session with a specific location
  • device_id, device_fingerprint (optional) — For device trust

Returns the same LoginResponse as email/password login.


SSO (Single Sign-On)

Discover Available Providers

curl "https://dev.api.olympuscloud.ai/v1/auth/sso/providers?tenant_slug=demo-restaurant"

Initiate SSO Flow

curl -X POST https://dev.api.olympuscloud.ai/v1/auth/sso/init \
-H "Content-Type: application/json" \
-d '{
"provider_id": "PROVIDER_UUID",
"shell": "restaurant_staff",
"redirect_uri": "https://app.olympuscloud.ai/auth/callback"
}'

Response includes an authorization_url — redirect the user there. After authenticating with the identity provider, the callback returns JWT tokens.

Supported providers: Google Workspace, Microsoft Entra ID, Okta, SAML 2.0.


Using Tokens

Include the access token in the Authorization header for all authenticated requests:

curl https://dev.api.olympuscloud.ai/v1/commerce/orders \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

JWT Payload Structure

The JWT contains these claims:

ClaimDescription
subUser ID (UUID)
tenant_idTenant ID (UUID)
emailUser email
rolesArray of role names
session_idSession ID (UUID)
expExpiration timestamp
iatIssued-at timestamp

Verifying Tokens

Public keys are available at the JWKS endpoint:

# OIDC-standard JWKS endpoint
curl https://dev.api.olympuscloud.ai/.well-known/jwks.json

# Also available at:
curl https://dev.api.olympuscloud.ai/v1/auth/jwks

Session Management

Get Current Session

curl https://dev.api.olympuscloud.ai/v1/auth/session \
-H "Authorization: Bearer $TOKEN"

Create Session

curl -X POST https://dev.api.olympuscloud.ai/v1/auth/session \
-H "Authorization: Bearer $TOKEN"

End Session (Logout)

curl -X DELETE https://dev.api.olympuscloud.ai/v1/auth/session \
-H "Authorization: Bearer $TOKEN"

Get Current User Profile

curl https://dev.api.olympuscloud.ai/v1/auth/me \
-H "Authorization: Bearer $TOKEN"
{
"id": "550e8400-e29b-41d4-a716-446655449120",
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"email": "manager@demo-restaurant.com",
"username": "mgr01",
"first_name": "Demo",
"last_name": "Manager",
"display_name": "Demo Manager",
"email_verified": true,
"roles": ["manager"],
"status": "active"
}

Security Best Practices

  1. Store tokens securely — Use httpOnly cookies for refresh tokens in web apps. Keep access tokens in memory only.
  2. Refresh proactively — Refresh before expiration to avoid interrupted requests.
  3. Use short-lived tokens — Access tokens expire in 1 hour by default.
  4. Revoke on logout — Always call POST /v1/auth/logout to invalidate the session server-side.
  5. Pin device context — Pass device_id and device_fingerprint for device trust scoring.

What's Next?