Give Your GPT-4 Agents Email Capabilities

Use OpenAI's function calling to connect GPT-4 agents to MultiMail for sending, reading, and managing email with configurable human oversight.


OpenAI's API provides function calling capabilities that let GPT-4 and other models invoke external tools with structured arguments. MultiMail gives these models a complete email infrastructure layer, so your agents can send, receive, read, and reply to emails on behalf of users through well-defined function calls.

By integrating MultiMail with the OpenAI API, your agents can handle email workflows while respecting human oversight boundaries. The default gated_send mode means your GPT-4 agent drafts emails but a human approves before delivery, adding a critical safety layer that the OpenAI API itself does not provide for external tool execution.

Connect OpenAI to MultiMail by defining email functions in OpenAI's function calling format and routing calls to the MultiMail REST API. You can also use the @multimail/mcp-server for automatic tool discovery with compatible adapters.

Built for OpenAI API developers

Function Calling Compatibility

OpenAI's function calling uses JSON Schema definitions that map directly to MultiMail's API endpoints. Define send_email, check_inbox, and reply_email as functions, and GPT-4 generates structured calls with typed parameters.

Safety Layer for Autonomous Agents

OpenAI's API does not gate external tool execution. MultiMail's oversight modes add the missing safety layer — from gated_send (human approves every email) to autonomous (full agent control) — so you can deploy email agents with confidence.

Assistants API Compatible

MultiMail works with both the Chat Completions API and the Assistants API. Define email functions as tools in either API, and your agent can manage email as part of broader multi-tool workflows.

Thread and Contact Management

MultiMail tracks email threads and contacts automatically. Your OpenAI agent can retrieve conversation context with get_thread and manage relationships with search_contacts, enabling sophisticated email workflows.

MCP Server Integration

The @multimail/mcp-server package exposes email tools in the Model Context Protocol format. Use MCP adapters to automatically discover and register all MultiMail tools with your OpenAI-powered agent.


Get started in minutes

Define MultiMail Functions for OpenAI
python
from openai import OpenAI
import requests
import json

client = OpenAI()
MULTIMAIL_API = "https://api.multimail.dev/v1"
MM_HEADERS = {"Authorization": "Bearer mm_live_your_api_key"}

email_functions = [
    {
        "type": "function",
        "function": {
            "name": "send_email",
            "description": "Send an email. In gated_send mode, queues for human approval.",
            "parameters": {
                "type": "object",
                "properties": {
                    "mailbox_id": {"type": "string", "description": "Mailbox to send from"},
                    "to": {"type": "string", "description": "Recipient email"},
                    "subject": {"type": "string", "description": "Subject line"},
                    "body": {"type": "string", "description": "Email body"}
                },
                "required": ["mailbox_id", "to", "subject", "body"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "check_inbox",
            "description": "Check inbox for recent messages.",
            "parameters": {
                "type": "object",
                "properties": {
                    "mailbox_id": {"type": "string", "description": "Mailbox to check"},
                    "limit": {"type": "integer", "description": "Max messages", "default": 10}
                },
                "required": ["mailbox_id"]
            }
        }
    }
]

Create function definitions for email tools using OpenAI's function calling schema.

Build an Email Agent with Function Calling
python
def execute_function(name, args):
    if name == "send_email":
        resp = requests.post(f"{MULTIMAIL_API}/send", headers=MM_HEADERS, json=args)
    elif name == "check_inbox":
        resp = requests.get(
            f"{MULTIMAIL_API}/mailboxes/{args[&"cm">#039;mailbox_id']}/inbox",
            headers=MM_HEADERS, params={"limit": args.get("limit", 10)}
        )
    elif name == "reply_email":
        resp = requests.post(f"{MULTIMAIL_API}/reply", headers=MM_HEADERS, json=args)
    else:
        return json.dumps({"error": f"Unknown function: {name}"})
    return json.dumps(resp.json())

def run_email_agent(user_message, mailbox_id):
    messages = [
        {"role": "system", "content": f"You are an email assistant for mailbox {mailbox_id}. "
         f"Emails are sent in gated_send mode and queue for human approval."},
        {"role": "user", "content": user_message}
    ]
    while True:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=email_functions
        )
        msg = response.choices[0].message
        if msg.tool_calls:
            messages.append(msg)
            for tool_call in msg.tool_calls:
                result = execute_function(
                    tool_call.function.name,
                    json.loads(tool_call.function.arguments)
                )
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": result
                })
        else:
            return msg.content

print(run_email_agent("Check my inbox and summarize unread messages", "mbx_abc123"))

Create an agentic loop where GPT-4 calls MultiMail functions and processes results.

