# saci.cc > Get a temporary email address in one click and read incoming messages right away. Free, no account needed, and emails are deleted after a day. Need an email to sign up somewhere but don't want to give out yours? Grab an address here and watch the messages come in. **What is a temporary email?** It's an address you use once and forget about. It's handy for signing up on websites, downloading a file or trying out a service without handing over your personal email or filling your inbox with spam. **How long are emails kept?** About a day. After that they're deleted for good, along with everything that arrived at the address. **Can I send email from saci.cc?** No. Addresses can only receive messages. **Can anyone else read my emails?** There's no password, so anyone who knows the address can see its inbox. Addresses are long and random, which makes them hard to guess, but don't use them for anything sensitive. **Is it free?** Yes, and you don't need an account. ## API A simple HTTP API, with no sign-up and no auth, to create temporary addresses and read the emails they get. Handy for end-to-end tests of sign-up and password reset flows. Base URL: `https://saci.cc/api` ### Quick start ```bash # 1. Create an address curl -X POST https://saci.cc/api/addresses # 2. Wait for an email (up to 25 s) curl "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails?wait=25" # 3. Read the email curl "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails/{messageId}" ``` ```javascript // 1. Create an address const { address } = await fetch("https://saci.cc/api/addresses", { method: "POST" }).then((r) => r.json()); // 2. Wait for an email (up to 25 s) const { emails } = await fetch(`https://saci.cc/api/addresses/${address}/emails?wait=25`).then((r) => r.json()); // 3. Read the email const email = await fetch(`https://saci.cc/api/addresses/${address}/emails/${emails[0].messageId}`).then((r) => r.json()); console.log(email.subject, email.text); ``` ```python import requests # 1. Create an address address = requests.post("https://saci.cc/api/addresses").json()["address"] # 2. Wait for an email (up to 25 s) emails = requests.get(f"https://saci.cc/api/addresses/{address}/emails", params={"wait": 25}).json()["emails"] # 3. Read the email email = requests.get(f"https://saci.cc/api/addresses/{address}/emails/{emails[0]['messageId']}").json() print(email["subject"], email["text"]) ``` ### Create address: `POST /addresses` Generates a new random address. Nothing to register: any email sent to it is available for about a day. - `name` (query): Optional. Address name (3 to 32 letters, numbers, dots, dashes or underscores). Random if omitted. ```bash curl -X POST https://saci.cc/api/addresses ``` Response (201): ```json { "address": "a1b2c3d4e5f60718@saci.cc" } ``` ### List emails: `GET /addresses/{address}/emails` Lists received emails, newest first. With wait, the request stays open until an email arrives (25 seconds at most), so you don't have to poll in a loop. - `address` (path, required): Full address, e.g. a1b2c3d4e5f60718@saci.cc - `wait` (query): Seconds to wait for an email, up to 25. Without it, the response is immediate. - `after` (query): ISO 8601 date. With wait, waits for an email received after it. ```bash curl "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails?wait=25" ``` Response (200): ```json { "emails": [ { "messageId": "0100019a2b3c4d5e-6f7a8b9c-...", "from": "GitHub ", "subject": "[GitHub] Please verify your email address", "receivedAt": "2026-10-20T15:30:00.000Z" } ] } ``` ### Read email: `GET /addresses/{address}/emails/{messageId}` Returns the email's content as HTML and plain text. - `address` (path, required): Full address, e.g. a1b2c3d4e5f60718@saci.cc - `messageId` (path, required): The messageId from the list ```bash curl "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails/{messageId}" ``` Response (200): ```json { "messageId": "0100019a2b3c4d5e-6f7a8b9c-...", "from": "GitHub ", "subject": "[GitHub] Please verify your email address", "receivedAt": "2026-10-20T15:30:00.000Z", "html": "

Your code is 482913

