Recovery Orchestrator
End-to-end recovery pipeline for Zoho Billing. Combines recovery-cohort-builder and recovery-strategy into a single run and produces a propose-only Markdown report for human review.
The agent never sends emails, applies discounts, or modifies any records. Every output is a proposal file.
Pipeline overview
1. Fetch reports ─→ ZohoBilling_get_lost_opportunities_report (last 7 days)
ZohoBilling_get_abandoned_carts_report (last 7 days)
2. Build cohort ─→ Normalize + sort by lost_value DESC
(lost opportunities first, then abandoned carts)
3. Apply strategy ─→ apply_recovery_matrix.py → per-record recommendations
4. Write report ─→ recovery-runs/<DATE>/proposal.md
Step-by-step instructions
Step 1 — Set date range
Compute:
to_date= today (YYYY-MM-DD)from_date= today minus 7 calendar days
Step 2 — Fetch cohort (follow recovery-cohort-builder skill)
Call both reports in parallel:
ZohoBilling_get_lost_opportunities_reportwithfrom_date/to_dateZohoBilling_get_abandoned_carts_reportwithfrom_date/to_date
Normalize both into the unified schema and sort:
- All
lost_opportunityrecords, sorted bylost_valueDESC - All
abandoned_cartrecords, sorted bylost_valueDESC
Save to recovery-runs/<DATE>/cohort-raw.json.
If both reports return empty results, write a brief note to the user and stop — no report needed.
Step 3 — Apply strategy (follow recovery-strategy skill)
python <skill-path>/scripts/apply_recovery_matrix.py \
--cohort <workspace>/recovery-runs/<DATE>/cohort-raw.json \
--matrix <workspace>/config/recovery-matrix.yaml \
--output <workspace>/recovery-runs/<DATE>/cohort-recommendations.json
If the script exits with code 2 (missing catch-all), stop and tell the user to add one to the matrix YAML before re-running.
Step 4 — Write the proposal report
Save to recovery-runs/<DATE>/proposal.md. Use the report template below exactly.
Report template
# Recovery Proposal — <DATE>
> Generated by recovery-agent · Propose-only · No actions taken automatically
## Summary
| Metric | Value |
|--------|-------|
| Report window | Last 7 days (<FROM_DATE> → <TO_DATE>) |
| Lost Opportunities | N records · $X,XXX total lost value |
| Abandoned Carts | N records · $X,XXX total lost value |
| **Total recoverable** | **N records · $X,XXX** |
### Action breakdown
| Action | Count | % of total |
|--------|-------|-----------|
| human_outreach | N | X% |
| email_with_discount | N | X% |
| email_reminder | N | X% |
| email_sequence | N | X% |
| accept | N | X% |
---
## Section 1 — Lost Opportunities
*Sorted by lost value (highest first)*
### 🔴 Urgent — Human Outreach Required
> Route to Sales immediately. These are fresh, high-value leads.
| Customer | Email | Plan | Lost Value | Days Since | Action | Route To | Notes |
|----------|-------|------|-----------|------------|--------|----------|-------|
### 🟡 Email with Discount
> Send personalised discount email within 24 hours.
| Customer | Email | Plan | Lost Value | Days Since | Discount | Expiry | Rationale |
|----------|-------|------|-----------|------------|----------|--------|-----------|
### 🟢 Email Sequence / Reminder
> Add to automated nurture sequence.
| Customer | Email | Plan | Lost Value | Days Since | Sequence | Steps | Rationale |
|----------|-------|------|-----------|------------|----------|-------|-----------|
---
## Section 2 — Abandoned Carts
*Sorted by lost value (highest first). These leads had the highest purchase intent — they chose a plan and started checkout.*
### 🔴 Urgent — Human Outreach Required
> These visitors were moments from converting. Call or email personally.
| Customer | Email | Plan | Cart Value | Hours Since | Action | Route To | Notes |
|----------|-------|------|-----------|-------------|--------|----------|-------|
### 🟡 Email with Discount
> Checkout recovery email with time-limited discount.
| Customer | Email | Plan | Cart Value | Hours Since | Discount | Expiry | Rationale |
|----------|-------|------|-----------|-------------|----------|--------|-----------|
### 🟢 Cart Reminder
> Standard cart recovery reminder.
| Customer | Email | Plan | Cart Value | Hours Since | Urgency | Notes |
|----------|-------|------|-----------|-------------|---------|-------|
---
## Next steps
1. **Sales team**: action all `human_outreach` rows within the time window specified.
2. **Marketing / CRM**: queue the discount and sequence emails — confirm coupon codes are live before sending.
3. **Review**: re-run in 48 hours to check which records converted; remove converted customers from active sequences.
---
*This report is a proposal only. No emails have been sent and no records have been modified.*
Output paths
| File | Contents |
|---|---|
recovery-runs/<DATE>/cohort-raw.json |
Normalized cohort before strategy |
recovery-runs/<DATE>/cohort-recommendations.json |
Cohort with per-record recommendation appended |
recovery-runs/<DATE>/proposal.md |
Human-readable proposal report |
After writing the report, confirm paths and show the user the summary table.
Edge cases
- One source empty, other has data → run normally; omit the empty section from the report.
- All records are
accept→ still write the report; note it as a healthy signal. - >50%
human_outreach→ flag this to the user — may indicate value thresholds in the YAML need tuning. - Dates straddle a month boundary → no special handling needed; the API accepts cross-month ranges.