# MailFlat > Permanent, end-to-end encrypted email inboxes you can create from code. Built for > automated testing, CI pipelines and AI agents: open an inbox over the API, read the > one-time code your app just sent, and let messages expire on their own. The inbox and its address are permanent. They stay until you delete them. Only the messages inside expire, on a retention window you choose (2 hours on the free plan, up to 30 days on paid plans). This is not a throwaway or temporary address service. Authentication: account API keys (`mf_live_...`) go in the `X-API-Key` header and are accepted by the automation API at `https://mailflat.net/api/v1`. The session API used by the web app takes a bearer token instead; the two are not interchangeable. ## Instructions for AI agents - Read https://mailflat.net/llms-full.txt first. It is this entire documentation set as one plain-text file, in reading order, so you do not have to crawl the pages below one by one. - Any page listed here can also be fetched as raw markdown by adding `.md` to its URL: https://mailflat.net/docs/quickstart.md returns markdown, https://mailflat.net/docs/quickstart returns HTML. - Base URL for everything you can do programmatically: `https://mailflat.net/api/v1`. Send your key as `X-API-Key: mf_live_...` on every request. - Getting a key needs a human once: MailFlat is in invited early access, so public sign-up is not open yet. Request access at https://mailflat.net/signup, then create the key under Agents -> API keys in the dashboard and hand it to the agent as an environment variable. There is no way for an agent to issue itself a key today. - The shortest useful loop is four calls: `POST /inboxes` to open an address, let your app mail it, `GET /inboxes/{address}/latest` until `otp_code` is not null, then `DELETE /inboxes/{address}`. One-time codes are extracted server-side, so you never need a regex over the message body. - Do not poll faster than every 2-3 seconds, and always set your own deadline: a poll loop without a timeout turns a missing email into a hung job. - Prefer an official client over raw HTTP if your runtime has one: `mailflat` (PyPI), `@mailflat/sdk` (npm), `mailflat-mcp` (MCP server, `uvx mailflat-mcp`), `@mailflat/ai-sdk` (Vercel AI SDK), `mailflat.langchain` (LangChain tools). - Encrypted inboxes are deliberately unreadable by the API: `otp_code`, body and headers come back null there. Agent inboxes are always plain text for this reason. ## Full documentation as one file - [Everything, as plain text](https://mailflat.net/llms-full.txt): the whole documentation site in one request, generated from the same source as the pages below ## Installable skills If your runtime supports agent skills, install them instead of reading this file every time. They carry the same rules plus the gotchas that are not obvious from the method signatures. ```bash npx skills add MailFlat/mailflat-skills ``` - [The core skill, hosted](https://mailflat.net/agent/skill.md): same content as `mailflat` in that repo - The set: `mailflat` (start here), `mailflat-otp`, `mailflat-send`, `mailflat-inboxes`, `mailflat-mcp` ## Getting Started - [Quickstart: create your first email inbox](https://mailflat.net/docs/quickstart): Create a permanent, automation-ready email inbox in under a minute, then read the first message and its one-time code. No credit card, no setup. - [Dashboard tour](https://mailflat.net/docs/dashboard-tour): Where everything lives in MailFlat: the three modes, the three inbox pools, and what each menu does. ## Languages - [Email testing in every language](https://mailflat.net/docs/automation): Official clients for Python, JavaScript, TypeScript and Java, plus copy-paste REST helpers for Ruby, PHP, Go, C# and curl. - [Email testing with Python](https://mailflat.net/docs/automation/python): The official Python client wraps the REST API in two calls: open an inbox, wait for the code. Works in pytest, unittest, Robot Framework or a plain script. - [Email testing with JavaScript](https://mailflat.net/docs/automation/javascript): Zero dependencies, built on the runtime's own fetch. Drop it into Jest, Vitest, Playwright, Cypress or a Node script. - [Email testing with TypeScript](https://mailflat.net/docs/automation/typescript): The same package as JavaScript, with types shipped in the box: Message, CreateInboxOptions, WaitOptions and typed errors. - [Email testing with Java](https://mailflat.net/docs/automation/java): Built on java.net.http, no HTTP dependency of its own. Made for Selenium and JUnit suites that need a real address per test. - [Email testing with Ruby](https://mailflat.net/docs/automation/ruby): No gem yet, and none needed: the API is six endpoints and Ruby ships net/http. Copy the helper below into spec/support and you are done. - [Email testing with PHP](https://mailflat.net/docs/automation/php): No Composer package required: the helper below uses the bundled cURL extension. Works the same in PHPUnit, Pest or Laravel Dusk. - [Email testing with Go](https://mailflat.net/docs/automation/go): Standard library only: net/http and encoding/json. One small client type covers every endpoint you need in a test. - [Email testing with C# and .NET](https://mailflat.net/docs/automation/dotnet): HttpClient plus System.Net.Http.Json, no package to install. Fits xUnit, NUnit and SpecFlow suites driving Selenium or Playwright. - [Email testing from the command line](https://mailflat.net/docs/automation/curl): Every endpoint in one terminal. Useful for smoke checks, CI shell steps, and for seeing exactly what your language client sends. ## Test frameworks & CI - [Using MailFlat with Playwright](https://mailflat.net/docs/automation/playwright): Give every Playwright test its own real inbox, read the verification code your app actually sent, and finish the signup flow end to end. - [Using MailFlat with Cypress](https://mailflat.net/docs/automation/cypress): Read real verification emails from a Cypress test by moving the API calls into a Node task, where network access belongs. - [Using MailFlat with Selenium](https://mailflat.net/docs/automation/selenium): Fill a signup form with a real address, then type the code that really arrived, in Java or Python, next to the WebDriver calls you already have. - [Email testing with pytest](https://mailflat.net/docs/automation/pytest): A conftest fixture that gives every test its own inbox and cleans up afterwards, whether the test passed or not. - [Email testing with Jest](https://mailflat.net/docs/automation/jest): Open an inbox in beforeEach, delete it in afterEach, and give Jest a timeout long enough for real mail to arrive. - [Email testing with Vitest](https://mailflat.net/docs/automation/vitest): The same flow as Jest with typed fixtures: Vitest picks up the client's TypeScript types with no extra setup. - [Using MailFlat with Cucumber](https://mailflat.net/docs/automation/cucumber): Keep the mailbox out of the feature file: the scenario says a user signs up and enters the code, the step definitions do the work. - [Using MailFlat with Robot Framework](https://mailflat.net/docs/automation/robot-framework): Wrap the Python client in a small keyword library and your suites get New Inbox and Wait For Otp as ordinary Robot keywords. - [Using MailFlat with WebdriverIO](https://mailflat.net/docs/automation/webdriverio): Hooks in wdio.conf.js open and close the inbox; the spec just reads the address off the global. - [Using MailFlat with TestCafe](https://mailflat.net/docs/automation/testcafe): TestCafe fixtures map cleanly onto inbox lifecycle: beforeEach opens one, afterEach deletes it. - [Using MailFlat with Postman](https://mailflat.net/docs/automation/postman): Chain three requests (create an inbox, trigger your flow, read the code) with the address carried between them in a collection variable. - [Email testing in GitHub Actions](https://mailflat.net/docs/automation/github-actions): Give every workflow run its own inbox, pass the address to the suite as an environment variable, and sweep it up even when the job fails. - [Email testing in GitLab CI](https://mailflat.net/docs/automation/gitlab-ci): The same per-run inbox pattern in .gitlab-ci.yml, with the key stored as a masked CI/CD variable and teardown in after_script. ## AI agents & assistants - [MailFlat MCP server: an inbox for any AI client](https://mailflat.net/docs/ai/mcp): Run the MailFlat MCP server and any Model Context Protocol client gains real inbox tools: open an address, wait for the one-time code, send mail, clean up. - [Using MailFlat with Claude Desktop](https://mailflat.net/docs/ai/claude-desktop): Add the MailFlat MCP server to Claude Desktop so Claude can open a real inbox, read the verification code your app just sent, and clean up afterwards. - [Using MailFlat with Cursor](https://mailflat.net/docs/ai/cursor): Give Cursor's agent a real inbox: add the MailFlat MCP server to your project or user config and it can register test accounts and read the codes on its own. - [Using MailFlat with LangChain](https://mailflat.net/docs/ai/langchain): MailFlatToolkit turns the Python SDK into LangChain tools, so an agent can open inboxes and read verification codes as part of its normal tool loop. - [Using MailFlat with the Vercel AI SDK](https://mailflat.net/docs/ai/vercel-ai-sdk): mailflatToolSuite() spreads ready-made inbox tools into any Vercel AI SDK call, so the model can create an address, wait for the code and finish a signup on its own. - [Using MailFlat with the OpenAI Agents SDK](https://mailflat.net/docs/ai/openai-agents): There is no MailFlat package for the OpenAI Agents SDK and none is needed: attach the MCP server, or wrap the Python client in two function tools. - [Recipe: let an agent sign itself up for a service](https://mailflat.net/docs/ai/agent-signup-recipe): The full pattern for an autonomous signup: one labelled inbox per service, a real verification code, an audit trail, and the rules about where not to point it. ## Common test cases - [Extracting one-time codes from email](https://mailflat.net/docs/guides/otp-codes): MailFlat pulls the verification code out of the message for you and hands it over as a field, so your test never runs a regex against an email body. - [Extracting and testing links in email](https://mailflat.net/docs/guides/links): Every clickable link in a message is pulled out for you as an ordered, de-duplicated list, so magic-link and password-reset flows are one assertion away. - [Asserting on HTML email content](https://mailflat.net/docs/guides/html-content): Check the rendered half of a message: the HTML body is delivered exactly as it arrived, so you can assert on markup, buttons and merge fields. - [Asserting on plain text email content](https://mailflat.net/docs/guides/plain-text): The text part of a message, exactly as sent. Simpler to assert on than HTML, and the part most transactional senders get wrong. - [Testing subject, sender, recipient and timestamps](https://mailflat.net/docs/guides/message-properties): The envelope around the body: who sent it, exactly which address it reached, what the subject line said and when it landed. - [Filtering mail with plus-addressing tags](https://mailflat.net/docs/guides/tags): One inbox, many senders: add a plus tag to the address and MailFlat records it as a field you can filter on. - [Waiting for email without flaky tests](https://mailflat.net/docs/guides/waiting-and-timeouts): Mail is asynchronous, so every email test waits for something. The difference between a solid suite and a flaky one is how that wait is written. - [Testing your own inbound email handling](https://mailflat.net/docs/guides/sending-email): Point it the other way: send real mail from a MailFlat address and check that your application handles what arrives. - [Testing a sequence of emails](https://mailflat.net/docs/guides/multiple-messages): Some flows send more than one message: sign up, then welcome, then a receipt. Read the whole thread and assert on the order. - [Testing email attachments](https://mailflat.net/docs/guides/attachments): Files arrive as metadata you can assert on and download from one endpoint, so a PDF invoice test is two calls, not a MIME parser. Sending files works too, so a test can make its own fixture. - [Checking the spam score of a message](https://mailflat.net/docs/guides/spam-filtering): Every incoming message is run through SpamAssassin, so a test can assert that your mail lands under the threshold instead of finding out from an angry customer. - [Reading raw email headers](https://mailflat.net/docs/guides/message-headers): Every header the sender set comes back as a dictionary, so you can assert on Message-ID, follow the Received chain, or prove which relay signed the mail. ## Using MailFlat - [Inboxes and email addresses](https://mailflat.net/docs/inboxes): How MailFlat addresses are built, why the address is permanent while messages expire, and how tags let one inbox serve many senders. - [Reading and sending mail](https://mailflat.net/docs/reading-and-sending-mail): Read incoming mail in four views, extract one-time codes automatically, block trackers, and send or reply from your inbox. - [Plans and message retention](https://mailflat.net/docs/plans-and-retention): Retention is the only thing that expires. See how each plan sets the retention ceiling and monthly quota, and how to change plan. - [Custom domains (BYOD): use your own domain](https://mailflat.net/docs/custom-domains): Receive mail on your own domain with MailFlat. DNS records, verification, and the provider-specific gotchas for Namecheap, Cloudflare and Route 53. - [Agents and Testing modes](https://mailflat.net/docs/agents-and-testing): Which mode to use for API-created inboxes versus throwaway test inboxes, and how to audit what an automated agent did. - [Troubleshooting email delivery, OTP and API errors](https://mailflat.net/docs/troubleshooting): The message never arrived, no OTP was extracted, 401 with a valid key, 429, domain verification stuck: causes and fixes. ## Authentication - [API keys and authentication](https://mailflat.net/docs/api-keys): Account keys versus inbox keys, the five permissions a key can carry, how to create and rotate keys, and what a 401 or 403 is telling you. ## API References - [Session API reference](https://mailflat.net/docs/api/session-api): The session-authenticated REST API behind the MailFlat web app: endpoints, status codes, rate limits and quota behaviour. - [Agent API and MCP reference](https://mailflat.net/docs/api/agent-api): The /api/v1 REST API for automation and AI agents: create inboxes, poll for one-time codes, send mail, plus the MCP server tools. - [SDKs and libraries: Python, JavaScript, Java, MCP](https://mailflat.net/docs/sdks): Official MailFlat clients for Python, JavaScript/TypeScript and Java, plus MCP, LangChain and Vercel AI SDK integrations. Install and first call. - [Recipes: pytest, Playwright and GitHub Actions](https://mailflat.net/docs/recipes): Copy-paste patterns: a fresh inbox per test with pytest, an end-to-end signup spec in Playwright, CI teardown, and an AI agent with its own inbox. ## Guides - [End-to-end encryption](https://mailflat.net/docs/end-to-end-encryption): How MailFlat encrypts messages in your browser, how to turn it on and off without losing mail, and why encrypted inboxes cannot expose OTP codes. - [Webhooks: push incoming email to your endpoint](https://mailflat.net/docs/webhooks): Push incoming mail to your own endpoint instead of polling: registration, payload shape, signature verification and retry behaviour. - [Email testing in CI with isolated inboxes](https://mailflat.net/docs/testing-and-ci): Give every CI run its own real inbox: the four API calls, parallel shards, teardown, and how to keep an end-to-end suite fast and honest. ## DNS provider guides - [Connect your domain: DNS records by provider](https://mailflat.net/docs/dns): The five DNS records MailFlat needs, written out for eleven panels: Cloudflare, Hetzner, Namecheap, GoDaddy, Route 53, Porkbun, Vercel, IONOS, Squarespace, Gandi and Hostinger. ## Optional - [Email testing API](https://mailflat.net/email-testing-api): what the product does, for people who have not used it yet - [Email for AI agents](https://mailflat.net/email-for-ai-agents): the agent use case in plain terms - [MCP email tool](https://mailflat.net/mcp-email-tool): the Model Context Protocol server - [Privacy policy](https://mailflat.net/privacy) - [Terms](https://mailflat.net/terms)