", "text": "Your code is 482913", "attachments": [ { "index": 0, "filename": "invoice.pdf", "contentType": "application/pdf", "size": 48213, "inline": false, "url": "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails/0100019a2b3c4d5e-6f7a8b9c-.../attachments/0" } ] } ``` ### Download attachment: `GET /addresses/{address}/emails/{messageId}/attachments/{index}` Redirects to a download link for the attachment, valid for a few minutes. The index comes from the email's attachments list. - `address` (path, required): Full address, e.g. a1b2c3d4e5f60718@saci.cc - `messageId` (path, required): The messageId from the list - `index` (path, required): Position of the attachment in the attachments list, starting at 0 ```bash curl -L -OJ "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails/{messageId}/attachments/0" ``` Response: 302 (redirect to the download link) ### Delete email: `DELETE /addresses/{address}/emails/{messageId}` Deletes one email and its attachments. Returns 204, or 404 if it doesn't exist. - `address` (path, required): Full address, e.g. a1b2c3d4e5f60718@saci.cc - `messageId` (path, required): The messageId from the list ```bash curl -X DELETE "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails/{messageId}" ``` Response: 204 (no body) ### Empty inbox: `DELETE /addresses/{address}/emails` Deletes every email in the inbox and says how many there were. - `address` (path, required): Full address, e.g. a1b2c3d4e5f60718@saci.cc ```bash curl -X DELETE "https://saci.cc/api/addresses/a1b2c3d4e5f60718@saci.cc/emails" ``` Response (200): ```json { "deleted": 3 } ``` ### Limits and errors - 120 requests per minute per IP. Above that you get a 429, with a Retry-After header saying how many seconds to wait. - wait goes up to 25 seconds per request. If time runs out, you get a normal response with the current list (which may be empty). - Emails are deleted about a day after they arrive. After that, reading one returns 404. - An invalid address or parameter returns 400. - There's no password: anyone who knows an address can read its inbox. Don't use it for anything sensitive. ## MCP server Connect saci.cc to your AI agent and it can create temporary emails, wait for messages and read verification codes on its own. Useful for end-to-end tests of sign-up flows or for creating test accounts. Server URL: `https://saci.cc/api/mcp`. Streamable HTTP transport, no auth. saci.cc gives you disposable email inboxes. Typical flow: create_inbox, use the address where an email is needed, then get_verification_code (for codes) or wait_for_email + get_email (for links and content). Waits are capped at 25 seconds per call; call again to keep waiting. Emails are deleted about a day after they arrive, and anyone who knows an address can read its inbox, so don't use it for anything sensitive. ### Connecting Claude Code: ```bash claude mcp add --transport http saci https://saci.cc/api/mcp ``` Claude (app or claude.ai): Settings → Connectors → Add custom connector, then paste `https://saci.cc/api/mcp`. Cursor (`~/.cursor/mcp.json`): ```json { "mcpServers": { "saci": { "url": "https://saci.cc/api/mcp" } } } ``` VS Code (`.vscode/mcp.json`): ```json { "servers": { "saci": { "type": "http", "url": "https://saci.cc/api/mcp" } } } ``` Other clients: ```json { "mcpServers": { "saci": { "type": "http", "url": "https://saci.cc/api/mcp" } } } ``` ### Tools ### `create_inbox` Create a new disposable email address. Use it wherever an email is needed (sign-ups, password resets, tests), then read what arrives with wait_for_email or get_verification_code. Emails are deleted about a day after they arrive. Pass a name to pick the address (e.g. signup-test), otherwise it's random. Picked names are easy to guess, so anyone could read that inbox. - `name` (string, optional): Optional address name: 3 to 32 letters, numbers, dots, dashes or underscores. Random if omitted. ### `list_emails` List the emails an inbox has received, newest first (sender, subject, date and message_id). - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc ### `wait_for_email` Wait until an email arrives in the inbox and return it (without the body; use get_email for that). Returns right away if a matching email is already there. Filters are case-insensitive substrings. - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc - `timeout_seconds` (integer, optional, 0 to 25): How long to wait for a new email, in seconds (0 to 25, default 25). Call again to keep waiting. - `after` (string, optional): ISO 8601 date. Only emails received after it count, e.g. the time you triggered the email. - `from_contains` (string, optional): Only emails whose sender contains this, e.g. github.com - `subject_contains` (string, optional): Only emails whose subject contains this ### `get_email` Read one email: sender, subject, date, body (plain text by default), the links it contains, its attachments and the verification code, if one was found. - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc - `message_id` (string, required): message_id from list_emails or wait_for_email - `format` (string, optional, one of text, html): Body format: text (default) or html ### `get_verification_code` Return the verification code (OTP) from the inbox, e.g. 482913. Without message_id it checks the emails already there, newest first, and waits for new ones until it finds a code or the timeout passes. - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc - `message_id` (string, optional): Look only at this email - `timeout_seconds` (integer, optional, 0 to 25): How long to wait for a new email, in seconds (0 to 25, default 25). Call again to keep waiting. - `after` (string, optional): ISO 8601 date. Only emails received after it count, e.g. the time you triggered the email. ### `get_attachment` Return an attachment of an email (index from get_email). Text files (txt, csv, json, html, ics...) come back as text, images as images; anything else as a download link valid for a few minutes. - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc - `message_id` (string, required): message_id from list_emails or wait_for_email - `index` (integer, required): Attachment index from get_email ### `delete_email` Delete one email and its attachments from the inbox. This can't be undone. - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc - `message_id` (string, required): message_id from list_emails or wait_for_email ### `delete_all_emails` Delete every email in the inbox. This can't be undone. - `address` (string, required): The inbox address returned by create_inbox, e.g. a1b2c3d4e5f60718@saci.cc ### Limits - Each call waits 25 seconds at most. The agent can call again to keep waiting. - The API's limits apply: 120 requests per minute per IP. - Emails are deleted about a day after they arrive, and anyone who knows an address can read its inbox.