MailSlurp logo

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.

Run in Postman

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:

  1. Create a new inbox for the test run.
  2. Save id as inboxId and emailAddress as inboxAddress in Postman.
  3. Send from that inbox by passing senderId: "{{inboxId}}", or trigger your own external service to send to {{inboxAddress}}.
  4. Include an 8 digit token in the subject, such as Postman attachment response 48291357.
  5. Wait for the reply with waitForMatchingFirstEmail.
  6. Verify attachment metadata with the email attachment endpoints.
  7. 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.

POST/inboxes/withDefaults

Create an inbox with default options. Uses MailSlurp domain pool address and is private.

Request, parameters, and responses

Responses

StatusSchemaDescription
201InboxDtoCreated
HTTP and SDK snippets

HTTP

HTTP
POST /inboxes/withDefaults HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/json

cURL

cURL
curl -X POST "https://api.mailslurp.com/inboxes/withDefaults" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"

JavaScript SDK

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

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.

POST/sendEmail

Send 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)

SimpleSendEmailOptionsapplication/json
FieldTypeRequiredDescription
senderIdstring:uuidNoID of inbox to send from. If null an inbox will be created for sending
tostringYesEmail address to send to
bodystringNoBody of the email message. Supports HTML
subjectstringNoSubject line of the email
Request example
{
  "to": "user@example.com",
  "senderId": "00000000-0000-4000-8000-000000000000",
  "body": "Hello from MailSlurp",
  "subject": "Hello from MailSlurp"
}

Responses

StatusSchemaDescription
201ResponseCreated
HTTP and SDK snippets

HTTP

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
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

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

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.

POST/waitForMatchingFirstEmail

Wait 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

NameTypeRequiredDescription
inboxIdstring:uuidYesId of the inbox we are matching an email for
timeoutinteger:int64NoMax milliseconds to wait
unreadOnlybooleanNoOptional filter for unread only
sincestring:date-timeNoFilter for emails that were received after the given timestamp
beforestring:date-timeNoFilter for emails that were received before the given timestamp
sortenum: ASC | DESCNoSort directionValues: ASC, DESC
delayinteger:int64NoMax milliseconds delay between calls

Request body (required)

MatchOptionsapplication/json
FieldTypeRequiredDescription
matchesMatchOption[]NoZero 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
conditionsConditionOption[]NoZero or more conditions such as `{ condition: 'HAS_ATTACHMENTS', value: 'TRUE' }`. Note the values are the strings `TRUE|FALSE` not booleans.
Request example
{
  "matches": [
    {
      "field": "SUBJECT",
      "should": "MATCH",
      "value": "value"
    }
  ],
  "conditions": [
    {
      "condition": "HAS_ATTACHMENTS",
      "value": "TRUE"
    }
  ]
}

Responses

StatusSchemaDescription
200EmailOK
HTTP and SDK snippets

HTTP

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
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

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

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.

GET/waitForLatestEmail

Fetch 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

NameTypeRequiredDescription
inboxIdstring:uuidNoId of the inbox we are fetching emails from
timeoutinteger:int64NoMax milliseconds to wait
unreadOnlybooleanNoOptional filter for unread only.
beforestring:date-timeNoFilter for emails that were before after the given timestamp
sincestring:date-timeNoFilter for emails that were received after the given timestamp
sortenum: ASC | DESCNoSort directionValues: ASC, DESC
delayinteger:int64NoMax milliseconds delay between calls

Responses

StatusSchemaDescription
200EmailOK
HTTP and SDK snippets

HTTP

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/json

cURL

cURL
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

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

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:

GET/emails/{emailId}/attachments

List 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

NameTypeRequiredDescription
emailIdstring:uuidYesID of email

Responses

StatusSchemaDescription
200AttachmentMetaData[]OK
HTTP and SDK snippets

HTTP

HTTP
GET /emails/00000000-0000-4000-8000-000000000000/attachments HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/json

cURL

cURL
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

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

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:

GET/emails/{emailId}/attachments/{attachmentId}/metadata

Get 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

NameTypeRequiredDescription
emailIdstring:uuidYesID of email
attachmentIdstringYesID of attachment

Responses

StatusSchemaDescription
200AttachmentMetaDataOK
HTTP and SDK snippets

HTTP

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/json

cURL

cURL
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

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

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.

GET/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

NameTypeRequiredDescription
emailIdstring:uuidYesID of email
attachmentIdstringYesID of attachment

Query parameters

NameTypeRequiredDescription
apiKeystringNoCan 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

StatusSchemaDescription
defaultstring:bytedefault response
HTTP and SDK snippets

HTTP

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/json

cURL

cURL
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

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

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.

GET/emails/{emailId}/attachments/{attachmentId}/base64

Get 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

NameTypeRequiredDescription
emailIdstring:uuidYesID of email
attachmentIdstringYesID of attachment

Responses

StatusSchemaDescription
200DownloadAttachmentDtoOK
HTTP and SDK snippets

HTTP

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/json

cURL

cURL
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

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

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:

  1. Add X-API-Key: <your API key> to each MailSlurp API step.
  2. Store id and emailAddress from POST /inboxes/withDefaults as scenario variables.
  3. Call your application or POST /sendEmail with those variables.
  4. Use POST /waitForMatchingFirstEmail with SUBJECT CONTAIN and the 8 digit token.
  5. Store email.id and the first attachment ID.
  6. Call /emails/{emailId}/attachments/{attachmentId}/metadata and assert name and contentType.
  7. Use /base64 for 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 waitForMatchingFirstEmail usually 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 /base64 and decode the base64FileContents value in the runner.
  • If your expected file type is an extension such as .pdf, assert the metadata name for the extension and contentType for the MIME type, such as application/pdf.

Complete request order

  1. POST /inboxes/withDefaults
  2. POST /sendEmail or your external service trigger
  3. POST /waitForMatchingFirstEmail
  4. GET /emails/{emailId}/attachments
  5. GET /emails/{emailId}/attachments/{attachmentId}/metadata
  6. GET /emails/{emailId}/attachments/{attachmentId} or GET /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.