guides
Reading Email in Postman
Use MailSlurp REST API calls in Postman or ACCELQ to create an inbox, wait for a matching email subject, verify attachment metadata, and download attachments.
Postman can run a complete MailSlurp email receive workflow without an SDK. Create an inbox, store its ID and email address as collection variables, trigger your application or external service, wait until a response email matches the subject token you expect, then verify and download the attachment.
The companion Postman collection includes the same variables, X-API-Key authentication, pre-request scripts, Tests tab assertions, subject matching, attachment metadata checks, and download requests shown below. You can also open the public collection in Postman to inspect each request before forking it.
The same REST sequence works in ACCELQ and other API automation tools because each step is a normal HTTPS request authenticated with the X-API-Key header.
sequenceDiagram autonumber participant Runner as Postman or ACCELQ participant MailSlurp as MailSlurp REST API participant Inbox as MailSlurp inbox participant App as External service Runner->>MailSlurp: POST /inboxes/withDefaults MailSlurp-->>Runner: inboxId and emailAddress Runner->>Runner: Store inboxId, inboxAddress, subjectToken Runner->>MailSlurp: POST /sendEmail with senderId inboxId MailSlurp->>App: Email from created inbox address App->>Inbox: Reply with subject containing 8 digit token and attachment Runner->>MailSlurp: POST /waitForMatchingFirstEmail MailSlurp-->>Runner: Matched email with attachment IDs Runner->>MailSlurp: GET attachment metadata MailSlurp-->>Runner: name, contentType, contentLength Runner->>MailSlurp: GET attachment bytes or base64 MailSlurp-->>Runner: Downloaded attachment
How MailSlurp fits the flow
A MailSlurp inbox is a real email address controlled by the API. When you create an inbox, MailSlurp returns an id and an emailAddress. Use the id for API calls and the emailAddress anywhere a sender or receiver needs a real address.
For the scenario described:
- Create a new inbox for the test run.
- Save
idasinboxIdandemailAddressasinboxAddressin Postman. - Send from that inbox by passing
senderId: "{{inboxId}}", or trigger your own external service to send to{{inboxAddress}}. - Include an 8 digit token in the subject, such as
Postman attachment response 48291357. - Wait for the reply with
waitForMatchingFirstEmail. - Verify attachment metadata with the email attachment endpoints.
- Download the attachment as bytes, or use the base64 endpoint for automated runners.
If the receiver should see the exact mailbox you created, make sure the send request uses senderId set to the created inbox ID. The From address will be the inbox email address returned by MailSlurp. If you need a specific human-readable address, create the inbox on a verified domain and keep the same senderId pattern.
Postman setup
Create a Postman collection and add these collection variables:
| Variable | Example | Purpose |
|---|---|---|
baseUrl |
https://api.mailslurp.com |
MailSlurp REST API base URL |
apiKey |
YOUR_MAILSLURP_API_KEY |
API key from the MailSlurp dashboard |
inboxId |
empty | Set after inbox creation |
inboxAddress |
empty | Set after inbox creation |
externalRecipient |
service-under-test@example.com |
Address that receives the first email |
subjectToken |
empty | Generated 8 digit token |
expectedSubject |
empty | Subject used for send and match |
expectedAttachmentName |
report.pdf |
Optional metadata assertion |
expectedAttachmentContentType |
application/pdf |
Optional metadata assertion |
emailId |
empty | Set after wait-for-match |
attachmentId |
empty | Set after metadata lookup |
The companion collection uses baseUrl for portability. The request snippets below spell out https://api.mailslurp.com so each call is clear when copied into Postman, Newman, ACCELQ, or another HTTP runner.
Get an API key from the MailSlurp dashboard, then authenticate every request with this header:
X-API-Key: {{apiKey}}
In Postman, set the header at collection level so every request inherits it. Header names are case-insensitive, so x-api-key and X-API-Key both work.
1. Create an inbox
Use the default inbox endpoint when you want a unique address for each run.
/inboxes/withDefaultsCreate an inbox with default options. Uses MailSlurp domain pool address and is private.
Request, parameters, and responses
Responses
| Status | Schema | Description |
|---|---|---|
201 | InboxDto | Created |
HTTP and SDK snippets
HTTP
POST /inboxes/withDefaults HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/jsoncURL
curl -X POST "https://api.mailslurp.com/inboxes/withDefaults" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"JavaScript SDK
import { Configuration, InboxControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const inboxController = new InboxControllerApi(config);
const result = await inboxController.createInboxWithDefaults();Python SDK
import mailslurp_client
from mailslurp_client.api.inbox_controller_api import InboxControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
inboxController = InboxControllerApi(api_client)
result = inboxController.create_inbox_with_defaults()Postman request:
POST https://api.mailslurp.com/inboxes/withDefaults
X-API-Key: {{apiKey}}
Add this to the request's Tests tab:
const inbox = pm.response.json();
pm.test("created a MailSlurp inbox", () => {
pm.response.to.have.status(201);
pm.expect(inbox.id).to.be.a("string");
pm.expect(inbox.emailAddress).to.include("@");
});
pm.collectionVariables.set("inboxId", inbox.id);
pm.collectionVariables.set("inboxAddress", inbox.emailAddress);
const token = String(Math.floor(10000000 + Math.random() * 90000000));
pm.collectionVariables.set("subjectToken", token);
pm.collectionVariables.set("expectedSubject", `Postman attachment response ${token}`);
After this request, Postman can reuse {{inboxId}}, {{inboxAddress}}, {{subjectToken}}, and {{expectedSubject}} in later calls.
2. Send or trigger the email
If your test starts by sending an email from the newly created mailbox to another system, call the MailSlurp send endpoint and pass the created inbox as senderId.
/sendEmailSend an email
If no senderId or inboxId provided a random email address will be used to send from.
Request, parameters, and responses
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
senderId | string:uuid | No | ID of inbox to send from. If null an inbox will be created for sending |
to | string | Yes | Email address to send to |
body | string | No | Body of the email message. Supports HTML |
subject | string | No | Subject line of the email |
{
"to": "user@example.com",
"senderId": "00000000-0000-4000-8000-000000000000",
"body": "Hello from MailSlurp",
"subject": "Hello from MailSlurp"
}Responses
| Status | Schema | Description |
|---|---|---|
201 | Response | Created |
HTTP and SDK snippets
HTTP
POST /sendEmail HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/json
Content-Type: application/json
{
"to": "user@example.com",
"senderId": "00000000-0000-4000-8000-000000000000",
"body": "Hello from MailSlurp",
"subject": "Hello from MailSlurp"
}cURL
curl -X POST "https://api.mailslurp.com/sendEmail" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"to":"user@example.com","senderId":"00000000-0000-4000-8000-000000000000","body":"Hello from MailSlurp","subject":"Hello from MailSlurp"}'JavaScript SDK
import { Configuration, CommonActionsControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const commonActionsController = new CommonActionsControllerApi(config);
const request = {
"simpleSendEmailOptions": {
"to": "user@example.com",
"senderId": "00000000-0000-4000-8000-000000000000",
"body": "Hello from MailSlurp",
"subject": "Hello from MailSlurp"
}
};
const result = await commonActionsController.sendEmailSimple(request);Python SDK
import mailslurp_client
from mailslurp_client.api.common_actions_controller_api import CommonActionsControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
commonActionsController = CommonActionsControllerApi(api_client)
simple_send_email_options = {
"to": "user@example.com",
"senderId": "00000000-0000-4000-8000-000000000000",
"body": "Hello from MailSlurp",
"subject": "Hello from MailSlurp"
}
result = commonActionsController.send_email_simple(simple_send_email_options)Postman request:
POST https://api.mailslurp.com/sendEmail
X-API-Key: {{apiKey}}
Content-Type: application/json
Body:
{
"senderId": "{{inboxId}}",
"to": "{{externalRecipient}}",
"subject": "{{expectedSubject}}",
"body": "Please reply to {{inboxAddress}} with the requested attachment. Token: {{subjectToken}}"
}
This sends from the MailSlurp inbox you just created. The receiver sees the created inbox address as the sender.
If your application is the sender, call your application endpoint instead and pass {{inboxAddress}} as the recipient. For example:
POST {{appBaseUrl}}/send-report
Content-Type: application/json
{
"to": "{{inboxAddress}}",
"subject": "{{expectedSubject}}",
"includeAttachment": true
}
The important detail is that the response email should arrive at {{inboxAddress}} and its subject should contain {{subjectToken}}.
3. Wait for the matching reply
For a subject that contains 8 random digits, use waitForMatchingFirstEmail. It holds the request open until a matching email arrives or the timeout expires. This is more reliable than manually polling a list endpoint.
/waitForMatchingFirstEmailWait for or return the first email that matches provided MatchOptions array
Perform a search of emails in an inbox with the given patterns. If a result if found then return or else retry the search until a result is found or timeout is reached. Match options allow simple CONTAINS or EQUALS filtering on SUBJECT, TO, BCC, CC, and FROM. See the `MatchOptions` object for options. An example payload is `{ matches: [{field: 'SUBJECT',should:'CONTAIN',value:'needle'}] }`. You can use an array of matches and they will be applied sequentially to filter out emails. If you want to perform matches and extractions of content using Regex patterns see the EmailController `getEmailContentMatch` method.
Request, parameters, and responses
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
inboxId | string:uuid | Yes | Id of the inbox we are matching an email for |
timeout | integer:int64 | No | Max milliseconds to wait |
unreadOnly | boolean | No | Optional filter for unread only |
since | string:date-time | No | Filter for emails that were received after the given timestamp |
before | string:date-time | No | Filter for emails that were received before the given timestamp |
sort | enum: ASC | DESC | No | Sort directionValues: ASC, DESC |
delay | integer:int64 | No | Max milliseconds delay between calls |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
matches | MatchOption[] | No | Zero or more match options such as `{ field: 'SUBJECT', should: 'CONTAIN', value: 'Welcome' }`. Options are additive so if one does not match the email is excluded from results |
conditions | ConditionOption[] | No | Zero or more conditions such as `{ condition: 'HAS_ATTACHMENTS', value: 'TRUE' }`. Note the values are the strings `TRUE|FALSE` not booleans. |
{
"matches": [
{
"field": "SUBJECT",
"should": "MATCH",
"value": "value"
}
],
"conditions": [
{
"condition": "HAS_ATTACHMENTS",
"value": "TRUE"
}
]
}Responses
| Status | Schema | Description |
|---|---|---|
200 | OK |
HTTP and SDK snippets
HTTP
POST /waitForMatchingFirstEmail?inboxId=00000000-0000-4000-8000-000000000000&timeout=value&unreadOnly=true HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/json
Content-Type: application/json
{
"matches": [
{
"field": "SUBJECT",
"should": "MATCH",
"value": "value"
}
],
"conditions": [
{
"condition": "HAS_ATTACHMENTS",
"value": "TRUE"
}
]
}cURL
curl -X POST "https://api.mailslurp.com/waitForMatchingFirstEmail?inboxId=00000000-0000-4000-8000-000000000000&timeout=value&unreadOnly=true" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"matches":[{"field":"SUBJECT","should":"MATCH","value":"value"}],"conditions":[{"condition":"HAS_ATTACHMENTS","value":"TRUE"}]}'JavaScript SDK
import { Configuration, WaitForControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const waitForController = new WaitForControllerApi(config);
const request = {
"inboxId": "00000000-0000-4000-8000-000000000000",
"timeout": null,
"unreadOnly": true,
"matchOptions": {
"matches": [
{
"field": "SUBJECT",
"should": "MATCH",
"value": "value"
}
],
"conditions": [
{
"condition": "HAS_ATTACHMENTS",
"value": "TRUE"
}
]
}
};
const result = await waitForController.waitForMatchingFirstEmail(request);Python SDK
import mailslurp_client
from mailslurp_client.api.wait_for_controller_api import WaitForControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
waitForController = WaitForControllerApi(api_client)
match_options = {
"matches": [
{
"field": "SUBJECT",
"should": "MATCH",
"value": "value"
}
],
"conditions": [
{
"condition": "HAS_ATTACHMENTS",
"value": "TRUE"
}
]
}
result = waitForController.wait_for_matching_first_email(inbox_id="00000000-0000-4000-8000-000000000000", timeout=NaN, unread_only=True, match_options)Postman request:
POST https://api.mailslurp.com/waitForMatchingFirstEmail?inboxId={{inboxId}}&timeout=120000&unreadOnly=true
X-API-Key: {{apiKey}}
Content-Type: application/json
Body:
{
"matches": [
{
"field": "SUBJECT",
"should": "CONTAIN",
"value": "{{subjectToken}}"
}
],
"conditions": [
{
"condition": "HAS_ATTACHMENTS",
"value": "TRUE"
}
]
}
Add this to the Tests tab:
const email = pm.response.json();
const subjectToken = pm.collectionVariables.get("subjectToken");
const attachments = email.attachments || [];
pm.test("matched the expected response email", () => {
pm.response.to.have.status(200);
pm.expect(email.id).to.be.a("string");
pm.expect(email.subject || "").to.include(subjectToken);
});
pm.test("response email has at least one attachment", () => {
pm.expect(attachments.length).to.be.greaterThan(0);
});
pm.collectionVariables.set("emailId", email.id);
pm.collectionVariables.set("attachmentId", attachments[0]);
Use unreadOnly=true for repeatable test runs. It prevents an older email in the same inbox from satisfying the wait.
Optional latest-email fallback
If you do not know the subject in advance, use waitForLatestEmail and then assert on the returned message.
/waitForLatestEmailFetch inbox's latest email or if empty wait for an email to arrive
Will return either the last received email or wait for an email to arrive and return that. If you need to wait for an email for a non-empty inbox set `unreadOnly=true` or see the other receive methods such as `waitForNthEmail` or `waitForEmailCount`.
Request, parameters, and responses
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
inboxId | string:uuid | No | Id of the inbox we are fetching emails from |
timeout | integer:int64 | No | Max milliseconds to wait |
unreadOnly | boolean | No | Optional filter for unread only. |
before | string:date-time | No | Filter for emails that were before after the given timestamp |
since | string:date-time | No | Filter for emails that were received after the given timestamp |
sort | enum: ASC | DESC | No | Sort directionValues: ASC, DESC |
delay | integer:int64 | No | Max milliseconds delay between calls |
Responses
| Status | Schema | Description |
|---|---|---|
200 | OK |
HTTP and SDK snippets
HTTP
GET /waitForLatestEmail?inboxId=00000000-0000-4000-8000-000000000000&timeout=value&unreadOnly=true HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/jsoncURL
curl -X GET "https://api.mailslurp.com/waitForLatestEmail?inboxId=00000000-0000-4000-8000-000000000000&timeout=value&unreadOnly=true" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"JavaScript SDK
import { Configuration, WaitForControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const waitForController = new WaitForControllerApi(config);
const request = {
"inboxId": "00000000-0000-4000-8000-000000000000",
"timeout": null,
"unreadOnly": true
};
const result = await waitForController.waitForLatestEmail(request);Python SDK
import mailslurp_client
from mailslurp_client.api.wait_for_controller_api import WaitForControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
waitForController = WaitForControllerApi(api_client)
result = waitForController.wait_for_latest_email(inbox_id="00000000-0000-4000-8000-000000000000", timeout=NaN, unread_only=True)GET https://api.mailslurp.com/waitForLatestEmail?inboxId={{inboxId}}&timeout=120000&unreadOnly=true
X-API-Key: {{apiKey}}
This is useful for exploratory Postman work, but subject matching is better for automated suites because it ties the assertion to the current run.
4. Verify attachment name and file type
The email returned by the wait endpoint includes attachment IDs. Use the attachment metadata endpoints to verify the file name, MIME type, and size before downloading the content.
To list metadata for all attachments on the email:
/emails/{emailId}/attachmentsList attachment metadata for an email
Returns metadata for all attachment IDs associated with the email (name, content type, size, and IDs).
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
emailId | string:uuid | Yes | ID of email |
Responses
| Status | Schema | Description |
|---|---|---|
200 | AttachmentMetaData[] | OK |
HTTP and SDK snippets
HTTP
GET /emails/00000000-0000-4000-8000-000000000000/attachments HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/jsoncURL
curl -X GET "https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/attachments" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"JavaScript SDK
import { Configuration, EmailControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const emailController = new EmailControllerApi(config);
const request = {
"emailId": "00000000-0000-4000-8000-000000000000"
};
const result = await emailController.getEmailAttachments(request);Python SDK
import mailslurp_client
from mailslurp_client.api.email_controller_api import EmailControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
emailController = EmailControllerApi(api_client)
result = emailController.get_email_attachments("00000000-0000-4000-8000-000000000000")GET https://api.mailslurp.com/emails/{{emailId}}/attachments
X-API-Key: {{apiKey}}
Add this to the Tests tab:
const attachments = pm.response.json();
const expectedName = pm.collectionVariables.get("expectedAttachmentName");
const expectedContentType = pm.collectionVariables.get("expectedAttachmentContentType");
const target = expectedName
? attachments.find((attachment) => attachment.name === expectedName)
: attachments[0];
pm.test("found attachment metadata", () => {
pm.response.to.have.status(200);
pm.expect(target, "matching attachment").to.exist;
pm.expect(target.id).to.be.a("string");
pm.expect(target.name).to.be.a("string");
pm.expect(target.contentType).to.be.a("string");
pm.expect(target.contentLength).to.be.greaterThan(0);
});
if (expectedName) {
pm.test("attachment name matches", () => {
pm.expect(target.name).to.eql(expectedName);
});
}
if (expectedContentType) {
pm.test("attachment content type matches", () => {
pm.expect(target.contentType).to.eql(expectedContentType);
});
}
pm.collectionVariables.set("attachmentId", target.id);
pm.collectionVariables.set("attachmentName", target.name);
pm.collectionVariables.set("attachmentContentType", target.contentType);
To fetch metadata for one attachment ID:
/emails/{emailId}/attachments/{attachmentId}/metadataGet email attachment metadata. This is the `contentType` and `contentLength` of an attachment. To get the individual attachments use the `downloadAttachment` methods.
Returns metadata for a specific attachment ID (name, content type, and size fields).
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
emailId | string:uuid | Yes | ID of email |
attachmentId | string | Yes | ID of attachment |
Responses
| Status | Schema | Description |
|---|---|---|
200 | AttachmentMetaData | OK |
HTTP and SDK snippets
HTTP
GET /emails/00000000-0000-4000-8000-000000000000/attachments/00000000-0000-4000-8000-000000000000/metadata HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/jsoncURL
curl -X GET "https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/attachments/00000000-0000-4000-8000-000000000000/metadata" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"JavaScript SDK
import { Configuration, EmailControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const emailController = new EmailControllerApi(config);
const request = {
"emailId": "00000000-0000-4000-8000-000000000000",
"attachmentId": "00000000-0000-4000-8000-000000000000"
};
const result = await emailController.getAttachmentMetaData(request);Python SDK
import mailslurp_client
from mailslurp_client.api.email_controller_api import EmailControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
emailController = EmailControllerApi(api_client)
result = emailController.get_attachment_meta_data("00000000-0000-4000-8000-000000000000", "00000000-0000-4000-8000-000000000000")GET https://api.mailslurp.com/emails/{{emailId}}/attachments/{{attachmentId}}/metadata
X-API-Key: {{apiKey}}
This endpoint returns fields such as name, contentType, contentLength, and id. Use it when your previous step already selected the attachment ID.
5. Download the attachment
For manual Postman testing, request the binary attachment endpoint and use Postman's Send and Download action.
/emails/{emailId}/attachments/{attachmentId}Get email attachment bytes. Returned as `octet-stream` with content type header. If you have trouble with byte responses try the `downloadAttachmentBase64` response endpoints and convert the base 64 encoded content to a file or string.
Returns attachment bytes by attachment ID. Use attachment IDs from email payloads or attachment listing endpoints.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
emailId | string:uuid | Yes | ID of email |
attachmentId | string | Yes | ID of attachment |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
apiKey | string | No | Can pass apiKey in url for this request if you wish to download the file in a browser. Content type will be set to original content type of the attachment file. This is so that browsers can download the file correctly. |
Responses
| Status | Schema | Description |
|---|---|---|
default | string:byte | default response |
HTTP and SDK snippets
HTTP
GET /emails/00000000-0000-4000-8000-000000000000/attachments/00000000-0000-4000-8000-000000000000?apiKey=value HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/jsoncURL
curl -X GET "https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/attachments/00000000-0000-4000-8000-000000000000?apiKey=value" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"JavaScript SDK
import { Configuration, EmailControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const emailController = new EmailControllerApi(config);
const request = {
"emailId": "00000000-0000-4000-8000-000000000000",
"attachmentId": "00000000-0000-4000-8000-000000000000",
"apiKey": "value"
};
const result = await emailController.downloadAttachment(request);Python SDK
import mailslurp_client
from mailslurp_client.api.email_controller_api import EmailControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
emailController = EmailControllerApi(api_client)
result = emailController.download_attachment("00000000-0000-4000-8000-000000000000", "00000000-0000-4000-8000-000000000000", api_key="value")GET https://api.mailslurp.com/emails/{{emailId}}/attachments/{{attachmentId}}
X-API-Key: {{apiKey}}
Accept: application/octet-stream
Add a lightweight response check:
const expectedContentType = pm.collectionVariables.get("attachmentContentType");
const responseType = pm.response.headers.get("Content-Type") || "";
pm.test("download response is successful", () => {
pm.response.to.have.status(200);
});
if (expectedContentType) {
pm.test("downloaded file type matches metadata", () => {
pm.expect(responseType).to.include(expectedContentType);
});
}
For automated runners, the base64 endpoint is often easier because the response is JSON and can be decoded by Newman, ACCELQ, a CI script, or a downstream API step.
/emails/{emailId}/attachments/{attachmentId}/base64Get email attachment as base64 encoded string as an alternative to binary responses. Decode the `base64FileContents` as a `utf-8` encoded string or array of bytes depending on the `contentType`.
Returns attachment payload as base64 in JSON. Useful for clients that cannot reliably consume binary streaming responses.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
emailId | string:uuid | Yes | ID of email |
attachmentId | string | Yes | ID of attachment |
Responses
| Status | Schema | Description |
|---|---|---|
200 | DownloadAttachmentDto | OK |
HTTP and SDK snippets
HTTP
GET /emails/00000000-0000-4000-8000-000000000000/attachments/00000000-0000-4000-8000-000000000000/base64 HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/jsoncURL
curl -X GET "https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/attachments/00000000-0000-4000-8000-000000000000/base64" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: application/json"JavaScript SDK
import { Configuration, EmailControllerApi } from "mailslurp-client";
const config = new Configuration({ apiKey: "YOUR_API_KEY" });
const emailController = new EmailControllerApi(config);
const request = {
"emailId": "00000000-0000-4000-8000-000000000000",
"attachmentId": "00000000-0000-4000-8000-000000000000"
};
const result = await emailController.downloadAttachmentBase64(request);Python SDK
import mailslurp_client
from mailslurp_client.api.email_controller_api import EmailControllerApi
configuration = mailslurp_client.Configuration()
configuration.api_key["x-api-key"] = "YOUR_API_KEY"
with mailslurp_client.ApiClient(configuration) as api_client:
emailController = EmailControllerApi(api_client)
result = emailController.download_attachment_base64("00000000-0000-4000-8000-000000000000", "00000000-0000-4000-8000-000000000000")GET https://api.mailslurp.com/emails/{{emailId}}/attachments/{{attachmentId}}/base64
X-API-Key: {{apiKey}}
Tests tab:
const attachment = pm.response.json();
const expectedContentType = pm.collectionVariables.get("attachmentContentType");
pm.test("downloaded base64 attachment", () => {
pm.response.to.have.status(200);
pm.expect(attachment.base64FileContents).to.be.a("string").and.not.empty;
pm.expect(attachment.sizeBytes).to.be.greaterThan(0);
});
if (expectedContentType) {
pm.test("base64 file type matches metadata", () => {
pm.expect(attachment.contentType).to.eql(expectedContentType);
});
}
pm.collectionVariables.set("attachmentBase64", attachment.base64FileContents);
Running the same flow in ACCELQ
ACCELQ can use the same MailSlurp REST calls as Postman:
- Add
X-API-Key: <your API key>to each MailSlurp API step. - Store
idandemailAddressfromPOST /inboxes/withDefaultsas scenario variables. - Call your application or
POST /sendEmailwith those variables. - Use
POST /waitForMatchingFirstEmailwithSUBJECTCONTAINand the 8 digit token. - Store
email.idand the first attachment ID. - Call
/emails/{emailId}/attachments/{attachmentId}/metadataand assertnameandcontentType. - Use
/base64for attachment content when your ACCELQ flow needs JSON instead of binary bytes.
MailSlurp wait endpoints make this pattern stable in API test tools because the request waits for the mailbox state you need instead of relying on fixed sleeps.
Troubleshooting
- A timeout from
waitForMatchingFirstEmailusually means the subject token did not match, the reply was sent to a different address, or the message arrived without an attachment. - If an older email is returned, use a fresh inbox per run and keep
unreadOnly=true. - If the receiver does not see the created inbox as the sender, confirm the send body includes
"senderId": "{{inboxId}}". - If Postman cannot save a binary file during automation, use
/base64and decode thebase64FileContentsvalue in the runner. - If your expected file type is an extension such as
.pdf, assert the metadatanamefor the extension andcontentTypefor the MIME type, such asapplication/pdf.
Complete request order
POST /inboxes/withDefaultsPOST /sendEmailor your external service triggerPOST /waitForMatchingFirstEmailGET /emails/{emailId}/attachmentsGET /emails/{emailId}/attachments/{attachmentId}/metadataGET /emails/{emailId}/attachments/{attachmentId}orGET /emails/{emailId}/attachments/{attachmentId}/base64
With these requests in a Postman collection, MailSlurp gives you a repeatable receive-email test that can be run manually, in collection runner, in Newman, or as ACCELQ API steps.