AI agents can handle order confirmations, delay notices, refund updates, and courier coordination without manual intervention — with full audit trails for every send.
Food delivery platforms and ghost kitchens operate on tight timing windows where a delayed or inaccurate email directly translates to refund requests, negative reviews, and churn. The communication surface is wide: diners expect real-time order status, couriers need pickup and route updates, and partner restaurants require accurate order details and settlement reports. High promotional send volumes add another layer — suppression lists, consent records, and local marketing regulations must be respected at scale. AI agents are well-suited to automate the routine high-volume flows, but the cost of a wrong order detail or a misfired refund notice is immediate and visible to the customer. MultiMail's monitored oversight mode lets agents send autonomously while operations teams retain visibility into every outbound message, making it practical to automate without losing accountability.
Order details — items, estimated delivery time, pickup address — can change after confirmation as kitchen capacity, courier availability, or inventory shifts. Emails sent with stale data trigger refund requests and support tickets. Agents need to pull current state at send time, not cache it from the order creation event.
Delivery status emails (out for delivery, arriving in 10 minutes, delivered) have a narrow window of usefulness. Sent too early they create false expectations; sent after arrival they're noise. Agents must trigger sends from real fulfillment events, not scheduled jobs.
State consumer protection laws and platform terms require accurate, timely refund status notices. An agent that sends a 'refund processed' email before the payment processor confirms the reversal creates legal exposure and undermines customer trust.
Ghost kitchens operating multiple virtual brands send high volumes of operational emails to restaurant partners and couriers daily. These must preserve traceability — who received what, when, and whether it was acted on — for dispute resolution and settlement reconciliation.
Re-engagement campaigns and promotional sends must honor suppression lists, CAN-SPAM unsubscribe headers, CCPA opt-out records, and GDPR consent where EU customers are involved. A single suppression list failure on a large promotional send creates regulatory exposure and deliverability damage.
FDA Food Code and state food safety regulations create liability when customer emails contain inaccurate allergen or dietary information. Agents generating personalized menu recommendations or order summaries must not make claims the underlying data cannot support.
Agents call send_email and reply_email to dispatch order confirmations, estimated arrival windows, and delivered confirmations triggered directly from fulfillment webhooks. In monitored mode, every send is visible to your operations team in real time without requiring their approval, so high-volume flows run at operational speed with full observability.
Agents poll payment processor state before sending refund confirmation emails, calling send_email only after the reversal is confirmed. Using gated_send mode for refund communications ensures a human reviews the notice before it reaches the customer, preventing premature confirmations that contradict payment processor state.
Agents send order details, pickup confirmations, and settlement summaries to restaurant partners and couriers via dedicated mailboxes. Monitored mode provides a full audit trail for every partner communication, supporting dispute resolution without requiring human approval on routine operational messages.
Agents manage post-delivery feedback requests and re-engagement sends against verified suppression lists. Autonomous mode is appropriate here for bulk sends where consent records are current, opt-out handling is automated via the cancel_message endpoint, and suppression list checks run before each send.
When a diner responds to a delivery update with a complaint or refund request, agents use check_inbox and get_thread to read the conversation and tag_email to classify it, then route to human agents via gated_all mode before any reply is sent. This prevents automated responses to sensitive dispute threads.
import multimail
from multimail import Multimail
client = Multimail(api_key="$MULTIMAIL_API_KEY")
def handle_order_confirmed(event: dict):
order = event["order"]
"cm"># Pull current order state — never use cached data from order creation
items_summary = ", ".join(
f"{item[&"cm">#039;quantity']}x {item['name']}" for item in order["items"]
)
allergen_note = order.get("allergen_flags", [])
body = f"""Your order "cm">#{order['id']} is confirmed.
Items: {items_summary}
Estimated delivery: {order[&"cm">#039;eta_minutes']} minutes
Delivery address: {order[&"cm">#039;delivery_address']}
"""
if allergen_note:
body += f"\nAllergen info on file: {&"cm">#039;, '.join(allergen_note)}"
client.send_email(
from_address=f"orders@{order[&"cm">#039;brand_domain']}",
to=order["customer_email"],
subject=f"Order "cm">#{order['id']} confirmed — arriving in {order['eta_minutes']} min",
body=body,
metadata={"order_id": order["id"], "event": "order_confirmed"}
)Send an order confirmation email immediately after a fulfillment event, pulling live order state at send time rather than using cached data from order creation.
import multimail
from multimail import Multimail
from enum import Enum
client = Multimail(api_key="$MULTIMAIL_API_KEY")
STATUS_SUBJECTS = {
"out_for_delivery": "Your order is on the way",
"arriving_soon": "Your order arrives in ~5 minutes",
"delivered": "Your order has been delivered",
}
STATUS_BODIES = {
"out_for_delivery": lambda o: f"Order "cm">#{o['id']} has been picked up by {o['courier_name']} and is heading your way.",
"arriving_soon": lambda o: f"Order "cm">#{o['id']} is about 5 minutes away. Head to the door.",
"delivered": lambda o: f"Order "cm">#{o['id']} was delivered at {o['delivered_at']}. Enjoy your meal.",
}
def handle_delivery_status(event: dict):
order = event["order"]
status = event["status"]
if status not in STATUS_SUBJECTS:
return # Ignore internal statuses not surfaced to customers
client.send_email(
from_address=f"updates@{order[&"cm">#039;brand_domain']}",
to=order["customer_email"],
subject=STATUS_SUBJECTS[status],
body=STATUS_BODIES[status](order),
metadata={"order_id": order["id"], "delivery_status": status}
)Trigger delivery status emails from real fulfillment events using MultiMail's send_email endpoint. Each status transition fires a targeted update rather than a polling job.
import multimail
from multimail import Multimail
import stripe
client = Multimail(api_key="$MULTIMAIL_API_KEY")
stripe.api_key = "sk_live_your_stripe_key"
def send_refund_confirmation(order_id: str, customer_email: str, refund_id: str):
"cm"># Verify the refund is actually succeeded before sending
refund = stripe.Refund.retrieve(refund_id)
if refund.status != "succeeded":
raise ValueError(
f"Refund {refund_id} status is &"cm">#039;{refund.status}', not 'succeeded'. "
"Deferring email until refund clears."
)
amount = refund.amount / 100 # cents to dollars
currency = refund.currency.upper()
# gated_send: human reviews before customer receives this
client.send_email(
from_address="[email protected]",
to=customer_email,
subject=f"Refund of {currency} {amount:.2f} processed for order "cm">#{order_id}",
body=(
f"Your refund of {currency} {amount:.2f} for order "cm">#{order_id} has been processed.\n\n"
f"Refund ID: {refund_id}\n"
"Funds typically appear within 3–5 business days depending on your bank."
),
oversight_mode="gated_send",
metadata={"order_id": order_id, "refund_id": refund_id}
)Use gated_send mode to hold refund confirmation emails until a human reviews them, preventing premature sends when payment processor reversal is pending.
import multimail
from multimail import Multimail
client = Multimail(api_key="$MULTIMAIL_API_KEY")
def run_reengagement_campaign(recipients: list[dict], brand_slug: str):
sent = 0
skipped = 0
for recipient in recipients:
"cm"># Check inbox for prior unsubscribe or opt-out signal
inbox = client.check_inbox(
mailbox=f"unsubscribes@{brand_slug}.multimail.dev",
query=recipient["email"],
limit=1
)
if inbox.get("total", 0) > 0:
skipped += 1
continue "cm"># Respect prior opt-out
client.send_email(
from_address=f"offers@{brand_slug}.multimail.dev",
to=recipient["email"],
subject="We miss you — here&"cm">#039;s 20% off your next order",
body=(
f"Hi {recipient[&"cm">#039;first_name']},\n\n"
"It&"cm">#039;s been a while. Use code WELCOME20 for 20% off your next order.\n\n"
"To stop receiving emails, reply with UNSUBSCRIBE."
),
headers={
"List-Unsubscribe": f"<mailto:unsubscribes@{brand_slug}.multimail.dev>",
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
},
metadata={"campaign": "reengagement_20pct", "recipient_id": recipient["id"]}
)
sent += 1
return {"sent": sent, "skipped_suppressed": skipped}Run re-engagement campaigns with automated suppression list checks and CAN-SPAM-compliant unsubscribe handling using the MultiMail API.
import multimail
from multimail import Multimail
client = Multimail(api_key="$MULTIMAIL_API_KEY")
COMPLAINT_KEYWORDS = ["refund", "wrong order", "missing", "late", "cold", "cancel", "allerg"]
def triage_support_inbox(mailbox: str):
inbox = client.check_inbox(mailbox=mailbox, limit=50, filter_tag="unread")
for message in inbox.get("messages", []):
body_lower = message["snippet"].lower()
is_complaint = any(kw in body_lower for kw in COMPLAINT_KEYWORDS)
if is_complaint:
"cm"># Tag for ops team visibility
client.tag_email(
message_id=message["id"],
tags=["complaint", "needs-human-review"]
)
"cm"># Pull full thread for context
thread = client.get_thread(thread_id=message["thread_id"])
"cm"># Draft a holding reply — gated_all requires human approval before send
client.reply_email(
message_id=message["id"],
body=(
"Thank you for reaching out. A member of our support team "
"will review your order and follow up within 2 hours."
),
oversight_mode="gated_all",
metadata={"thread_id": message["thread_id"], "triage": "complaint"}
)Read inbound customer complaint threads and route them for human review before any automated reply is sent, using check_inbox, get_thread, tag_email, and gated_all mode.
| Regulation | Requirement | How MultiMail helps |
|---|---|---|
| CAN-SPAM | All commercial email must include a functioning unsubscribe mechanism, a physical mailing address, and must honor opt-out requests within 10 business days. Re-engagement and promotional campaigns are subject to these requirements; transactional order emails have narrower exemptions. | MultiMail supports List-Unsubscribe and List-Unsubscribe-Post headers on outbound sends. Suppression list checks can be enforced in agent code by querying a dedicated unsubscribe mailbox via check_inbox before each promotional send. The cancel_message endpoint allows in-flight sends to be cancelled when a new opt-out arrives during a campaign run. |
| CCPA | California residents have the right to opt out of the sale or sharing of personal data used for targeted communications. Re-engagement campaigns using purchase history or behavioral data for personalization must provide a clear opt-out path and honor prior opt-out signals. | Agent workflows can query opt-out status before each send using check_inbox against a dedicated opt-out mailbox, and tag opt-out requests with tag_email for downstream processing. Metadata fields on each send preserve the consent basis used, supporting audit responses to consumer rights requests. |
| GDPR | For EU customers, marketing emails require a lawful basis (typically explicit consent). Consent records must be current and traceable. Data used to personalize communications must be limited to the purpose for which consent was given. Right to erasure requests must be actable. | Monitored mode provides a full send log with timestamps, recipient identifiers, and metadata fields where consent basis can be recorded per message. This supports audit responses. Agent code can enforce consent checks before sending by reading stored consent state and short-circuiting the send_email call when consent is absent or expired. |
| FDA Food Code / State Food Safety Laws | Customer-facing communications containing allergen information, dietary claims, or health-related statements must be accurate. Inaccurate allergen disclosures in order confirmation emails can create direct liability under state consumer protection laws. | MultiMail does not generate order content — agents must pull allergen and dietary data from authoritative menu databases at send time rather than caching it. The metadata field on each send_email call can record the data source and version used, creating an audit trail that links each email to the menu snapshot it was generated from. |
| State Consumer Protection Laws | Refund, cancellation, and delay notices must be accurate and timely. Sending a refund confirmation before the payment processor confirms the reversal, or a cancellation notice with incorrect order details, can constitute a deceptive trade practice under state consumer protection statutes. | Gated_send oversight mode holds refund and cancellation emails for human review before delivery, preventing premature sends. For automated flows, agents can verify payment processor state via API before calling send_email, and the monitored mode audit log provides a timestamped record of when each notice was sent relative to the fulfillment event. |
Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 50-tool MCP server. Formally verified in Lean 4.