Skip to content

OAuth

OAuth is the path for a third-party application that connects to a customer’s Infinite Audience account on their behalf — Zapier today. It’s not a self-service “register your own OAuth app” flow: the set of client applications is a fixed, platform-approved registry, each with its own allowed scopes and redirect URIs. If you’re integrating your own backend or scripts against your own account, use an API key instead — it’s simpler and doesn’t require a registered client.

Standard OAuth 2.0 authorization code grant with mandatory PKCE (S256) — this is RFC 9700’s recommendation, not optional here:

  1. Your app redirects the user to GET /v1/oauth/authorize with client_id, redirect_uri, response_type=code, scope, code_challenge, and code_challenge_method=S256.
  2. The user reviews and approves a consent screen showing exactly which scopes your app is requesting.
  3. We redirect back to your redirect_uri with a short-lived authorization code.
  4. Your backend exchanges that code — plus the original code_verifier — at POST /v1/oauth/token for an access token and a refresh token.
  5. Use the access token as a normal bearer token. When it expires, use the refresh token to get a new one without involving the user again.
Parameter Required Notes
client_id yes Must resolve to a registered client, or this 400s directly (there’s no redirect target to trust yet).
redirect_uri yes Must be on that client’s registered allow-list.
response_type yes Must be code — nothing else is supported.
scope no Space-separated. Anything not on the client’s allowed-scope list is rejected.
code_challenge yes RFC 7636 PKCE challenge.
code_challenge_method yes Must be S256plain is rejected.
state recommended Echoed back on both success and error redirects.

Every failure after client_id/redirect_uri validation redirects back to your app with error and error_description query params (RFC 6749 §4.1.2.1) rather than showing an error page — validate client_id and redirect_uri yourself before sending users here if you want to fail fast.

Two grant types:

Terminal window
# Exchanging an authorization code
curl -X POST https://api.infiniteaudience.ai/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=$AUTH_CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code_verifier=$CODE_VERIFIER"
# Refreshing an expired access token
curl -X POST https://api.infiniteaudience.ai/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=$REFRESH_TOKEN" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"
{
"access_token": "cfo_eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "...",
"scope": "discovery purchase"
}

Refresh tokens last 90 days. An authorization code is valid for 60 seconds and single- use — replaying it revokes the whole grant as a security response, not just a “try again.”

POST /v1/oauth/revoke (client-authenticated, RFC 7009) revokes a specific token. A user can also revoke your app’s entire grant from their own account settings at any time — build your integration to handle a sudden 401 on a previously-working refresh token gracefully.