# Temp Mail API ::u-page-hero --- orientation: horizontal --- ```bash # 1. Get available domains curl https://api.mail.tm/domains # 2. Create account curl -X POST https://api.mail.tm/accounts \ -H "Content-Type: application/json" \ -d '{"address":"user@domain.com","password":"secret"}' # 3. Get token curl -X POST https://api.mail.tm/token \ -H "Content-Type: application/json" \ -d '{"address":"user@domain.com","password":"secret"}' # 4. Fetch messages curl https://api.mail.tm/messages \ -H "Authorization: Bearer TOKEN" ``` #title Temp Mail API #description Create temporary email accounts and receive emails via REST API. No API key required. #links :::u-button --- size: xl to: https://docs.mail.tm/getting-started/authentication trailing-icon: i-heroicons-arrow-right --- Getting Started ::: :::u-button --- color: neutral size: xl target: _blank to: https://api.mail.tm trailing-icon: i-heroicons-arrow-top-right-on-square variant: outline --- OpenAPI Spec ::: :: ::u-page-section{headline="Workflow" title="How it works"} :::u-stepper --- items: - title: Fetch domains description: Get available domain names from the API. icon: i-heroicons-globe-alt - title: Create account description: Create a temporary email account with one request. icon: i-heroicons-user-plus - title: Use the address description: Sign up on sites that require email confirmation. icon: i-heroicons-envelope - title: Message arrives description: We receive it and store it for you. icon: i-heroicons-server - title: Fetch messages description: Fetch messages via the API or listen in real-time with SSE. icon: i-heroicons-inbox color: primary orientation: horizontal size: lg --- ::: :: ::u-page-section --- features: - title: No API key required description: Just call the endpoints. No signup, no tokens to start. icon: i-heroicons-bolt - title: 8 QPS rate limit description: The general quota limit is 8 queries per second (QPS) per IP address. icon: i-heroicons-clock description: Completely free. No API key, no signup, no paid tiers. headline: Pricing orientation: horizontal title: Access to the API --- :image-placeholder{icon="i-heroicons-sparkles"} :: ::u-page-section --- features: - title: No illegal activity description: Usage of our API for illegal activity is strictly prohibited. icon: i-heroicons-shield-exclamation - title: No reselling description: Don't build a paid product that just wraps our API. icon: i-heroicons-no-symbol - title: No proxy services description: Don't mirror or proxy our API under a different domain. icon: i-heroicons-document-duplicate - title: Attribution required description: If you use our API, link back to mail.tm somewhere visible. icon: i-heroicons-link reverse: true headline: Policy orientation: horizontal title: Terms of Use --- :image-placeholder{icon="i-heroicons-scale"} :: ::u-page-section --- description: The API follows the OpenAPI v3 spec. Download it or explore interactively. title: General Information --- #links :::u-button --- color: neutral target: _blank to: https://api.mail.tm/docs.jsonld trailing-icon: i-heroicons-arrow-down-tray variant: outline --- Download OpenAPI Spec ::: :::u-button --- color: neutral target: _blank to: https://api.mail.tm trailing-icon: i-heroicons-arrow-top-right-on-square variant: outline --- Interactive API Docs ::: :: # Authentication To make any request (except [account creation](https://docs.mail.tm/api/accounts#post-accounts) and [/domains](https://docs.mail.tm/api/domains)) you need a bearer token. No API key is needed — just create an account and request a token. > *How to get it?* You need to make a ***POST*** request to the ***/token*** path. ## Request **Body** | Name | Type | Description | | -------- | ------ | ---------------------------------------------- | | address | string | Account's address. Example: | | password | string | Account's password. | **Params** *None* ## Response ```json { "id": "string", "token":"string" } ``` Use this token as ```shell "Authorization":"Bearer TOKEN" ``` In every request! ::note Remember: You should first create the account and then get the token! :: # Error Handling ## Successful Generally, the request is successful when the response code is 200, 201 or 204 (You could also check if the code is between 200 and 204) ## Unsuccessful Usually, when the request has an error the code is between 400 and 430. **Bad request 400:** Something in your payload is missing! Or, the payload isn't there at all. **Unauthorized 401:** Your token isn't correct (Or the headers hasn't a token at all!). Remember, every request (Except [POST /accounts](https://docs.mail.tm/api/accounts#post-accounts) and [POST /token](https://docs.mail.tm/getting-started/authentication)) should be authenticated with a Bearer token! **Not found 404:** You're trying to access an account that doesn't exist? Or maybe reading a non-existing message? Go check that! **Method not allowed 405:** Maybe you're trying to ***GET*** a ***/token*** or ***POST*** a ***/messages***. Check the path you're trying to make a request to and check if the method is the correct one. **I'm a teapot 418:** Who knows? Maybe the server becomes a teapot! **Unprocessable entity 422:** Some went wrong on your payload. Like, the username of the address while creating the account isn't long enough, or, the account's domain isn't correct. Things like that. **Too many requests 429:** You exceeded the limit of 8 requests per second! Try delaying the request by one second! # Domains ## GET `/domains` Get the list of available domains. You need a domain before you can [create an account](https://docs.mail.tm/api/accounts#post-accounts). Returns a paginated list of domains. **Body** *None* **Params** | Name | Type | Description | | ---- | ---- | -------------------------- | | page | int | The collection page number | **Response** ```json { "hydra:member": [ { "@id": "string", "@type": "string", "@context": "string", "id": "string", "domain": "string", "isActive": true, "isPrivate": true, "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ], "hydra:totalItems": 0, "hydra:view": { "@id": "string", "@type": "string", "hydra:first": "string", "hydra:last": "string", "hydra:previous": "string", "hydra:next": "string" }, "hydra:search": { "@type": "string", "hydra:template": "string", "hydra:variableRepresentation": "string", "hydra:mapping": [ { "@type": "string", "variable": "string", "property": "string", "required": true } ] } } ``` When you create an email, you have to know first which domain to use. You'll need to retrieve the domain, and then, do like so: ```javascript "user@"+domains[0]['domain'] ``` There are up to 30 domains per page, to check the total number, retrieve it from `"hydra:totalItems"` ## GET `/domains/{id}` Retrieve a domain by its id (Useful for deleted/private domains) **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | ---------------------------------- | | id | string | The domain you want to get with id | **Response** ```json { "@id": "string", "@type": "string", "@context": "string", "id": "string", "domain": "string", "isActive": true, "isPrivate": true, "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ``` # Accounts ## POST `/accounts` Create a new temporary email account. **Body** | Name | Type | Description | | -------- | ------ | ---------------------------------------------- | | address | string | Account's address. Example: | | password | string | Account's password. | **Params** *None* **Response** ```json { "@context": "string", "@id": "string", "@type": "string", "id": "string", "address": "user@example.com", "quota": 0, "used": 0, "isDisabled": true, "isDeleted": true, "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ``` At this point, you could now [get the token](https://docs.mail.tm/getting-started/authentication) and do all the cool stuff you want to do. ## GET `/accounts/{id}` Get an Account resource by its id (Obviously, the Bearer token needs to be the one of the account you are trying to retrieve) **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | ------------------------------- | | id | string | The message you want to gets id | **Response** ```json { "@context": "string", "@id": "string", "@type": "string", "id": "string", "address": "user@example.com", "quota": 0, "used": 0, "isDisabled": true, "isDeleted": true, "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ``` ## DELETE `/accounts/{id}` Deletes the Account resource. ::caution Be careful! We can't restore your account, if you use this method, bye bye dear account :c :: **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | ------------------------------------ | | id | string | The account you want to delete by id | **Response** *None* ***(Returns status code 204 if successful.)*** ## GET `/me` Returns the Account resource that matches the Bearer token that sent the request. **Body** *None* **Params** *None* **Response** ```json { "@context": "string", "@id": "string", "@type": "string", "id": "string", "address": "user@example.com", "quota": 0, "used": 0, "isDisabled": true, "isDeleted": true, "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ``` # Messages ## GET `/messages` Get all messages for your account. Returns a paginated list. **Body** *None* **Params** | Name | Type | Description | | ---- | ---- | -------------------------- | | page | int | The collection page number | **Response** ```json { "hydra:member": [ { "@id": "string", "@type": "string", "@context": "string", "id": "string", "accountId": "string", "msgid": "string", "from": { "name": "string", "address": "string" }, "to": [ { "name": "string", "address": "string" } ], "subject": "string", "intro": "string", "seen": true, "isDeleted": true, "hasAttachments": true, "size": 0, "downloadUrl": "string", "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ], "hydra:totalItems": 0, "hydra:view": { "@id": "string", "@type": "string", "hydra:first": "string", "hydra:last": "string", "hydra:previous": "string", "hydra:next": "string" }, "hydra:search": { "@type": "string", "hydra:template": "string", "hydra:variableRepresentation": "string", "hydra:mapping": [ { "@type": "string", "variable": "string", "property": "string", "required": true } ] } } ``` There are up to 30 messages per page, to check the total number, retrieve it from `"hydra:totalItems"` ## GET `/messages/{id}` Retrieves a Message resource with a specific id (It has way more information than a message retrieved with [GET /messages](https://docs.mail.tm/#get-messages) but it hasn't the "intro" member) **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | --------------------------------- | | id | string | The message you want to get by id | **Response** ```json { "@context": "string", "@id": "string", "@type": "string", "id": "string", "accountId": "string", "msgid": "string", "from": { "name": "string", "address": "string" }, "to": [ { "name": "string", "address": "string" } ], "cc": [ "string" ], "bcc": [ "string" ], "subject": "string", "seen": true, "flagged": true, "isDeleted": true, "verifications": [ "string" ], "retention": true, "retentionDate": "2022-04-01T00:00:00.000Z", "text": "string", "html": [ "string" ], "hasAttachments": true, "attachments": [ { "id": "string", "filename": "string", "contentType": "string", "disposition": "string", "transferEncoding": "string", "related": true, "size": 0, "downloadUrl": "string" } ], "size": 0, "downloadUrl": "string", "createdAt": "2022-04-01T00:00:00.000Z", "updatedAt": "2022-04-01T00:00:00.000Z" } ``` ## DELETE `/messages/{id}` Deletes the `Message` resource. **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | ----------------------------------- | | id | string | The message you want to delete's id | **Response** *None* ***(Returns status code 204 if successful.)*** ## PATCH `/messages/{id}` Marks a Message resource as read! **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | --------------------------------- | | id | string | The message you want to read's id | **Response** ```json { "seen": true } ``` To check if the message has been read, you could also check if the status code is 200! ## GET `/sources/{id}` Gets a Message's Source resource (If you don't know what this is, you either don't really want to use it or you should read [this](https://en.wikipedia.org/wiki/Email#Plain_text_and_HTML){rel=""nofollow""}!) **Body** *None* **Params** | Name | Type | Description | | ---- | ------ | -------------------------------- | | id | string | The source you want to get by id | **Response** ```json { "@context": "string", "@id": "string", "@type": "string", "id": "string", "downloadUrl": "string", "data": "string" } ``` You don't really need the `downloadUrl` if you already have the "data" String. It will simply download that data. ## Attachments Message's attachments need to be handled in a certain way. When you download them, be sure to download them in the right encoding (For example, a .exe file will need to be downloaded as an array of integers, but a json will need to be downloaded as String! Also, remember: APIs are your friends. contentType member can help you know how to decode the file) # Real-time Events Instead of webhooks, we use [Mercure](https://mercure.rocks/){rel=""nofollow""} to push real-time SSE events. This lets you receive emails instantly without polling. ## Listen to messages To listen for incoming emails, connect to the Mercure hub. **Base url:** `https://mercure.mail.tm/.well-known/mercure` **Topic:** `/accounts/{id}` ::note Remember! You must use the `Bearer TOKEN` authorization in the headers! :: For each listened message, there will be an `Account` event. That Account is the Account resource that received the message, with updated `"used"` property. # Integrations | Language | Link | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | .NET | [SmorcIRL/mail.tm](https://github.com/SmorcIRL/mail.tm){rel=""nofollow""} | | Dart | [mailtm\_client](https://pub.dev/packages/mailtm_client){rel=""nofollow""} | | Golang | [felixstrobel/mailtm](https://github.com/felixstrobel/mailtm){rel=""nofollow""}, [msuny-c/mailtm](https://github.com/msuny-c/mailtm){rel=""nofollow""} | | Java | [shivam1608/JMailTM](https://github.com/shivam1608/JMailTM){rel=""nofollow""} | | JavaScript | [cemalgnlts/Mailjs](https://github.com/cemalgnlts/Mailjs){rel=""nofollow""} | | PHP | [heithemmoumni/mail.tm](https://github.com/heithemmoumni/mail.tm){rel=""nofollow""} | | Python | [CarloDePieri/pymailtm](https://github.com/CarloDePieri/pymailtm){rel=""nofollow""}, [prtolem/MailTM](https://github.com/prtolem/MailTM){rel=""nofollow""}, [RPwnage/MailTMClient](https://github.com/RPwnage/MailTMClient){rel=""nofollow""} | | Rust | [AwesomeIbex/mail-tm-rs](https://github.com/AwesomeIbex/mail-tm-rs){rel=""nofollow""} | | Swift | [devwaseem/MailTMSwift](https://github.com/devwaseem/MailTMSwift){rel=""nofollow""} | Built something? Let us know and we'll add it here. # About ## Questions and suggestions Got questions or ideas? Email us at . ## Tech stack Our stack includes [API-Platform](https://api-platform.com/){rel=""nofollow""}, [Mercure](https://mercure.rocks/){rel=""nofollow""}, [Nuxt.js](https://nuxtjs.org){rel=""nofollow""}, [Haraka](https://haraka.github.io){rel=""nofollow""}, [Caddy](https://caddyserver.com/){rel=""nofollow""}, [MongoDB](https://www.mongodb.com/){rel=""nofollow""}, [Node.js](https://nodejs.org){rel=""nofollow""}, [CentOS](https://centos.org){rel=""nofollow""}