REX / Revenue Execution Agent

Documentation

REX is a revenue execution platform. It connects to the systems you already use, works out which customers are actually at risk and why, decides what to do within rules you set, carries out the parts it's allowed to, and shows you whether it worked.

Overview

REX isn't a CRM, a payment dashboard, or a support chatbot, and it isn't tied to any one vendor. Think of it as a layer that sits on top of the payment, support, CRM, analytics, and communication tools you already run. You keep your own systems; REX works with them.

Most failed-payment flows stop at "payment failed, please update your card." REX treats that as the start of an investigation instead of the end of one. It looks at who the customer is, how they've been using the product, and what's happened with support before, then decides whether the situation is worth acting on, and only calls a case resolved once it's confirmed the action actually worked.

How REX decides

This guide is for teams integrating REX. It explains what data REX reads, how it decides which customers need attention, what it will and won't do on its own, and what every number on the dashboard means. Nothing here is a black box: every score REX shows can be traced back to the signals below, and every action to the rule that allowed it.

What REX reads

REX works with the systems you already have. The more it can see, the better it judges. What it can't see, it tells you: each customer page lists anything a score was calculated without.

SourceWhat REX readsWhat it's used for
Stripe (required)Customers (name, email, phone, preferred language, country), subscriptions (plan, monthly amount), invoices (failed attempts, the bank's decline code, amount), the card on file (last four digits, expiry)Spotting failed payments, knowing what each customer is worth, retrying payments, making payment links, reminding customers before a card expires
Support tool (optional)Ticket count and recent ticket subjectsMore tickets, and tickets about money, raise risk
Product usage (optional)Active days in the last 30, sent to POST /v1/usage (daily or weekly)Falling usage raises risk and triggers an early check-in; steady use marks a customer worth saving
CRM (optional)Account owner and tierContext for your team on each case

When you connect Stripe, REX imports every customer and subscription straight away, not just the ones whose payment has already failed. Payments that are already failing are picked up at import.

Sending REX your data

Stripe needs no code. Everything else is one authenticated POST with your workspace's API key (Authorization: Bearer rex_…).

WhatHowWhat REX does with it
Stripe eventsAutomatic. REX receives Stripe's webhook when it has a public address, and otherwise reads Stripe's event logFailed and paid invoices start and close cases. Card details feed expiry reminders
Product usagePOST /api/v1/usage with customer_id and active_days_30, daily or weeklyCompares each customer with their own normal and checks in when usage slips
Other signalsPOST /api/v1/events with event, customer_id, occurred_at and any detailsFor example, cancellation.page_viewed when a customer opens your cancellation page

customer_id is your ID for the customer, the same one Stripe holds (cus_…). Sending the same external_event_id twice is safe: REX handles each event once.

How REX reaches customers: phone calls and SMS go through Twilio, and emails through Resend, from REX's own accounts. Every attempt is recorded with its real result.

Three questions, answered separately

For every customer, REX asks three separate questions:

  1. Risk: how likely are we to lose them?
  2. Priority: how much does acting now matter?
  3. Contact: may REX reach out right now?

They're kept apart on purpose. A loyal, engaged customer isn't more likely to leave; they're more worth keeping. And a high-risk customer who asked not to be called stays high-risk, but REX doesn't call them.

Risk: how likely are we to lose them?

Risk is a score from 0 to 100. It's the sum of the warning signs below, capped at 100. Each sign shows on the customer page with its points and where it came from.

SignalPointsSourceWhen it counts
A payment failed+40StripeAny failed subscription payment
The card can't be charged again+25StripeStolen, lost, expired, "do not honor" or "pick up card": retrying won't help
Fraud or a dispute+25StripeFlagged by the bank. These payments are never retried
Looks temporary0StripeInsufficient funds and similar: a retry may well work
Opened the cancellation page+35Your appRight now
Opened the cancellation page recently+25Your appEarlier, with another signal now
Using the product less than before+20Product usageUsage is falling compared to the customer's own normal
Usage has slipped sharply+25Product usageThe latest reading is under 60% of the customer's usual (see below)
Barely using the product+10Product usageFewer than 5 active days in the last 30
Several support tickets+15Support3 or more recent tickets
Tickets about money+10SupportSubjects mentioning billing, invoices, charges, refunds, pricing, cancelling or downgrading
Warning signs in several places+5 per placeAllSigns from two or more of payments, intent, product and support at once. One problem seen in several systems is worse than any one sign alone

Levels: 65 and above is high, 35–64 is medium, below 35 is low. Your rules can treat levels differently. For example, you can let REX call high-risk customers automatically and ask for approval on the rest.

Priority: how much does acting now matter?

Priority puts customers in order. It's calculated as:

Priority = risk × a year of the customer's revenue × urgency

A customer paying ₹4,999 a month at 80% risk, in a normal situation, has a priority of 0.8 × ₹59,988 × 1 = ₹47,990. The command center sorts every queue by priority, and each customer page shows this sum.

Urgency reflects the situation itself:

SituationUrgencyWhy
The card needs replacing×1.25Waiting won't fix it
They're on the cancellation page×1.2They're deciding right now
Normal×1
They promised to pay on a date×0.5Give them the chance to keep their word
Already recovered×0Nothing left to do

Value tiers are relative to your own customers, not fixed amounts, so they mean the same thing whether your plans cost $49 or ₹20,000. The top 20% of your paying customers by monthly revenue are high value, the next 40% mid, and the rest low. The tier decides whether a customer is worth a phone call at the end of the escalation ladder: low-value accounts are handed to your team instead.

Contact: may REX reach out right now?

Before any call, REX checks a gate. The gate isn't a score: a single failed check stops the call.

CheckIf it fails
A phone number is on fileNo call: the attempt is recorded with the reason, and REX carries on with the rest of the recipe (for a failed payment, the retry)
The customer hasn't asked not to be calledBlocked: REX remembers "don't call me again" for good
Nobody on your team has claimed the customerBlocked: when someone clicks I'm handling this, REX stays out until they release it
REX hasn't called them within the rest period (default 3 days)On hold: the call waits for approval
It's within your calling hours and daysOn hold: the call waits for approval
The workspace is live, not in shadow modeOn hold: REX records what it would have done

When someone on your team clicks Let REX handle it on a customer, that's a person deciding. REX calls even within the rest period. Do-not-call, "I'm handling this" and calling hours still apply.

After a failed payment: the escalation ladder

REX doesn't phone a customer the minute a payment fails. That feels pushy, and many failures fix themselves. It starts with the quietest thing that might work and escalates only while the payment is still unpaid.

A temporary decline (such as insufficient funds):

WhenWhat REX does
First daysNothing: Stripe's own automatic retries go first
Day 2Emails the customer a payment link
Day 4Texts the payment link
Day 6Calls, if still unpaid. For low-value accounts, hands the case to your team instead

A card that can't be charged again (stolen, lost or expired): retrying is pointless, so:

WhenWhat REX does
Straight awayEmails and texts a link to pay with a new card
Day 1Calls, if still unpaid. For low-value accounts, hands the case to your team instead
  • It stops the moment they pay. Every remaining step is cancelled.
  • It stops if the case moves on for any other reason, for example when someone approves a different action.
  • Pace: standard uses the timings above, gentle waits 1.5× as long, fast waits half as long.
  • On by default for every new workspace. You can turn it off, or change the pace, in Setup → Set the rules.
  • When it's skipped: in shadow mode, when a person clicks Let REX handle it (then REX calls straight away), and for fraud or a dispute, which always go straight to a person.

After a promise to pay

Customers often agree on a call to pay later: "I'll pay on Friday", or "send me the link in three days". REX holds the account until that day and doesn't charge the card early. It doesn't forget the promise either:

WhenWhat REX does
The due date, 10 am your timeOne reminder with the payment link, by your delivery channels. Skipped if the link they asked for is already going out that day
The day after, 10 amAsks your payment system whether it was paid
  • Paid: the case is recovered, for the amount actually paid. REX checks your payment system directly, so a missed webhook can't leave a paying customer marked unpaid.
  • Not paid: the case is marked promise not kept and moves to Needs a human. The offer log records the hold as not kept, so your team can see it before granting another.
  • Paid early: the moment the payment arrives, the reminder and the check are cancelled.
  • If your payment system can't be reached, REX tries again in six hours, up to three times, rather than calling a promise broken over a network error.

These follow-ups run on the calendar: a date agreed on a call is a real date.

Before anything fails: card-expiry reminders

Once a day, REX looks for cards on file that expire by the end of next month. It sends each customer one friendly reminder by email or SMS to update their card before the payment fails. A customer gets this reminder at most once every 25 days, and it's never a phone call.

Before anything fails: usage slipping

A customer rarely cancels out of the blue. Usage usually drops first. If you send REX a usage reading for each customer (active days in the last 30), it compares each reading with that customer's own normal, not with everyone else's:

  • The customer's normal is the median of their earlier readings. REX keeps the last 12.
  • Slipping means the latest reading is under 60% of that normal. It needs at least 4 readings, and a normal of at least 8 active days, so a light user who has always been light is never flagged.
  • What REX does: once a day it opens a case and sends one short, helpful email offering a person to help. It's never a call, never a discount, and never "we noticed you're leaving".
  • How often: at most once every 3 weeks per customer. A customer who already has an open case isn't nudged.
  • Outcome: the case closes as nudged. If the customer later fails a payment, their risk already carries the usage signal.
POST /v1/usage
{ "customer_id": "cus_123", "active_days_30": 7 }

What REX may offer on a call

What REX may agree to is set by your rules. Everything it agrees is written to the offer log, so the same customer can't be granted the same concession month after month without your team seeing it.

OfferLimit
Hold the account until a dateUp to your longest payment hold (default 7 days). A customer who asks for longer is offered the latest date allowed
Send a payment linkNow, or on the day the customer asks for ("send it in three days")
Retry the cardNow, or at a time the customer picks
A pause30 days, instead of cancelling. Automatic
A cheaper planAutomatic if you allow discounts, otherwise your team approves each one
A refundAutomatic up to your limit (default 1,000). Above it, your team approves

Offers are real actions, not promises

When a customer agrees to an offer on a call, REX carries it out in your payment system straight after the call, through the same policy check as any other action:

  • Pause: Stripe stops collecting until the resume date (pause_collection), and the failed invoice is voided, so the customer isn't charged while paused. REX doesn't retry the card.
  • Cheaper plan: REX moves the subscription to the next plan down, meaning the most expensive active price below the current one in the same currency and billing interval. The change applies from the next bill, with no proration. If there's no cheaper plan, REX applies a coupon instead: 20% off for 3 months.
  • Result: either way, the case closes as retained, and the customer page shows exactly what changed (for example, "Moved from Growth to Pro").

If your rules need approval for a cheaper plan, the case stops at Needs a human until someone approves it.

Offer limits

A concession works once. Given every month, it's a discount people learn to ask for. So:

  • Once per 90 days: a customer can accept each kind of pause or price cut at most once in 90 days.
  • On the call: REX doesn't offer the same concession again. A customer asking for a second pause, or complaining about price again after a plan change, is handed to your team.
  • In the gate: if an offer still reaches your payment system, it's blocked by the offer_limit rule and recorded like any other blocked action.

A payment link is a page in your payment system (for Stripe, the hosted invoice page), where the customer can pay, with a new card if needed.

  • Delivery: REX sends the link by SMS, email or both, as you choose.
  • Timing: it goes straight after the call, or on the day the customer asked for.
  • What's recorded: each channel's actual result: sent, failed (and why), or not sent (for example, no email on file). The dashboard never says a link was sent when it wasn't.

Shadow mode

Every new workspace starts in shadow mode. REX works every failed payment through (who to call, what to offer, what to retry) and records each decision as "would have", without calling, texting or charging anyone. Review a few days of shadow decisions in the command center and the report. When you'd have made the same calls, switch REX to live.

Your rules become REX's policy

The choices in Setup → Set the rules generate the policy REX runs under. Nothing is left to judgment outside it:

  • Always a person: fraud and chargebacks, whatever else you choose.
  • Never automatic: anything your rules don't cover waits for a person.
  • Always on record: every decision is stored with the rule that made it and why, and every action with its result.

The numbers on your dashboard

MetricWhat it means
RecoveredMoney actually collected on rescued cases in the period: the failed payment that was then paid
Kept (retained)Customers who took a pause or a cheaper plan instead of leaving. No money was collected, but the customer stayed
NudgedEarly check-ins sent because usage slipped
Keeps … a yearWhat those customers are worth over a year (monthly revenue × 12): the revenue you kept
At risk nowThe amounts on every open case: REX is on it, needs a human, or waiting on the customer
Promised, not yet paidAmounts customers agreed on a call to pay by a date
Needs a humanCases waiting on your approval, blocked by your rules, not recovered (including promises not kept), or handed to your team
Shadow decisionsCases REX decided in shadow mode without acting
On a call nowLive phone calls in progress
CasesFailed payments and churn signals REX worked in the period
Needed a personApprovals your team gave, plus cases handed to them
Blocked by your rulesActions your policy stopped: fraud, chargebacks, do-not-call, "I'm handling this"
Payment links deliveredLinks sent, and links that failed, across SMS and email

The command center's queues:

  • REX is on it: detected, calling, or climbing the ladder.
  • Needs a human: approvals and hand-offs.
  • Waiting on the customer: they promised to pay by a date. REX checks the day after, and moves an unpaid promise to Needs a human.
  • Recovered: paid, or kept on a pause or a cheaper plan.

Each queue is ordered by priority.

What REX keeps on record

  • Every policy decision: what was proposed, the outcome (automatic, needs approval, blocked), the rule and the reason.
  • Every action and its result: calls with their transcript, payment retries, pauses, plan changes, links, messages.
  • The contact log: every call, SMS and email, and how it went.
  • The offer log: every hold, link, retry, pause and plan change offered, whether it was accepted, and whether a promised payment was kept.
  • The clock: every step REX has planned, taken or stopped, with the result or the reason. Open it from Command center → Coming up → The REX clock: Coming up, Done and Stopped tabs.

Today's limits

  • Product usage and support signals come from connected tools. Without them, risk is scored from Stripe alone, and the customer page says so.
  • Everyone calls from a shared REX number for now. Your own number is coming.
  • Messages to Indian numbers need DLT registration for business SMS. International SMS may be filtered until then.

The core loop

A failed payment, a visit to the cancellation page, a drop in usage: every one of these moves through the same nine stages. Nothing skips straight from noticing a problem to a canned response.

EventContextRiskRecipeReasonPolicyExecuteVerifyOutcome

REX doesn't just suggest what to do. It carries out the part it's allowed to, then checks the result before calling anything recovered.

System architecture

Every case moves down one pipeline, in the same order, every time. The runtime reads whichever recipe applies and works through its steps; it doesn't have separate logic bolted on for each situation.

EventGatewayReceives the signalContextEngineBuilds the pictureRiskEngineScores the riskRecipeMatcherPicks the playbookAgentRuntimeDecides the actionPolicyEngineChecks it's allowedExecutionCarries it outVerificationConfirms it worked

Everything here is scoped to your account. Nothing about how one company's data is read or scored ever touches another company's.

How each piece works

Event Gateway

The entry point. Accepts an incoming event for your account and ignores anything it has already seen.

Reads

An event from your systems, sent with your API key

Produces

A new case to work on, or nothing if it was a duplicate

Context Engine

Builds a full picture of the customer from whatever systems you have connected. If you have not connected something, that part is simply left out.

Reads

The customer, and whatever you have connected

Produces

Customer profile, support history, and usage, where available

Risk Engine

Scores how serious the situation is, with a plain-English reason for every factor that contributed. This is a calculation, not a guess.

Reads

The event, and the customer's context

Produces

A risk score and level, with the reasons behind it

Recipe Matcher

Looks up which recipe you've configured to handle this kind of event. Adding a new recipe never requires a code change.

Reads

Your account, and the type of event

Produces

The matching recipe, or none if you haven't configured one

Agent Runtime

Follows the matched recipe step by step, working out what to propose at each stage.

Reads

The recipe, the risk score, and the context

Produces

A proposed action for each step, sent to the Policy Engine

Policy Engine

Checks every proposed action against your own rules before anything happens. Nothing executes without clearing this step.

Reads

The proposed action, the risk score, and your rules

Produces

Automatic, needs approval, blocked, or denied

What happens after an event comes in

Everything up to the policy check runs the same way every time: build context, score the risk, match a recipe, decide on an action. The interesting part is what happens next, since a proposed action can end up in one of three places: carried out automatically, held for approval, or stopped outright. The diagram below walks through all three:

YourBackendsends the eventREXAPIchecks the API keyAgentRuntimeruns the recipePolicyEngineapplies your rulesConnectedSystema mock todayAuditLogrecords everythingalt[allowed automatically][needs approval][blocked or denied]Send an event (payment failed) with your API keyBuild context, score the risk, match a recipe(no branching yet, so it's shown as one step here)Decide what to do and prepare a proposal for itCheck the proposal against your policy rulesResult: automatic, needs approval, blocked, or deniedRecord the decision and why it was madeCarry out the actionResultRecord what happenedCase updated: action takenSave the action so it can be approved laterCase updated: waiting for approval(a separate request, whenever approval comes)Approve the pending actionConfirm the approvalCheck that nothing about the case has changedCheck the policy again, using the latest risk dataResult, checked againif anything changed or it's no longer allowed, stop hereCarry out the actionResultRecord what happenedRecord that the case was blocked, nothing was doneCase updated: blocked

A blocked action and a denied one both stop the same way here: nothing is ever carried out, and the case shows exactly why.

Policy layer

REX never lets a model decide everything on its own. Every action it proposes is checked against rules you set, in the order you set them, and the check also takes into account how risky the situation actually is, not just which action was proposed:

Retry a payment, high risk           -> allowed automatically
  ("losing the account costs more than the retry")

Refund over 1,000                    -> needs your approval

A fraud signal is present            -> blocked, no contact attempted

A chargeback has happened            -> denied, always goes to a person

Anything else                        -> needs your approval (the default)

Rules are checked in order and the first match wins. Every rule set needs a default at the end, and REX won't accept a configuration that leaves one out.

Recipes

A recipe is what you configure, not what you code: which event it responds to, what it needs access to, the steps it takes, and how success is defined. Three recipes are available today:

RecipeResponds toStepsNeeds access to
Payment RecoveryA payment failureLook into it, reach out, decide, retry the payment, confirm the outcomePayments, voice, support
Churn RescueA visit to the cancellation pageLook into it, reach out, decide, open a ticket for a human, confirm the outcomeVoice, support
Usage NudgeUsage slipping below the customer's own normalLook into it, send one helpful check-in email, log it for your teamSupport

Payment Recovery is the recipe used in the reference walkthrough below. More recipes, like trial and checkout rescue, are on the roadmap but not available yet.

Capabilities & providers

REX doesn't build logic around any one vendor. It works against five kinds of connections, and whichever provider you use for each one plugs into the same interface underneath. Today, every one of them runs on a mock version so the whole flow can be tried without any external accounts:

ConnectionAvailable todayPlanned
PaymentsmockDodo, Stripe, Razorpay, or your own
SupportmockFreshworks, Zendesk, or your own
VoicemockElevenLabs, Sarvam, a local pipeline, or your own
CRMmockSalesforce, HubSpot, or your own
AnalyticsmockPostHog, Segment, Amplitude, or your own

Where the console shows REX placing a call or retrying a payment today, that's the mock standing in, not a real vendor. If you haven't connected something, REX doesn't fail: it still scores the risk and works out what it would do, it just can't act on that one part yet.

Accounts & authentication

Every company on REX gets its own isolated space: its own data, its own connections, its own recipes, its own rules, its own history. There's one rule underneath all of it: which account a request belongs to is decided by the API key it's sent with, never by anything else in the request.

An API key identifies your account and nothing else needs to. Creating a new account for the first time is the one exception, since there's no key yet to prove who's asking, so that step needs a separate setup credential. After that, everything, connecting a system, setting your rules, configuring a recipe, can be done with your own key.

Reference walkthrough

The scenario the console is seeded with, running against the mock providers described above:

A payment fails for Arjun Sharma (Rs 4,999/month, insufficient funds)

REX pulls in what it knows about the account
Scores it as high risk (a real payment failure, not a minor signal)
Matches it to the Payment Recovery recipe
Reaches out, then retries the payment
Your rules allow all of it automatically
The retry succeeds

Result: recovered, Rs 59,988 in annual revenue protected

See it live in the console: open at-risk customers and click into Arjun Sharma once the demo account is seeded, or check voice call for the conversation the mock voice provider produces.

Current status

Available now Stripe: connect with a key, import every customer and subscription, failed and paid invoices start and close cases, retries, payment links, pauses, plan changes and coupons. Real phone calls through Twilio, held by Voxie, in 17 languages. Payment links by SMS (Twilio) and email (Resend). Risk, priority and contact as three separate, explained answers. A policy gate for every action, with shadow mode, calling hours, rest between calls, do-not-call, "I'm handling this" and offer limits. The escalation ladder, card-expiry reminders and usage-slipping check-ins. Contact and offer logs, a full audit trail, isolated accounts, API key authentication, onboarding, the command center and the report. Three recipes.

Partly there Support, CRM and analytics are still mock providers; product usage can be sent directly to POST /v1/usage. Every company calls from one shared REX number. SMS to Indian numbers needs DLT registration. After a person approves an action, the rest of the recipe doesn't continue. Stripe keys are encrypted at rest, with the key in an environment variable rather than a KMS.

On the roadmap Connect with Stripe (OAuth). A number per company. Real support, CRM and analytics connectors. A public SDK, outbound webhooks, and a worker queue in place of the in-process clock. Key rotation and rate limiting.