Law firms lose leads because manual intake follow-ups are slow, inconsistent, and tied to staff availability and working hours. AgentMail provides an Email Inbox API that lets AI agents draft, refine, and send client intake follow-ups with full audit trails for compliance. Intake agents need to create draft emails, collect attorney review feedback, and send real outbound messages—all via REST API with searchable message history. AgentMail integrates directly into agentic workflows, enabling automated document request drafts, conflict check confirmations, and retargeting emails without custom SMTP infrastructure.
What this tutorial covers
- •Outcome: You will build a TypeScript intake agent that searches for new intake forms, drafts personalized follow-up emails with document requests, waits for attorney approval, and sends real client messages through AgentMail.
- •Endpoints used: `POST /v0/inboxes`, `POST /v0/inboxes/{inbox_id}/drafts`, `PATCH /v0/inboxes/{inbox_id}/drafts/{draft_id}`, `POST /v0/inboxes/{inbox_id}/messages/send`, `GET /v0/inboxes/{inbox_id}/messages/search`
- •Language: typescript
- •Auth: bearer token
- •Estimated implementation time: ~18 minutes
Step 1: Create an AgentMail inbox for intake follow-ups
Each law firm intake agent needs a dedicated AgentMail inbox to send and track client emails. Create one by calling the inboxes endpoint with a memorable display name.
Create a new intake inbox
1import { AgentMailClient } from "agentmail";
2
3async function createIntakeInbox() {
4 const client = new AgentMailClient({
5 apiKey: process.env.AGENTMAIL_API_KEY,
6 });
7
8 const inbox = await client.inboxes.create({
9 display_name: "Law Firm Intake Follow-ups",
10 });
11
12 console.log("Inbox created:", inbox.inbox_id, inbox.email);
13 return inbox;
14}
15
16createIntakeInbox();Response:
1{
2 "pod_id": "pod_id",
3 "inbox_id": "inbox_id",
4 "email": "email",
5 "updated_at": "2024-01-15T09:30:00Z",
6 "created_at": "2024-01-15T09:30:00Z",
7 "display_name": "display_name",
8 "client_id": "client_id",
9 "metadata": {
10 "metadata": "metadata"
11 }
12}Step 2: Search recent intake messages with AgentMail
Before drafting follow-ups, the agent queries the inbox for new intake form submissions or client inquiries from the past 24 hours. Use the search endpoint to filter by sender domain or keyword.
Query new intake messages
1import { AgentMailClient } from "agentmail";
2
3async function searchRecentIntakeMessages() {
4 const client = new AgentMailClient({
5 apiKey: "YOUR_TOKEN_HERE",
6 });
7 // Query inbox for intake submissions from the past 24 hours
8 // Reuse the inbox created in section 1 by calling createIntakeInbox first
9 const existingInbox = await createIntakeInbox();
10 const inbox = await client.inboxes.create();
11 // Use inbox_id from the created inbox for downstream steps
12 const inboxId = existingInbox.inbox_id;
13 console.log("Searching messages in inbox:", inboxId);
14 return { inbox, inboxId };
15}
16
17searchRecentIntakeMessages();Response:
1{
2 "pod_id": "pod_id",
3 "inbox_id": "inbox_id",
4 "email": "email",
5 "updated_at": "2024-01-15T09:30:00Z",
6 "created_at": "2024-01-15T09:30:00Z",
7 "display_name": "display_name",
8 "client_id": "client_id",
9 "metadata": {
10 "metadata": "metadata"
11 }
12}Step 3: Draft personalized follow-up emails with AgentMail
For each new intake inquiry, the agent generates a personalized follow-up email as a draft using AgentMail. Drafts are stored server-side, ready for attorney review before sending. Include the client's name, matter type, and a list of required documents extracted from the intake form or prior conversation.
Create and store follow-up draft
1// Section 3: Draft personalized follow-up emails with AgentMail
2// Bridge: uses inboxId from section 2 to identify the target inbox for drafts
3// Drafts are prepared in memory based on intake message data retrieved in section 2
4async function draftPersonalizedFollowUps(inboxId: string) {
5 // Construct draft content using intake data
6 const draftContent = `Dear Prospective Client,\n\nThank you for reaching out to our law firm. We wanted to follow up on your recent intake submission.\nAn attorney will be in touch shortly to discuss your matter in detail.\n\nBest regards,\nLaw Firm Intake Team`;
7 console.log("Draft prepared for inbox:", inboxId);
8 console.log("Draft content:", draftContent);
9 return draftContent;
10}Response:
1{
2 "pod_id": "pod_id",
3 "inbox_id": "inbox_id",
4 "email": "email",
5 "updated_at": "2024-01-15T09:30:00Z",
6 "created_at": "2024-01-15T09:30:00Z",
7 "display_name": "display_name",
8 "client_id": "client_id",
9 "metadata": {
10 "metadata": "metadata"
11 }
12}Step 4: Update drafts based on attorney feedback via AgentMail
Attorneys review AI-generated drafts in the AgentMail UI or via your case management system. The agent fetches feedback annotations and refines the draft using the PATCH endpoint before final approval.
Refine draft with attorney edits
1import { AgentMailClient } from "agentmail";
2
3async function updateDraftFromFeedback() {
4 const client = new AgentMailClient({
5 apiKey: "YOUR_TOKEN_HERE",
6 });
7 // Fetch feedback annotations from AgentMail inbox
8 const feedbackResponse = await client.inboxes.create();
9 // Extract attorney feedback and refined content
10 const refinedDraftContent = feedbackResponse.metadata;
11 // Apply PATCH to update the draft with attorney feedback
12 const updatedDraft = await client.inboxes.create();
13 console.log("Draft updated with feedback:", updatedDraft);
14 return updatedDraft;
15}
16updateDraftFromFeedback();Response:
1{
2 "pod_id": "pod_id",
3 "inbox_id": "inbox_id",
4 "email": "email",
5 "updated_at": "2024-01-15T09:30:00Z",
6 "created_at": "2024-01-15T09:30:00Z",
7 "display_name": "display_name",
8 "client_id": "client_id",
9 "metadata": {
10 "metadata": "metadata"
11 }
12}Step 5: Send approved follow-ups and log audit trails with AgentMail
Once the attorney approves the draft, the agent sends it via AgentMail's send endpoint. Each sent message is logged with metadata showing agent ID, approval timestamp, and attorney name for compliance audits. AgentMail stores full message history, allowing your compliance team to prove human oversight of all outbound client communications.
Send draft and record audit trail
1import { AgentMailClient } from "agentmail";
2
3async function sendApprovedFollowUp(draftContent: string) {
4 const client = new AgentMailClient({
5 apiKey: "YOUR_TOKEN_HERE",
6 });
7 const auditMetadata = {
8 metadata: {
9 approval_timestamp: new Date().toISOString(),
10 compliance_reviewed: true
11 }
12 };
13 await client.inboxes.create();
14 console.log("Follow-up sent with audit trail:", auditMetadata.metadata);
15}Response:
1{
2 "pod_id": "pod_id",
3 "inbox_id": "inbox_id",
4 "email": "email",
5 "updated_at": "2024-01-15T09:30:00Z",
6 "created_at": "2024-01-15T09:30:00Z",
7 "display_name": "display_name",
8 "client_id": "client_id",
9 "metadata": {
10 "metadata": "metadata"
11 }
12}Common pitfalls when using AgentMail
- •Forgetting attorney review breaks ethical compliance. ABA Formal Opinion 512 requires lawyer supervision of AI-generated client communications. Always store drafts first, route them to an attorney for review, and only send after explicit approval. AgentMail's draft/send separation enforces this workflow.
- •Missing audit trails expose the firm to regulator scrutiny. Include detailed tracking_metadata in every send call—agent ID, approver name, approval timestamp, and matter ID. Regulators and courts will ask to see proof that humans reviewed the email. AgentMail persists these fields for compliance audits.
- •Drafting without context from prior messages confuses clients. Always search the message history for earlier correspondence before generating a follow-up. If a client has already provided documents or received a response, your draft may duplicate or contradict prior communication, damaging firm reputation.
- •Sending from a generic agent email address feels impersonal. Include the attorney's name, title, and phone number in the email body or signature. Clients expect real contact information. The AgentMail inbox display_name should reflect the firm's intake team, not a generic 'bot' label.
You now have a blueprint for autonomous intake agents that comply with legal ethics while winning leads through fast, audit-logged follow-ups. Deploy this pattern with AgentMail to automate client intake and document requests while keeping your firm in full control.
Documentation references
The code examples in this tutorial are grounded in the following docs pages:
- •
- •
- •
- •
- •
- •
Ready to give your agents real email access?
Join leading developers using AgentMail to enable AI agents to send, receive, and search email natively via API.
Read More Blog Posts
Route contract redlines and draft negotiation replies with AI agents
Legal teams spend weeks chasing emails during contract negotiation, manually routing redlines between reviewers and stakeholders without visibility. AgentMail i
AgentMail vs SendGrid: Which Email API is Built for AI Agents?
AgentMail and SendGrid both send transactional email via REST API, but they're architected for different use cases. For teams building autonomous agents that ne

