API Keys
Create a key
Section titled “Create a key”In the app, go to Account → Integrations and create a key. You’ll be asked for a name and
the scopes it should carry (defaults to discovery if you don’t pick any — see
Scopes).
Only an org owner or admin can create or revoke keys — the account scope this requires
is role-gated server-side, not just hidden in the UI. If you’re on a team without that role,
ask your org owner.
A key looks like:
cf_live_QSoVINQ4nCJQryOAQcEMBAX8hpEnKAPJThere is a single cf_live_ prefix for all environments — dev and prod keys are
indistinguishable by format, so keep track of which one you’re pasting where.
Exchange it for an access token
Section titled “Exchange it for an access token”A cf_live_ key is not a bearer token. Every request must first exchange it:
curl -X POST https://api.infiniteaudience.ai/v1/auth/token \ -H "Content-Type: application/json" \ -d '{"api_key": "cf_live_QSoVINQ4nCJQryOAQcEMBAX8hpEnKAPJ"}'{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600}Use access_token as a bearer token on every subsequent call:
curl https://api.infiniteaudience.ai/v1/catalog/fields \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."There is no refresh token — re-exchange instead
Section titled “There is no refresh token — re-exchange instead”expires_in is always 3600 and the response carries nothing to refresh. When a token is
close to expiring (or a request 401s), call POST /v1/auth/token again with the same key. A
minimal client that owns this for you:
class InfiniteAudienceAuth { private token: string | null = null; private expiresAt = 0;
constructor(private apiKey: string, private baseUrl = 'https://api.infiniteaudience.ai') {}
async getToken(): Promise<string> { // Refresh 60s early so a request in flight doesn't land right as it expires. if (this.token && Date.now() < this.expiresAt - 60_000) return this.token;
const res = await fetch(`${this.baseUrl}/v1/auth/token`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ api_key: this.apiKey }), }); if (!res.ok) throw new Error(`Token exchange failed: ${res.status}`); const body = await res.json(); this.token = body.access_token; this.expiresAt = Date.now() + body.expires_in * 1000; return this.token!; }}Revoke a key
Section titled “Revoke a key”Delete it from Account → Integrations, or DELETE /v1/settings/api-keys/{id}. Revoked
keys still appear in GET /v1/settings/api-keys (with active: false) so you can see your
history — they aren’t deleted, just deactivated. Any access token already issued from a
revoked key keeps working until it naturally expires (up to 1 hour) — revoking doesn’t
invalidate tokens already in flight.