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
| Method | Endpoint | Use Case |
|---|---|---|
| Email + Password | POST /v1/auth/login | Standard web/mobile login |
| Staff PIN | POST /v1/auth/login/pin | Quick POS terminal login |
| OAuth (Google, Microsoft) | GET /v1/auth/oauth/:provider | Social login / SSO |
| SSO (SAML/OIDC) | POST /v1/auth/sso/init | Enterprise SSO |
| Token Refresh | POST /v1/auth/refresh | Extend 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 addresspassword(required) — User's passwordtenant_slug(optional) — Required if user belongs to multiple tenantsdevice_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 acceptsemailfield name)pin(required) — 6-digit PIN (also acceptscodefield name)tenant_slug(optional)location_id(optional) — Associates session with a specific locationdevice_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:
| Claim | Description |
|---|---|
sub | User ID (UUID) |
tenant_id | Tenant ID (UUID) |
email | User email |
roles | Array of role names |
session_id | Session ID (UUID) |
exp | Expiration timestamp |
iat | Issued-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
- Store tokens securely — Use
httpOnlycookies for refresh tokens in web apps. Keep access tokens in memory only. - Refresh proactively — Refresh before expiration to avoid interrupted requests.
- Use short-lived tokens — Access tokens expire in 1 hour by default.
- Revoke on logout — Always call
POST /v1/auth/logoutto invalidate the session server-side. - Pin device context — Pass
device_idanddevice_fingerprintfor device trust scoring.
What's Next?
- First Request — Request format, pagination, and error handling
- REST API Examples — Full auth examples in Python, JavaScript, and Go
- Security Best Practices — In-depth security guide
Related Documentation
- Quickstart — End-to-end getting started
- First Request — Making API requests
- API Reference — Full API documentation