Skip to main content

Authentication patterns

API keys are the simplest path — embed or seed via fromKeychain(...) and move on. Third-party apps that want per-user consent use OAuth 2.1 with PKCE instead. The SDK doesn’t ship a built-in OAuth client — it’s an integration pattern — but the Keychain helpers handle token storage and rotation once you’ve exchanged for tokens.

OAuth 2.1 with ASWebAuthenticationSession

Four moving parts: ASWebAuthenticationSession for the authorize redirect, URLSession for the token exchange, the SDK’s Keychain helpers for persistence, and a catch on UnauthorizedError to trigger refresh. 1. Launch the authorize flow. Generate a PKCE verifier + challenge, build /auth/authorize, and let ASWebAuthenticationSession handle the redirect back.
2. Exchange the code for tokens via POST /auth/token with grant_type=authorization_code, the code, and the original code_verifier. The response carries access_token (marfa_at_...), refresh_token (marfa_rt_...), and expires_in. 3. Persist the access token via the SDK’s Keychain helper — it becomes the API key for subsequent calls. Store the refresh token separately (same service, different account).
On subsequent launches, rehydrate without the auth flow:
4. Refresh on expiry. Any SDK call can throw UnauthorizedError when the access token expires. Catch it, exchange the refresh token for a new pair, overwrite the Keychain entries, and retry:
Refresh tokens rotate on every exchange — the prior refresh token is invalidated. Reusing a rotated token returns 400 token_reuse_detected; the app must restart the authorize flow. Store the latest pair atomically.
ASWebAuthenticationSession requires a UI host — a UIWindow on iOS, NSWindow on macOS. Server-side Swift, background extensions, and command-line tools cannot run this flow; they must use an API key.
See Authentication → OAuth 2.1 for the full endpoint reference, scope grammar, consent-screen behavior, and refresh-token rotation rules.