A walkthrough of the exact billing integration that turned a lead-qualification agent into a $180k/month revenue line — with code, timing, and dashboard proof.
Most AI agent billing fails at the moment it matters most — when the outcome finally lands.
Without automated metering, every billable outcome requires a manual invoice. At scale, this becomes a full-time job nobody budgeted for.
Coarse monthly aggregates don't tell you which agent actions drove revenue. You can't optimize what you can't see.
Promising "pay on success" means you do the work first and invoice later. Customers forget, dispute, or ghost. There's no automated way to collect.
ChainOps runs a B2B sales pipeline. Their AI agent accepts a cold prospect, enriches the company data, scores the lead, and fires a result when the lead reaches qualified status. Here's how the billing integrates at each step.
The agent fires meter events at four points: task start, enrichment complete, scoring complete, and outcome resolution. Rev handles the deferred billing so the base fee charges immediately and the outcome bonus fires only when the lead qualifies.
Lead arrives → task registered with outcome: 'pending'
LLM runs → tokens metered, first price computed
Lead scores qualified → outcome resolved with outcome: 'success'
Dashboard updates → outcome bonus added to total
When the lead arrives, fire POST /v1/meter with outcome: 'pending'. This opens a deferred billing record. The base fee charges immediately; the outcome bonus waits.
// Step 1: Register the task when lead arrives async function onLeadReceived(lead) { const taskId = crypto.randomUUID(); const res = await fetch('https://rev.polsia.app/v1/meter', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', 'Idempotency-Key': taskId, }, body: JSON.stringify({ agent_id: 'lead-qualifier-v3', action: 'lead.received', outcome: 'pending', // ← deferred: bonus not charged yet metadata: { lead_id: lead.id, source: lead.source, task_id: taskId, // store this for later resolve }, }), }); const { price_charged, outcome_id } = await res.json(); console.log(`Base fee charged: $${price_charged}`); return outcome_id; // save this to resolve later }
After the LLM call, fire another meter event capturing the tokens consumed. Rev computes the token-rate portion of the price and stores the full record.
.usage.prompt_tokens and .usage.completion_tokens. Don't meter before the call or you'll record zero tokens.
// Step 2: Meter after LLM call — captures tokens and outcome async function enrichLead(lead) { // Your LLM call const llmResponse = await openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: `Enrich and score: ${lead.company}` }], }); // Fire meter event — Rev computes price from your pricing config const meterRes = await fetch('https://rev.polsia.app/v1/meter', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ agent_id: 'lead-qualifier-v3', action: 'lead.enriched', tokens_input: llmResponse.usage.prompt_tokens, tokens_output: llmResponse.usage.completion_tokens, outcome: 'success', metadata: { lead_id: lead.id, enriched_at: new Date().toISOString(), model: 'gpt-4o', }, }), }); const { price_charged } = await meterRes.json(); console.log(`Token rate charged: $${price_charged}`); }
When the lead scores above the qualification threshold, resolve the pending outcome with outcome: 'success'. The outcome bonus fires at this point — not before.
pending until resolution. If the lead disqualifies, resolve with outcome: 'failure' — no bonus fires, and the pending bonus is written off.
// Step 3: Resolve outcome when lead qualifies async function resolveLeadOutcome(outcomeId, lead, score) { const resolvedOutcome = score >= 70 ? 'success' : 'failure'; const res = await fetch( `https://rev.polsia.app/v1/outcomes/${outcomeId}/resolve`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ outcome: resolvedOutcome, metadata: { lead_id: lead.id, score: score, resolved_at: new Date().toISOString(), }, }), } ); const { outcome_bonus, total_charged } = await res.json(); if (resolvedOutcome === 'success') { console.log(`Outcome bonus: $${outcome_bonus} — lead qualified!`); } }
Open the Rev dashboard to see every meter call, outcome resolution, and revenue total in real time. Here's what the ChainOps dashboard looks like after a month of running.
| Agent | Action | Outcome | Charged |
|---|---|---|---|
| lead-qualifier-v3 | lead.received | pending | $0.20 |
| lead-qualifier-v3 | lead.enriched | success | $0.14 |
| lead-qualifier-v3 | lead.resolved | success | $0.06 + $0.60 bonus |
Get your API key, instrument one agent, and have a billing dashboard running before end of day. No credit card required.