# Introduction

> Build on Maylee, the AI email client. Read, search, triage and send email across every mailbox of a workspace, from your own code or from an AI agent.

Source: https://docs.maylee.app/

Maylee connects Gmail, Microsoft 365 and IMAP mailboxes in one workspace, and sorts them with AI. This site documents the two ways to drive a workspace from outside the app:

- [REST API](/api-reference): List, search and read email, label and triage it, prepare drafts or send, and configure labels, AI label rules, views and filters.

- [MCP server](/mcp): Connect Claude, ChatGPT, Cursor or any MCP client to a workspace, with OAuth and per-connection permissions.

## The REST API

```txt
Base URL        https://api.maylee.app/api/v1
Authentication  Authorization: Bearer mk_...
Content type    application/json
```

The machine-readable reference is the [OpenAPI document](/openapi.json), also served without authentication on `GET https://api.maylee.app/api/v1/openapi.json`, so that you can generate a client before you even have a key.

## Quickstart

### 1. Create an API key

In the Maylee app, open **Settings**, then **API keys**, and create a key in the **Maylee API Key** section. Give it the `read` scope for this quickstart. The secret starts with `mk_` and is shown **once**: copy it now. See [Authentication](/authentication) for scopes and the separate permission to send emails.

```bash
export MAYLEE_KEY="mk_..."
```

### 2. List your mailboxes

Every request carries the key as a Bearer token. The workspace comes from the key: no URL carries a workspace identifier.

**cURL**

```bash  
curl https://api.maylee.app/api/v1/mailboxes \
  -H "Authorization: Bearer $MAYLEE_KEY"
```

**JavaScript**

```js
const response = await fetch('https://api.maylee.app/api/v1/mailboxes', {
  headers: { Authorization: `Bearer ${process.env.MAYLEE_KEY}` },
})
const { items } = await response.json()
console.log(items)
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://api.maylee.app/api/v1/mailboxes",
    headers={"Authorization": f"Bearer {os.environ['MAYLEE_KEY']}"},
)
print(response.json()["items"])
```

```json
{
  "items": [
    {
      "id": "cmbx1a2b3c4d5e6f7g8h9i0j",
      "email": "contact@your-company.com",
      "name": "Contact",
      "picture": null,
      "provider": "GOOGLE",
      "isActive": true,
      "createdAt": "2026-06-02T09:14:31.000Z",
      "lastSyncAt": "2026-08-25T14:02:11.000Z",
      "syncError": null,
      "backwardSyncComplete": true
    }
  ]
}
```

Keep the `id`: sending needs a `mailboxId`, and most filters use it.

### 3. Read the latest emails

**cURL**

```bash  
curl -G https://api.maylee.app/api/v1/emails \
  -H "Authorization: Bearer $MAYLEE_KEY" \
  --data-urlencode 'mailboxId=cmbx1a2b3c4d5e6f7g8h9i0j' \
  --data-urlencode 'folderType=INBOX' \
  --data-urlencode 'limit=10'
```

**JavaScript**

```js
const params = new URLSearchParams({
  mailboxId: 'cmbx1a2b3c4d5e6f7g8h9i0j',
  folderType: 'INBOX',
  limit: '10',
})
const response = await fetch(`https://api.maylee.app/api/v1/emails?${params}`, {
  headers: { Authorization: `Bearer ${process.env.MAYLEE_KEY}` },
})
const { items, nextCursor } = await response.json()
```

**Python**

```python
response = requests.get(
    "https://api.maylee.app/api/v1/emails",
    headers={"Authorization": f"Bearer {os.environ['MAYLEE_KEY']}"},
    params={"mailboxId": "cmbx1a2b3c4d5e6f7g8h9i0j", "folderType": "INBOX", "limit": 10},
)
page = response.json()
```

You get a page of emails, most recent first, with sender, recipients, subject, preview snippet and labels. Bodies are fetched on demand with [`GET /emails/{emailId}/body`](/api-reference/emails/get-email-body). Continue with [Common tasks](/common-tasks) to reply in a thread, prepare a draft for review, or let Maylee classify email for you.

## Five things to know

**The workspace comes from the key, never from the URL.** A key only reaches the data of the workspace it was created in, even if the URL is forged.

**Session cookies are never accepted** on `/api/v1`. Only `Authorization: Bearer mk_...` works, which makes the API immune to cross-site request forgery.

**The secret of a key is shown once**, at creation. Only a SHA-256 hash of it is stored: if you lose it, create a new key.

**Making email leave the workspace needs two permissions**: the `write` scope and the **Send emails** option of the key. That covers sending, auto-forward rules and auto-reply. A key that classifies email should not be able to write to your customers if it leaks.

**Every request is bounded.** Requests per minute and per month, filter complexity, execution time and body size all have limits, and every authenticated response carries `X-RateLimit-*` headers. See [Rate limits and quotas](/rate-limits).

## For AI agents

This documentation is written to be read by agents too. Every page is available as Markdown: add `.md` to its URL, or send `Accept: text/markdown`. [`/llms.txt`](/llms.txt) lists every page with a one-line summary, and [`/llms-full.txt`](/llms-full.txt) holds the whole site, API reference and MCP tools included, in one file.
