Authentication & Access
Authentication & Access
OAuth 2.0 client credentials, credential-bound tenancy, and the auth failures you can hit.
The WestIQ Platform API uses the OAuth 2.0 client credentials grant for
server-to-server access. Each approved partner receives a client_id and
client_secret during onboarding, together with the token endpoint URL for
their integration.
Treat your client_secret like a password. Store it in a secrets manager,
never in source control, and rotate it if you suspect exposure.
1. Get a token
Exchange your client credentials for a short-lived bearer access token at your token endpoint (a Cognito hosted domain; the exact URL is in your onboarding pack):
Send it on every request as Authorization: Bearer <token>, and cache it
until it expires rather than requesting one per call.
Only access tokens are accepted. Sending an ID token — or any token whose
token_use is not access — is rejected with 401 auth.invalid_token.
2. Your credential IS your airline
Every partner credential is bound to its airline on the WestIQ side: the
token’s client_id is resolved through a server-side mapping to your
airline_id. You never send an airline identifier — not as a header, not as
a body field, not as a token claim. There is nothing to configure and nothing
to get wrong.
This is a deliberate isolation property, not a convenience:
- A request can only ever act as the airline its credential is bound to. Tenancy cannot be forged, because the request carries no tenancy input.
- A credential with no airline mapping is rejected with
403 auth.unknown_client— never resolved to a default tenant. - Your searches see your airline’s catalog namespace plus the shared
globalnamespace, and nothing else.
You can observe the resolution in every search response:
parsed.filters.airlineId is the airline your credential resolved to.
3. One scope: westiq/search
Every /v1 endpoint — search and events alike — requires the
westiq/search scope on the access token. Request it in the token call (as
in the example above). A token without it is rejected with
403 auth.insufficient_scope.
4. Auth failures you will see
All auth failures return the standard error envelope:
Unmatched routes also return 401, by design (the API denies by default). If a request 401s unexpectedly, check the path before debugging your token.
Rate limits
The platform edge applies a per-IP rate limit of 2000 requests per 5-minute
window. Requests over the limit are blocked at the edge with a plain
403 — without the API’s error envelope — and the block clears on its own
once your request rate drops. If you see bare 403s under load, back off and
retry with jitter.