Calling LuxID reliably
Why this page
LuxID is a dependency in your authentication path. This page collects the operational practices - timeouts, retries, idempotency, caching and outage behaviour - that keep your integration resilient when the network or LuxID is having a bad day. It is written for the engineer who owns the integration in production.
Timeouts
Set explicit timeouts on every call to LuxID; never rely on a client library default of "no timeout".
| Call | Suggested connect / read timeout | Notes |
|---|---|---|
GET /mga/sps/oauth/oauth20/authorize | n/a (browser redirect) | This is a user-agent redirect, not a server-to-server call. |
POST /mga/sps/oauth/oauth20/token (code exchange, refresh) | 3 s / 10 s | On the critical sign-in path - fail fast and surface a retry to the user rather than hanging. |
GET /mga/sps/oauth/oauth20/userinfo | 3 s / 10 s | Cache the result for the life of your session rather than calling on every request. |
GET /mga/sps/oauth/oauth20/jwks/OIDC-LUXID | 3 s / 5 s | Called rarely (cached); a short timeout is fine. |
A read timeout shorter than your overall request budget lets you return a clean error to the user instead of holding a worker thread open.
Retries and backoff
Retry transient failures only, with exponential backoff and jitter. Do not retry deterministic client errors (invalid_grant, invalid_client, invalid_request) - they will fail again.
For the same reason, it is good practice to wrap your calls to LuxID in a circuit breaker. When LuxID becomes unreachable or starts returning errors, the breaker trips so your application stops hammering the endpoint, fails fast for a short cool-off period, then sends a probe request to detect recovery before resuming normal traffic. This protects both your application (threads and connection pools are not exhausted waiting on a struggling dependency) and LuxID (no retry storm during an incident).
| Condition | Retry? | Guidance |
|---|---|---|
| Connection timeout / connection refused / DNS failure | Yes | Exponential backoff (e.g. 1s, 2s, 4s) with jitter, small cap (3-4 attempts). |
HTTP 503 / temporarily_unavailable | Yes | Honour Retry-After if present; otherwise back off. |
HTTP 5xx / OAuth server_error | Yes | Back off; if it persists, contact LuxID support. |
HTTP 429 | Yes | Honour Retry-After; reduce request rate. |
OAuth invalid_grant, invalid_client, invalid_request | No | Fix the request or re-initiate an interactive login; retrying will not help. |
Rate limits are not published, and are not communicated alongside your credentials, because they may be adjusted dynamically. Treat HTTP 429 as the signal and handle it with backoff (see below) rather than coding to a fixed number. If you run a marketing campaign or launch likely to spike authentication volume, flag it to LuxID in advance (see SLA and support).
Idempotency
- Authorisation code exchange is single-use. A given
codecan be redeemed exactly once. If aPOST /mga/sps/oauth/oauth20/tokentimes out, do not blindly replay the same code - the original request may have succeeded server-side, and a replay returnsinvalid_grant. Treat a timed-out code exchange as a failed sign-in and start a fresh authorisation request. - Refresh-token rotation is on for most Partner configurations - confirm your Application's setting. Every refresh exchange returns a new refresh token and immediately revokes the previous one. Persist the new token from each response and discard the old one.
- Serialise concurrent refreshes. If two workers refresh the same token in parallel, one succeeds and the other gets
invalid_grant, forcing an interactive login. Use a lock (or a single-flight pattern) so only one refresh is in flight per session. See Session management.
JWKS caching and key rotation
- Fetch the JWKS once and cache it; do not fetch on every token validation. Respect the
Cache-Controlheaders on the JWKS response. - LuxID rotates signing keys periodically. If you receive an ID token with a
kidyou do not recognise, fetch the JWKS once to pick up the new key, then re-validate. If thekidis still absent, reject the token. - Never hardcode a key; always select by
kid. See Key management.
Behaviour during a LuxID outage
Authentication should fail closed: if LuxID is unreachable, do not grant access on the assumption that the user is who they claim.
Practical guidance:
- Already-authenticated users can keep using your application for the life of your application session - your session does not require LuxID to be reachable on every request (that is the point of issuing your own session after sign-in). Size your session lifetime with this in mind.
- New sign-ins and token refreshes will fail while LuxID is down. Surface a clear, branded "sign-in is temporarily unavailable, please try again shortly" message rather than a stack trace.
- Rule out your own side first - work through the diagnostic decision tree to tell whether the problem is yours or LuxID's before you open a ticket. See Diagnose a failing request.
- Do not hammer a failing endpoint - your backoff (above) protects both sides and avoids compounding an incident.
HTTP client hygiene
- Reuse connections (keep-alive / a pooled HTTP client) rather than opening a new TLS connection per call.
- Validate TLS certificates - never disable verification to "make it work".
- Log the LuxID Global Transaction ID from the response headers on every call; it is the identifier your own code can capture automatically and quote to LuxID to trace a request. If a request is blocked at LuxID's edge, the WAF page also returns a Support ID - capture that too when present. The two are distinct: see the identifiers reference and Diagnose a failing request.
Related pages
- Session management - aligning your session with LuxID's, refresh patterns.
- Key management - JWKS, signing keys and rotation.
- Endpoints reference - the URLs you are calling.
- OAuth and OIDC error codes - which errors are retryable.
- Diagnose a failing request - decision tree for integration errors.