Discover billers from Gmail
Connect a user's Gmail with a single-use PKCE transaction, then surface live discovery progress.
1. Create the transaction
Generate a high-entropy verifier on your server and retain it. Send only its base64url SHA-256 challenge. This endpoint requires your secret BillerAPI key.
Node
import { createHash, randomBytes } from 'node:crypto';
const codeVerifier = randomBytes(64).toString('base64url');
const codeChallenge = createHash('sha256')
.update(codeVerifier, 'ascii')
.digest('base64url');
const response = await fetch(
'https://sandbox.api.billerapi.com/v1/emails/gmail/oauth-sessions',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_id: 'user_123',
redirect_uri: 'https://yourapp.com/oauth/gmail',
code_challenge: codeChallenge,
code_challenge_method: 'S256',
}),
},
);
const { data } = await response.json();
// Redirect the user's browser to data.oauth_url.Warning
Never expose client credentials, the verifier, the returned consent URL, or the completion proof in logs. The removed
/v1/emails/gmail/oauth-url and one-phase /v1/emails/gmail/connect routes have no compatibility aliases.2. Receive the callback handoff
Google returns through BillerAPI's unchanged public callback. BillerAPI validates state and records authorization, then redirects to your registered URI with status, session_id, and completion_token in the URL fragment. The public callback does not exchange tokens.
3. Complete with PKCE
Node
const complete = await fetch(
`https://sandbox.api.billerapi.com/v1/emails/gmail/oauth-sessions/${sessionId}/complete`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_id: userId,
completion_token: completionToken,
code_verifier: codeVerifier,
}),
},
);
const { data } = await complete.json();
// 200: COMPLETED. 202: honor Retry-After and poll data.status_url.Note
REAUTHORIZE_REQUIRED is terminal for this transaction. Start a fresh Google authorization; do not retry the old provider code.4. Stream discovery
A completed receipt includes discovery_run_id. Use it with the discovery-run SSE API to render progress and ready-to-connect billers.
Browser
const events = new EventSource(
`https://sandbox.api.billerapi.com/v1/discovery-runs/${discoveryRunId}/stream`,
{ withCredentials: true },
);Was this page helpful?