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.
| Source | What REX reads | What 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 subjects | More 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 tier | Context 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_…).
| What | How | What REX does with it |
|---|---|---|
| Stripe events | Automatic. REX receives Stripe's webhook when it has a public address, and otherwise reads Stripe's event log | Failed and paid invoices start and close cases. Card details feed expiry reminders |
| Product usage | POST /api/v1/usage with customer_id and active_days_30, daily or weekly | Compares each customer with their own normal and checks in when usage slips |
| Other signals | POST /api/v1/events with event, customer_id, occurred_at and any details | For 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:
- Risk: how likely are we to lose them?
- Priority: how much does acting now matter?
- 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.
| Signal | Points | Source | When it counts |
|---|---|---|---|
| A payment failed | +40 | Stripe | Any failed subscription payment |
| The card can't be charged again | +25 | Stripe | Stolen, lost, expired, "do not honor" or "pick up card": retrying won't help |
| Fraud or a dispute | +25 | Stripe | Flagged by the bank. These payments are never retried |
| Looks temporary | 0 | Stripe | Insufficient funds and similar: a retry may well work |
| Opened the cancellation page | +35 | Your app | Right now |
| Opened the cancellation page recently | +25 | Your app | Earlier, with another signal now |
| Using the product less than before | +20 | Product usage | Usage is falling compared to the customer's own normal |
| Usage has slipped sharply | +25 | Product usage | The latest reading is under 60% of the customer's usual (see below) |
| Barely using the product | +10 | Product usage | Fewer than 5 active days in the last 30 |
| Several support tickets | +15 | Support | 3 or more recent tickets |
| Tickets about money | +10 | Support | Subjects mentioning billing, invoices, charges, refunds, pricing, cancelling or downgrading |
| Warning signs in several places | +5 per place | All | Signs 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:
| Situation | Urgency | Why |
|---|---|---|
| The card needs replacing | ×1.25 | Waiting won't fix it |
| They're on the cancellation page | ×1.2 | They're deciding right now |
| Normal | ×1 | |
| They promised to pay on a date | ×0.5 | Give them the chance to keep their word |
| Already recovered | ×0 | Nothing 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.
| Check | If it fails |
|---|---|
| A phone number is on file | No 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 called | Blocked: REX remembers "don't call me again" for good |
| Nobody on your team has claimed the customer | Blocked: 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 days | On hold: the call waits for approval |
| The workspace is live, not in shadow mode | On 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):
| When | What REX does |
|---|---|
| First days | Nothing: Stripe's own automatic retries go first |
| Day 2 | Emails the customer a payment link |
| Day 4 | Texts the payment link |
| Day 6 | Calls, 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:
| When | What REX does |
|---|---|
| Straight away | Emails and texts a link to pay with a new card |
| Day 1 | Calls, 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:
| When | What REX does |
|---|---|
| The due date, 10 am your time | One 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 am | Asks 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.
| Offer | Limit |
|---|---|
| Hold the account until a date | Up to your longest payment hold (default 7 days). A customer who asks for longer is offered the latest date allowed |
| Send a payment link | Now, or on the day the customer asks for ("send it in three days") |
| Retry the card | Now, or at a time the customer picks |
| A pause | 30 days, instead of cancelling. Automatic |
| A cheaper plan | Automatic if you allow discounts, otherwise your team approves each one |
| A refund | Automatic 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_limitrule and recorded like any other blocked action.
Payment links
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
| Metric | What it means |
|---|---|
| Recovered | Money 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 |
| Nudged | Early check-ins sent because usage slipped |
| Keeps … a year | What those customers are worth over a year (monthly revenue × 12): the revenue you kept |
| At risk now | The amounts on every open case: REX is on it, needs a human, or waiting on the customer |
| Promised, not yet paid | Amounts customers agreed on a call to pay by a date |
| Needs a human | Cases waiting on your approval, blocked by your rules, not recovered (including promises not kept), or handed to your team |
| Shadow decisions | Cases REX decided in shadow mode without acting |
| On a call now | Live phone calls in progress |
| Cases | Failed payments and churn signals REX worked in the period |
| Needed a person | Approvals your team gave, plus cases handed to them |
| Blocked by your rules | Actions your policy stopped: fraud, chargebacks, do-not-call, "I'm handling this" |
| Payment links delivered | Links 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.
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.
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.
An event from your systems, sent with your API key
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.
The customer, and whatever you have connected
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.
The event, and the customer's context
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.
Your account, and the type of event
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.
The recipe, the risk score, and the context
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.
The proposed action, the risk score, and your rules
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:
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:
| Recipe | Responds to | Steps | Needs access to |
|---|---|---|---|
| Payment Recovery | A payment failure | Look into it, reach out, decide, retry the payment, confirm the outcome | Payments, voice, support |
| Churn Rescue | A visit to the cancellation page | Look into it, reach out, decide, open a ticket for a human, confirm the outcome | Voice, support |
| Usage Nudge | Usage slipping below the customer's own normal | Look into it, send one helpful check-in email, log it for your team | Support |
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:
| Connection | Available today | Planned |
|---|---|---|
| Payments | mock | Dodo, Stripe, Razorpay, or your own |
| Support | mock | Freshworks, Zendesk, or your own |
| Voice | mock | ElevenLabs, Sarvam, a local pipeline, or your own |
| CRM | mock | Salesforce, HubSpot, or your own |
| Analytics | mock | PostHog, 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.