Parallel Function Calls for Email Workflows
python
"cm"># GPT-4 may return multiple tool_calls in one response
"cm"># Example: checking inbox AND searching contacts simultaneously

search_contacts_fn = {
    "type": "function",
    "function": {
        "name": "search_contacts",
        "description": "Search contacts by name or email.",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "Search term"}
            },
            "required": ["query"]
        }
    }
}

all_functions = email_functions + [search_contacts_fn]

def execute_function(name, args):
    endpoints = {
        "send_email": lambda: requests.post(f"{MULTIMAIL_API}/send", headers=MM_HEADERS, json=args),
        "check_inbox": lambda: requests.get(
            f"{MULTIMAIL_API}/mailboxes/{args[&"cm">#039;mailbox_id']}/inbox",
            headers=MM_HEADERS, params={"limit": args.get("limit", 10)}
        ),
        "search_contacts": lambda: requests.get(
            f"{MULTIMAIL_API}/contacts/search",
            headers=MM_HEADERS, params={"q": args["query"]}
        )
    }
    resp = endpoints.get(name, lambda: None)()
    return json.dumps(resp.json()) if resp else json.dumps({"error": "Unknown"})

GPT-4 can call multiple functions in parallel. Handle parallel check_inbox and search_contacts calls.

TypeScript / Node.js Integration
typescript
import OpenAI from 'openai';

const openai = new OpenAI();
const MULTIMAIL_API = 'https://api.multimail.dev/v1';
const MM_HEADERS = { Authorization: 'Bearer mm_live_your_api_key' };

const tools: OpenAI.Chat.Completions.ChatCompletionTool[] = [
  {
    type: 'function',
    function: {
      name: 'send_email',
      description: 'Send an email. In gated_send mode, queues for approval.',
      parameters: {
        type: 'object',
        properties: {
          mailbox_id: { type: 'string' },
          to: { type: 'string' },
          subject: { type: 'string' },
          body: { type: 'string' }
        },
        required: ['mailbox_id', 'to', 'subject', 'body']
      }
    }
  }
];

async function executeFunction(name: string, args: Record<string, unknown>) {
  const resp = await fetch(`${MULTIMAIL_API}/send`, {
    method: 'POST',
    headers: { ...MM_HEADERS, 'Content-Type': 'application/json' },
    body: JSON.stringify(args)
  });
  return resp.json();
}

const response = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Send a meeting reminder to [email protected]' }],
  tools
});

Use the OpenAI Node.js SDK with MultiMail's REST API for TypeScript projects.


Step by step

1

Create a MultiMail Account and API Key

Sign up at multimail.dev, create a mailbox, and generate an API key from your dashboard. Your key will start with mm_live_.

2

Install Dependencies

Install the OpenAI Python SDK and requests library for calling the MultiMail API.

bash
pip install openai requests
3

Define Email Function Schemas

Create function definitions for send_email, check_inbox, and other MultiMail operations using OpenAI's tools format with JSON Schema parameters.

4

Build the Agent Loop

Implement a loop that sends messages to GPT-4, checks for tool_calls in the response, executes functions against MultiMail, and returns results as tool messages.

bash
response = client.chat.completions.create(
    model="gpt-4o",
    tools=email_functions,
    messages=messages
)
5

Approve Pending Emails

If your mailbox uses gated_send mode (the default), review and approve pending emails in the MultiMail dashboard before they are delivered.


Common questions

Can I use the Assistants API with MultiMail?
Yes. Define MultiMail email functions as tools when creating your Assistant. The Assistants API manages conversation state and tool execution, so you can build persistent email agents that remember context across sessions. Define the same function schemas used with Chat Completions.
What happens when GPT-4 sends an email in gated_send mode?
In gated_send mode, the MultiMail API returns a success response with a pending status. The email is queued for human review in the MultiMail dashboard. Once approved, it is delivered. Your agent can check the status of pending emails using the list_pending endpoint.
Does GPT-4 support parallel email function calls?
Yes. GPT-4 can return multiple tool_calls in a single response. For example, it might call check_inbox and search_contacts simultaneously. Your execution loop should handle all tool calls and return all results before the next model invocation.
How do I handle email attachments?
The MultiMail API supports attachments via the send and reply endpoints. Pass attachments as base64-encoded content in the request body. Your function definition should include an optional attachments parameter that GPT-4 can populate when the user requests it.
Is there rate limiting on the MultiMail API?
Rate limits depend on your plan tier. The Starter (free) plan allows 200 emails per month, while paid plans range from 5,000 to 150,000. The API returns standard 429 responses when limits are reached, which your agent loop can handle with retry logic.

Explore more

The only agent email with a verifiable sender

Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.