Abandoned-cart recall you own: sequences, coupons, deliverability
Multi-step recall sequences, per-interval coupons, and queue dedupe are the easy part. The hard part is owning your own sending reputation.
Every funnel tool claims abandoned-cart recovery. Almost none explain what it does, and none explain the part that decides whether it works at all.
The mechanism is simple: orders that sit in PENDING past a time threshold get an email. Autonnel does that with three configurable touches and optional coupons, and I will walk through exactly how. Then I am going to spend the second half of this post on deliverability, because when you self-host, the sending reputation is yours, and that is the variable that decides whether recall recovers revenue or quietly fills spam folders.
The sequence
Recall targets orders that started checkout and never reached payment. Autonnel checks PENDING orders on a schedule and sends the right email at each configured interval. There are three:
| Interval | Template | Default offset |
|---|---|---|
| Recall 1 | RECALL_1 | 24 hours after order creation |
| Recall 2 | RECALL_2 | 72 hours after order creation |
| Recall 3 | RECALL_3 | 168 hours, one week |
The hour offsets are yours to change. What you cannot change is that each interval maps to a distinct template type, so there is no configuration in which two touches send the same body.
Offsets are measured from order creation, not from the last touch. Moving Recall 2 from 72 to 48 does not shift Recall 3, it just compresses the gap between the second and third message. An evenly spaced sequence is arithmetic you do yourself.
The templates ship in English, French, German and Spanish. Which one a customer gets is decided by the checkout language recorded on their order, falling back to English when it is not one of the four. You do not pick this per campaign, and I think that is right: the language the customer shopped in is the language they should be recalled in.
Coupons per interval
Each interval can optionally carry a coupon, and this is where a recall sequence stops being three reminders and starts being an escalation.
Bind a coupon to an interval and two things happen. The code is injected into the email as a highlighted block, and the recall link carries ?coupon=CODE so the discount applies automatically when the customer lands. They do not have to type anything.
Coupons are percentage or fixed amount, with optional minimum order amount, usage limit and expiry. So the obvious shape is: no coupon at 24 hours, a modest percentage at 72, something sharper at a week, with a usage limit on the sharp one so a leaked code cannot be farmed indefinitely.
Two behaviours you want to know before you meet them in production:
Only one coupon applies per order. There is no stacking. If a recall link carries ?coupon=A and the customer pastes code B into the checkout field, the last one applied wins. Your recall discount can be overwritten by a worse public code from a voucher site, and nothing warns you.
Deactivating a bound coupon does not disable the interval. Only active coupons appear in the binding dropdown, but if you switch off a coupon that is already bound, the interval keeps firing and the email goes out with no code in it. That email is not broken, but it is not the one you designed either. If you retire a coupon, check what it was bound to.
What the cron actually does
The recall processor runs every 30 minutes. For each interval it queries PENDING orders whose creation time falls in that interval’s window, skips orders with a placeholder or missing email, checks whether that exact recall touch was already sent for that order, builds the checkout URL, and enqueues the email.
Three details in there are load-bearing.
Dedupe is per order and per interval, and it cannot be bypassed. The same recall touch is never queued twice for the same order. This is the guarantee that makes a 30-minute cron safe: overlapping runs, a restart mid-batch, a backfill after downtime, none of them can produce a duplicate. The flip side is that in development you cannot re-test a touch on the same order. You create a fresh PENDING order or you see nothing.
Attribution survives. The recall link preserves all the original URL parameters from the order, so fbclid, ttclid, gclid and your UTM tags ride along. A recovered conversion attributed to nothing is worth very little to you, and this is the difference between a recall sequence you can measure and one you take on faith. The link also carries recall=true, so recovered sessions are distinguishable from cold ones.
Two limits keep the job bounded. Each interval run caps at 200 candidate orders, so a single cron tick cannot turn into a long-running batch. And the window carries a 72-hour lookback buffer to catch orders missed during downtime. That buffer is a real ceiling: an order older than its interval plus 72 hours will never receive that recall email. Four days of downtime and those orders are gone from the sequence. I prefer that to coming back online and blasting a week of backlog into a cold list, but it is a loss and you should know it is happening.
Disabling recall is a toggle. The cron still fires, it just exits immediately.
Now the part nobody writes about
Everything above is mechanism, and mechanism is the easy half.
When you self-host, sending reputation is yours. There is no shared platform IP absorbing your mistakes and no vendor deliverability team quietly cleaning up after you. Your domain, your bounce rate, your complaint rate, your problem.
The first consequence comes before you send anything: SPF, DKIM and DMARC on your sending domain. The docs list it as a prerequisite for configuring a provider at all, and call skipping it the most common reason emails land in spam. Recall raises the stakes over transactional mail, because recall is unsolicited by definition. A receipt lands on goodwill the customer extended by buying. A recall email has none of that credit, and it goes to the population most likely to hit the spam button.
The second consequence is volume, and this is where free tiers fall over.
Autonnel supports SMTP, Resend and AWS SES. Resend’s free tier caps sending at 100 emails per day. Do the arithmetic against a three-touch sequence. One cart that never converts consumes three emails. At 100 per day that is roughly 33 abandoned carts, before a single receipt, shipped, delivered or refunded notification, which share the same quota. The docs say it directly: use a paid plan for production recall. That is the most common way I expect a self-hosted recall setup to fail on day one.
Two more constraints that catch people:
SMTP does not work on Cloudflare Workers. Workers do not support outbound TCP connections to SMTP ports, so Gmail SMTP, Postmark SMTP and your own mail server are all off the table there. On Workers you use Resend or SES, both of which send over HTTPS. If SMTP is a hard requirement, deploy on Node instead. That is a deployment-shape decision, not a settings toggle, and far cheaper to make before you build than after.
SES starts in sandbox mode, which restricts sending to verified addresses only. Sandbox SES will pass every test you run against your own inbox and reach zero customers. Request production access before launch.
One trap in the tooling itself: the Test connection button verifies that credentials are valid and the provider is reachable. It does not verify deliverability. A green result with broken DKIM is entirely possible. Send a real message to an inbox on a domain you do not control and read the headers.
When it goes wrong, look at the queue
Emails are not sent inline. Order events and the recall cron enqueue; a background job dispatches through your provider. Every row appears in the /orders/emails tab with the recipient, template type, a status of PENDING, COMPLETED or FAILED, an attempt count and the last provider error. Filter to recall types, or to failures, when the sequence “isn’t sending”.
A failing send is retried with backoff, starting at 5 minutes and capping at 6 hours between attempts, and it gives up after 5. That cap matters more than it sounds: a misconfigured provider does not leave a queue that drains itself once you fix the configuration, it leaves a pile of exhausted rows that were already spent while the configuration was wrong. Watch the FAILED filter after any provider change. Deactivating a provider is the gentler case, since queued mail stays pending and resumes once a provider is configured again.
The limitation I would want told to me
Template customisation is not available in the admin UI. You can preview every template in every language, and that is all. Changing the copy of RECALL_1 means editing the template source in your fork and rebuilding, and if you maintain those edits, upstream changes to the template structure may need manual merging.
For a transactional receipt that is fine. For recall it is a real constraint, because recall copy is marketing copy and marketing copy wants iteration. Right now each iteration costs you a deploy. Weigh that before planning a recall program around rapid testing.
One more thing to check in your own deployment: PENDING covers two situations, an order waiting on the customer and a PayPal payment that is authorised but not yet captured. Recall queries PENDING orders. Whether the second group gets recalled depends on how your auto-capture schedule compares to your first interval, so if you run PayPal in authorisation mode, verify that before turning recall on.
Worth it anyway
None of this is an argument against running recall yourself. It is the bill.
The upside is the one that runs through the rest of self-hosting a checkout: no per-contact tier, and no fee attached to how well the sequence performs. Recovered revenue is yours. Set that against what ClickFunnels charges for the same capability and the arithmetic gets favourable quickly. What remains is a paid email plan, measured against a recovery rate you can observe.
Just do not start on the free tier and conclude that recall does not work.
Full details in recall settings, email provider and coupons. If you would rather not own the sending reputation at all, Cloud is the same application with the operations handled.