Use casesWorkflow
AI Appointment Booking Agent
An AI agent that handles scheduling conversations over email — booking meetings, negotiating times, managing reschedules, and sending confirmations, without any human involvement.
The problem
Scheduling meetings is one of the most tedious parts of professional communication. The back-and-forth alone — proposing times, checking availability, accommodating time zones, handling last-minute changes — can eat hours every week. Calendar tools like Calendly help, but they require the other party to click a link and pick from a grid. Many people simply prefer to negotiate times over email, the way they always have.
For businesses that handle high volumes of scheduling — sales teams booking demos, healthcare practices confirming patient visits, consulting firms arranging client calls — this manual email coordination becomes a serious bottleneck. Hiring a human scheduling assistant works, but doesn't scale. What if an AI agent could own the entire scheduling conversation?
How an agent solves this
An AI scheduling agent operates from its own email address — something like scheduling@yourcompany.com. When someone requests a meeting (or gets introduced by a teammate), the agent takes over the conversation. It checks calendar availability, proposes times, responds to counter-proposals, handles rescheduling requests, and sends confirmations — all through natural email.
Because the agent uses a real email address with proper DKIM and SPF authentication, replies land in the recipient's inbox like any other email. No links to click, no forms to fill out. The experience feels like emailing a responsive, tireless human assistant.
- Propose available time slots based on real calendar data
- Negotiate duration, location (virtual or in-person), and attendees
- Handle rescheduling and cancellation requests gracefully
- Send calendar invites and confirmations automatically
- CC the meeting organizer on confirmations so they stay in the loop
How it works with Robotomail
Robotomail provides the email infrastructure your scheduling agent needs to operate autonomously. Create a dedicated mailbox, receive inbound messages via webhooks, and send replies through the API — all with proper threading so conversations stay organized.
Step 1: Create a scheduling mailbox
curl -X POST https://api.robotomail.com/v1/mailboxes \
-H "Authorization: Bearer rm_your_api_key" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"address": "scheduling",
"domainId": "dom_yourcompany",
"displayName": "Alex — Scheduling Assistant"
}
JSONStep 2: Receive scheduling requests via webhook
When someone emails your scheduling address, Robotomail delivers the message to your webhook endpoint in real time. Your agent parses the request, checks the calendar, and decides how to respond.
{
"event": "message.received",
"timestamp": "2026-03-22T14:32:00Z",
"data": {
"message_id": "11111111-1111-4111-8111-111111111111",
"mailbox_id": "22222222-2222-4222-8222-222222222222",
"mailbox_address": "scheduling@yourcompany.com",
"from": "jane@clientcorp.com",
"to": [
"scheduling@yourcompany.com"
],
"cc": [],
"subject": "Re: Meeting Request — Q2 Planning",
"body_text": "Tuesday at 2pm works. Can we do 45 minutes instead of 30?",
"thread_id": "33333333-3333-4333-8333-333333333333",
"received_at": "2026-03-22T14:32:00Z",
"attachments": []
}
}Step 3: Pull thread history for context
Before replying, your agent can fetch the full conversation thread to understand context — what times were already proposed, what was rejected, and what the current state of the negotiation is.
curl https://api.robotomail.com/v1/mailboxes/mbx_scheduling/threads/thr_4x9p1q \
-H "Authorization: Bearer rm_your_api_key"Step 4: Send a confirmation reply
Once times are agreed upon, fetch the original email and set inReplyTo to its RFC Message-ID (message.messageId), so the reply carries the original email header reference.
# inReplyTo below stands for the fetched message.messageId; see the reply example below.
curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_scheduling/messages \
-H "Authorization: Bearer rm_your_api_key" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"to": [
"jane@clientcorp.com"
],
"subject": "Re: Meeting Request — Q2 Planning",
"bodyText": "Perfect — Tuesday March 25 at 2:00 PM EST for 45 minutes is confirmed. I've sent a calendar invite to your email. See you then!",
"inReplyTo": "<original-message@example.com>"
}
JSONKey benefits
- Zero friction for the other party. No links, no calendly pages, no apps to install. They just reply to an email.
- Threaded conversations. Every message in a scheduling exchange stays in one thread, making it easy to review the negotiation history.
- Professional deliverability. Emails come from your domain with proper DKIM, SPF, and DMARC — not a generic address that triggers spam filters.
- Handles edge cases. Rescheduling, cancellations, time zone mismatches, multi-attendee coordination — your agent can handle all of it programmatically.
- Scales infinitely. Whether you're scheduling 5 meetings a day or 500, the agent responds in seconds, 24/7.
Read the API documentation to get started, or learn more about why we built Robotomail. Get started and have your scheduling agent running in minutes — paid plans come with a 30-day money-back guarantee.
Connect the workflow to a real reply
The webhook's data.message_id is a database ID used to retrieve or deduplicate a message. Fetch it with the GET message endpoint, then use the response's message.messageId (the RFC Message-ID) as inReplyTo. Keep data.thread_id for your application's conversation state. Do not use a database ID or thread ID as a reply header. Stop and investigate if the fetched message has no Message-ID.
Examples use illustrative IDs. Replace them with IDs from your account; never construct an email Message-ID from a database ID. These workflows email other people and need a paid plan. Test Free with your verified account email first; see plans.
Verify the webhook signature over the raw body, persist the event and deduplicate on the database message ID before acknowledging it. Run your application logic from a durable queue. The database, calendar, CRM and model functions shown above belong to your application.
This shell example fetches an incoming email and builds all required send fields. Set ROBOTOMAIL_API_KEY, ROBOTOMAIL_MAILBOX_ID and ROBOTOMAIL_MESSAGE_ID in your environment. Apply your recipient and approval rules before sending.
# Requires jq. Use mailbox_id and message_id from the verified webhook.
original=$(curl --fail --silent --show-error \
"https://api.robotomail.com/v1/mailboxes/$ROBOTOMAIL_MAILBOX_ID/messages/$ROBOTOMAIL_MESSAGE_ID" \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY") || exit 1
payload=$(printf '%s' "$original" | jq -e --arg body "Thanks, I received your message." '
.message | if (.messageId | type == "string" and length > 0) then
{to: [.fromAddress], subject: ("Re: " + .subject), bodyText: $body, inReplyTo: .messageId}
else error("Original email has no Message-ID") end
') || exit 1
curl --fail --silent --show-error \
"https://api.robotomail.com/v1/mailboxes/$ROBOTOMAIL_MAILBOX_ID/messages" \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY" \
-H "Content-Type: application/json" \
--data-binary "$payload"
Read receive and reply and webhook verification for the full setup.