Operations Alerts
These are the automated emails sent to the operations team when events require attention or awareness. All ops emails go to the configured SPV operati...
These are the automated emails sent to the operations team when events require attention or awareness. All ops emails go to the configured SPV operations email address.
Complete List of Operations Alerts
Payment Retry Exhausted
| Detail | Value |
|---|---|
| When sent | When all automatic retry attempts for a payment have been used up |
| Subject | "Retry exhausted: Investment #[ID] -- [Investor Name] -- [Deal Name]" |
| What it contains | Investment details, number of attempts, failure code, failure details |
| What to do | Contact the investor to resolve the banking issue. Options: investor fixes their bank, switches to wire, or cancels. See Payment Failed playbook. |
| Triggered by | RetryPaymentService exhausting max attempts |
Permanent Payment Failure
| Detail | Value |
|---|---|
| When sent | When a payment fails with a non-retriable error (no automatic retries possible) |
| Subject | "Permanent payment failure: Investment #[ID] -- [Investor Name] -- [Deal Name]" |
| What it contains | Investment details, failure code, failure detail, and that it's not retriable |
| What to do | Investigate the failure reason. Contact the investor. May need to cancel the investment or arrange alternative payment. See Payment Failed playbook. |
| Triggered by | HandlePaymentFailedJob detecting non-retriable failure |
Verification Needs Action
| Detail | Value |
|---|---|
| When sent | When a KYC or KYB verification enters "needs_info" status |
| Subject | "Verification needs action: [Investor Name] -- [KYC/KYB]" |
| What it contains | Investor name, verification type (KYC or KYB), number of affected investments |
| What to do | Contact the investor about the additional documentation needed. See Verification Issues playbook. |
| Triggered by | compliance.kyc_needs_info or compliance.kyb_needs_info event |
Verification Rejected
| Detail | Value |
|---|---|
| When sent | When a KYC or KYB verification is rejected |
| Subject | "Verification rejected: [Investor Name] -- [KYC/KYB]" |
| What it contains | Investor name, verification type, number of affected investments |
| What to do | Investigate the rejection reason. Help the investor resolve the issue or consider alternative approaches (like wire bypass). See Verification Issues playbook. |
| Triggered by | compliance.kyc_rejected or compliance.kyb_rejected event |
Wire Transfer Expired (Ops)
| Detail | Value |
|---|---|
| When sent | Only when the payment provider (Modern Treasury) archives an expected payment -- a manual/terminal action at the provider. We never trigger this on overdue alone. |
| Subject | "Wire expired: Investment #[ID] -- [Investor Name] -- [Deal Name]" |
| What it contains | Investment details and expected payment details |
| What to do | The EP is moved to expired locally, but a late wire that eventually arrives will still reconcile and fund the investment automatically. Contact the investor if you want to chase them. If they paid and you need to nudge MT, use the Re-open action on the expected payment admin page -- this calls MT's unarchive endpoint and puts the EP back in pending so MT will auto-match. See Wire Not Received playbook. |
| Triggered by | Provider expected_payment.archived webhook (NOT overdue -- those are informational and tracked separately below). |
Wire Transfer Overdue (Provider) (Ops)
| Detail | Value |
|---|---|
| When sent | When Modern Treasury sends the expected_payment.overdue webhook (an expected payment passed its date_upper_bound without being reconciled). The expected payment remains matchable -- this is informational only. |
| Subject | "Wire overdue (informational): Investment #[ID] -- [Investor Name] -- [Deal Name]" |
| What it contains | Investment details, expected payment details, days waiting |
| What to do | Usually nothing -- if you want to stop chasing, cancel the EP from admin (which archives it at MT and triggers the expired alert above). Otherwise the EP keeps waiting and the wire will auto-reconcile when it arrives. Distinct from the Wire Overdue Escalation below, which is our internal day-counter (15 / 20 days). |
| Triggered by | Provider expected_payment.overdue webhook |
Wire Overdue Escalation
| Detail | Value |
|---|---|
| When sent | When a wire has been pending for 15 or 20 business days (alongside the investor's third and final reminders) |
| Subject | "Wire overdue [X] days: Investment #[ID] -- [Investor Name]" |
| What it contains | Investment details and how many business days the wire has been overdue |
| What to do | Follow up with the investor. At this point, it's likely the investor either forgot or needs assistance. Consider whether to keep waiting or cancel the investment manually. See Wire Not Received playbook. |
| Triggered by | Automated overdue wire check (runs daily) |
Overpayment Detected
| Detail | Value |
|---|---|
| When sent | When an inbound payment completes and the investment has received more than the committed amount |
| Subject | "Overpayment detected: Investment #[ID] -- [Investor Name] -- [Deal Name]" |
| What it contains | Investment details, committed amount, total collected amount, overpayment amount, payment order ID |
| What to do | Adjust the investment amount up to match the collected amount (use "Adjust Amount" action), or initiate a partial refund for the excess. |
| Triggered by | payments.order_completed event (via HandlePaymentCompletedJob) when overpayment is detected |
Funding Close Settled (Ops Summary)
| Detail | Value |
|---|---|
| When sent | When a Funding Close is settled |
| Subject | "Funding Close #[N] settled for [SPV Name]: $[Amount] across [N] investors" |
| What it contains | Close number, SPV name, total settled amount, number of investors |
| What to do | Informational -- confirm the settlement details are correct. Proceed with next steps (additional closes, SPV closure, disbursement). |
| Triggered by | funding_close.settled event |
Funding Close Cancelled (Ops Notice)
| Detail | Value |
|---|---|
| When sent | When a Funding Close is cancelled |
| Subject | "Funding Close #[N] cancelled for [SPV Name]" |
| What it contains | Close number and SPV name |
| What to do | Informational -- be aware that the investments from this close are now unassigned and available for a new close. |
| Triggered by | funding_close.cancelled event |
SPV Cancelled -- Funded Investments Need Refund
| Detail | Value |
|---|---|
| When sent | When an SPV is cancelled and it has funded investments (investors whose money has already been collected) |
| Subject | "SPV cancelled: [SPV Name] -- [N] funded investments need refund review" |
| What it contains | SPV name, number of funded investments, total funded amount, and a link to the SPV admin page |
| What to do | Review each funded investment and initiate refunds via the "Initiate Refund" action on each investment page. Funded investors have been notified that a refund is being processed. |
| Triggered by | spv.cancelled event (via HandleSpvCancelledJob) when funded investments exist |
Stale Pending Investments
| Detail | Value |
|---|---|
| When sent | Daily (weekday mornings) when investments have been stuck in pending for longer than the configured threshold (default 5 days) |
| Subject | "Stale pending investments: [N] investments stuck for [X]+ days" |
| What it contains | Table of stale investments with ID, investor name, deal name, amount, and number of days pending |
| What to do | Investigate each investment in the admin panel. Common causes: bank registration failure, KYC/KYB not resolving, wire never matched, or missed retry. Take action: re-dispatch payment, cancel investment, or contact the investor. |
| Triggered by | Automated daily stale investment detection job (weekdays 10 AM UTC) |
Ledger Invariant Violations
| Detail | Value |
|---|---|
| When sent | When the daily ledger invariant check detects error-level violations |
| Subject | "Ledger invariant violations detected: [N] violation(s)" |
| What it contains | Timestamp, list of violated invariants with entity type, entity ID, and detail |
| What to do | Investigate the specific invariant and entity. See Ledger Health & Validation for what each check means. |
| Triggered by | Daily scheduled ledger validation job |
| Also sent to | Slack (configured ledger alerts channel) |
What Admins Should Know
- Action-required alerts need prompt attention -- retry exhausted, permanent failure, and verification issues all mean the system can't proceed without human help.
- Informational alerts keep you aware -- settlement and cancellation notices don't require action but help you stay on top of what's happening.
- Wire escalation is time-sensitive -- a wire overdue for 15+ business days likely needs a phone call or personal outreach to the investor. Ops is notified at 15 and 20 business days. Wires never auto-expire; if the investor is unresponsive, cancel the investment manually. The overdue wire check runs automatically on weekdays at 2 PM UTC.
- Expired EPs still accept late wires. A wire that arrives after we marked the expected payment
expired(because MT archived it) will still reconcile and fund the investment. The reconciliation writes alate_matchaudit entry so it's clear this funded post-expiry by design. Use the Re-open admin action only when you want MT to resume auto-matching (it calls MT's unarchive endpoint). - Stale pending investment alerts run daily on weekday mornings -- they catch investments that fell through the cracks. Common causes include failed bank registration, unresolved KYC/KYB, wires that were never sent, or a scheduled retry that never fired.
- Verification emails currently go to ops only -- investor-facing verification failure emails are not yet enabled. The ops team is responsible for communicating verification issues to investors.
- All alerts include investment IDs -- you can use the investment ID to quickly find the relevant record in the admin panel.
Was this page helpful?
Last updated 5 days ago
Built with Documentation.AI