Free Temp Mail API Documentation

Use the EduMails temporary email API to list available domains, generate disposable email addresses, and retrieve incoming messages for your own testing and permitted integrations. The service is receive-only: there is no public endpoint for sending email.

EduMails is a disposable inbox service. An address returned by this API is not proof of enrollment, an institutional student mailbox, or a guarantee of a student discount. See the edumail and student email explanation.

Base URL: https://api.edu-mails.com/api
Format: JSON over HTTPS. Send Accept: application/json; add Content-Type: application/json for JSON request bodies.

Documentation reviewed: .

Access and inbox passwords

The public endpoints do not require an API key. To read an inbox that has a password, supply its password in the X-Inbox-Password request header. A UUID identifies an inbox; it is not a replacement for password protection. An unprotected custom address can be generated again and return the same inbox, so do not treat an address or its UUID as a private account.

Use only inboxes you created or are authorized to access. Keep passwords and inbox identifiers out of shared logs, repositories and URLs. No password-reset endpoint is available. These inboxes are unsuitable for important account recovery or sensitive mail.

GET /domains

Return public domains matching a TLD filter. The optional tld query parameter defaults to .edu.pl; this endpoint does not automatically return every domain category. A filter with no matches returns an empty domain list.

This read-only example lists domain metadata without creating an inbox:

curl --get 'https://api.edu-mails.com/api/domains' \
  --data-urlencode 'tld=.edu.pl' \
  --header 'Accept: application/json'

A successful response has status: "success" and an array at data.domains. Each entry includes an id, name and tld. Use a current returned domain ID for custom generation; availability can change. Domain spelling or suffix does not establish university affiliation.

POST /emails/generate

Generate an address using a JSON body. This request creates server data, except when a custom address already exists and is reused.

  • action: use "random" (the default) or "custom".
  • alias: username for custom mode. It is trimmed, lowercased, stripped to letters a–z and digits 0–9, and truncated to 30 characters. If fewer than 5 characters remain, a random alias is generated.
  • domain_id: in custom mode, select an available public domain returned by /domains.
  • tld: in custom mode, the fallback filter if no usable domain_id is supplied; defaults to .edu.pl. If the chosen ID is unavailable, another public domain in the fallback category may be selected.

Random mode chooses across all public domains. It does not restrict its choice to the supplied TLD or domain ID. Always read the final data.email.address from the response.

Random request body

{
  "action": "random"
}

Custom request body

The ID below is illustrative. Replace it with a current domain ID from the listing before making a request.

{
  "action": "custom",
  "alias": "demoqa2026",
  "domain_id": 123
}

Illustrative response

Examples use the reserved domain example.com and a placeholder identifier; they do not describe a live inbox. Actual objects can contain additional fields.

{
  "status": "success",
  "data": {
    "email": {
      "uuid": "YOUR_INBOX_UUID",
      "address": "demoqa2026@example.com",
      "has_password": false
    },
    "reused": false
  }
}

Store the returned UUID to read this inbox. The custom response includes data.reused: true means the same address already existed and its existing UUID was returned. The random response does not include this flag. Generation does not return a password or grant access to password-protected messages.

GET /emails/{uuid}

Read an authorized inbox by replacing {uuid} with its returned UUID. A successful response includes data.email and data.messages, ordered newest first. An empty inbox returns an empty messages array. This route has no documented pagination parameters.

For a protected inbox, send X-Inbox-Password: YOUR_INBOX_PASSWORD as a header. Omit it for an unprotected inbox. Do not place the password in a query string.

{
  "status": "success",
  "data": {
    "email": {
      "uuid": "YOUR_INBOX_UUID",
      "address": "demoqa2026@example.com",
      "has_password": true
    },
    "messages": []
  }
}

Message records use fields including uuid, from, recipient, subject, body and created_at. Handle empty or missing content. Treat email content as untrusted; do not insert message HTML into your application without appropriate sanitization or isolation.

A missing or incorrect password produces HTTP 401 with data.password_required: true. An unknown UUID produces HTTP 404.

PUT /emails/{uuid}/password

Set or change the password on an inbox you are authorized to manage. Send a required password string of 6–72 characters in the JSON body. The new password is stored as a hash and is not returned by the API.

{
  "password": "YOUR_NEW_UNIQUE_PASSWORD"
}

If the inbox already has a password, also provide current_password in the body or the current password in X-Inbox-Password. A supplied current_password takes precedence over the header. The current-password body field accepts at most 72 characters.

{
  "password": "YOUR_NEW_UNIQUE_PASSWORD",
  "current_password": "YOUR_CURRENT_PASSWORD"
}

Success returns HTTP 200, message: "Inbox password saved." and the updated object at data.email. A wrong current password returns 401, an unknown inbox returns 404, and an invalid body returns 422 when JSON is requested. There is no public password removal or recovery endpoint.

Errors, polling and limits

  • 200: the request succeeded, including generation and password updates.
  • 400: address generation found no eligible domain. Refresh the domain listing and check your selected category.
  • 401: protected inbox access failed or the current password is incorrect. Stop polling and obtain the correct password.
  • 404: the UUID was not found. Check the identifier; do not keep polling a missing inbox.
  • 422: a password update failed validation. Inspect the JSON validation errors and correct the request.

No fixed public request quota is documented here. This does not imply unlimited capacity or a service-level guarantee. Poll conservatively, stop when you have the message you need, and pause while an inbox is inactive. A five-second interval matches the website's current refresh behavior; it is a suggested client interval, not a guaranteed rate allowance.

If an upstream service returns 429, respect Retry-After when provided and back off. Use bounded retries for transient network or server failures; avoid retry storms. Do not automatically retry random generation after an uncertain timeout, because another request may create another address.

There is no public send-mail, delete-message, delete-inbox or webhook-subscription endpoint documented by this interface. Inbox retention and third-party acceptance are not guaranteed. For end-user instructions, read the temp mail guide, inbox safety guide and terms and privacy information.