MailSlurp logo

BrowserStack Integration

Use MailSlurp HTTP APIs in BrowserStack sign-up and OTP verification tests

View Markdown Agent setup
BrowserStack and MailSlurp integration banner

MailSlurp fits BrowserStack best when BrowserStack drives the browser UI and MailSlurp handles email state over HTTP. A common pattern is to create a fresh inbox for the test, submit that address in your app's sign-up form, wait for the OTP email, extract the code, and then type the code back into the BrowserStack session.

The test suite orchestrates both sides of the flow: it uses BrowserStack to drive the browser and MailSlurp APIs to create inboxes, wait for messages, and extract the OTP needed to finish the sign-up flow.

BrowserStack MailSlurp OTP flow

Authenticate API requests

Create an API key in the MailSlurp dashboard. MailSlurp accepts API keys in either of these forms:

  • Recommended: x-api-key: YOUR_API_KEY request header
  • Alternative: ?apiKey=YOUR_API_KEY query parameter

Header-based authentication:

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

Query-parameter authentication:

POST https://api.mailslurp.com/inboxes/withDefaults?apiKey=YOUR_API_KEY
Accept: application/json

Use the header form by default. It is easier to manage in helpers, CI secrets, and BrowserStack test configuration.

Typical BrowserStack OTP workflow

Imagine your app has a user sign-up form with email, password, and verification code fields.

  1. Start the BrowserStack test and open the sign-up page.
  2. Call createInboxWithDefaults to create a fresh MailSlurp inbox for this test run.
  3. Put the returned emailAddress into the sign-up form and submit it.
  4. Let your app send the OTP email.
  5. Call waitForLatestEmail with the new inbox ID and wait for the verification email.
  6. Call getEmailContentMatch with the email ID to extract the OTP from the message body.
  7. Type the OTP into the verification form and assert the user reaches the expected logged-in page.

If you are using BrowserStack's low-code tooling, keep these MailSlurp calls in a small helper script, test task, or API action that runs alongside the browser session.

1. Create an inbox for the sign-up flow

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()
API_KEY=your_api_key

INBOX_JSON=$(curl -sS -X POST "https://api.mailslurp.com/inboxes/withDefaults" \
  -H "x-api-key: ${API_KEY}" \
  -H "Accept: application/json")

INBOX_ID=$(printf '%s' "$INBOX_JSON" | jq -r '.id')
EMAIL_ADDRESS=$(printf '%s' "$INBOX_JSON" | jq -r '.emailAddress')

printf 'Use this address in the BrowserStack sign-up form: %s\n' "$EMAIL_ADDRESS"
POST https://api.mailslurp.com/inboxes/withDefaults
x-api-key: YOUR_API_KEY
Accept: application/json

The response includes both the inbox id and the generated emailAddress. Use that address for the new user registration step in BrowserStack.

2. Wait for the verification email

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)

After BrowserStack clicks your app's Sign up, Continue, or Send code button, wait for the latest unread email in the new inbox:

EMAIL_JSON=$(curl -sS "https://api.mailslurp.com/waitForLatestEmail?inboxId=${INBOX_ID}&timeout=120000&unreadOnly=true" \
  -H "x-api-key: ${API_KEY}" \
  -H "Accept: application/json")

EMAIL_ID=$(printf '%s' "$EMAIL_JSON" | jq -r '.id')
EMAIL_SUBJECT=$(printf '%s' "$EMAIL_JSON" | jq -r '.subject')

printf 'Received email %s with subject: %s\n' "$EMAIL_ID" "$EMAIL_SUBJECT"
GET https://api.mailslurp.com/waitForLatestEmail?inboxId=INBOX_ID&timeout=120000&unreadOnly=true
x-api-key: YOUR_API_KEY
Accept: application/json

Because the inbox was created just for this test, unreadOnly=true keeps the request aligned with the message generated by the current sign-up attempt.

3. Extract the OTP code from the email body

POST /emails/{emailId}/contentMatch

Run regex against hydrated email body and return matches

Executes a Java regex pattern over hydrated email body text and returns the full match plus capture groups. Pattern syntax follows Java `Pattern` rules.

Request, parameters, and responses

Path parameters

NameTypeRequiredDescription
emailIdstring:uuidYesID of email to match against

Request body (required)

ContentMatchOptions application/json
FieldTypeRequiredDescription
patternstringYesJava style regex pattern. Do not include the typical `/` at start or end of regex in some languages. Given an example `your code is: 12345` the pattern to extract match looks like `code is: (\d{6})`. This will return an array of matches with the first matching the entire pattern and the subsequent matching the groups: `['code is: 123456', '123456']` See htt...
Request example
{
  "pattern": "value"
}

Responses

StatusSchemaDescription
200EmailContentMatchResultOK
HTTP and SDK snippets

HTTP

HTTP
POST /emails/00000000-0000-4000-8000-000000000000/contentMatch HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: application/json
Content-Type: application/json

{
  "pattern": "value"
}

cURL

cURL
curl -X POST "https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/contentMatch" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  --data '{"pattern":"value"}'

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",
  "contentMatchOptions": {
    "pattern": "value"
  }
};

const result = await emailController.getEmailContentMatch(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)
    content_match_options = {
      "pattern": "value"
    }
    result = emailController.get_email_content_match("00000000-0000-4000-8000-000000000000", content_match_options)

getEmailContentMatch uses Java-style regex patterns. Add a capture group around the OTP so the extracted code is returned in matches[1].

MATCH_JSON=$(curl -sS -X POST "https://api.mailslurp.com/emails/${EMAIL_ID}/contentMatch" \
  -H "x-api-key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data '{"pattern":"(?:verification code|OTP|code)[:\\s-]*(\\d{6})"}')

OTP_CODE=$(printf '%s' "$MATCH_JSON" | jq -r '.matches[1]')

printf 'OTP code: %s\n' "$OTP_CODE"
POST https://api.mailslurp.com/emails/EMAIL_ID/contentMatch
x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: application/json

{
  "pattern": "(?:verification code|OTP|code)[:\\s-]*(\\d{6})"
}

Take OTP_CODE and enter it into the BrowserStack verification page to finish the sign-up flow.

End-to-end example sequence

This is the full MailSlurp side of a BrowserStack OTP test:

API_KEY=your_api_key

INBOX_JSON=$(curl -sS -X POST "https://api.mailslurp.com/inboxes/withDefaults" \
  -H "x-api-key: ${API_KEY}" \
  -H "Accept: application/json")
INBOX_ID=$(printf '%s' "$INBOX_JSON" | jq -r '.id')
EMAIL_ADDRESS=$(printf '%s' "$INBOX_JSON" | jq -r '.emailAddress')

# BrowserStack fills the sign-up form with $EMAIL_ADDRESS and submits it here.

EMAIL_JSON=$(curl -sS "https://api.mailslurp.com/waitForLatestEmail?inboxId=${INBOX_ID}&timeout=120000&unreadOnly=true" \
  -H "x-api-key: ${API_KEY}" \
  -H "Accept: application/json")
EMAIL_ID=$(printf '%s' "$EMAIL_JSON" | jq -r '.id')

MATCH_JSON=$(curl -sS -X POST "https://api.mailslurp.com/emails/${EMAIL_ID}/contentMatch" \
  -H "x-api-key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data '{"pattern":"(?:verification code|OTP|code)[:\\s-]*(\\d{6})"}')
OTP_CODE=$(printf '%s' "$MATCH_JSON" | jq -r '.matches[1]')

# BrowserStack types $OTP_CODE into the verification form and asserts success here.

Secondary option: visual and non-coded tests

If you prefer visual and non-coded tests try our MailSlurp test interface. It gives you a browser-based inbox view where you can sign in with your API key, create disposable inboxes, inspect received emails, and read OTP codes without wiring MailSlurp HTTP calls into your test runner first.

Open video on YouTube

This approach is useful when you are building BrowserStack flows in a recorder or low-code runner, when you want a visible inbox during test authoring, or when you need to debug a verification email template before you move to API-based assertions.

A typical visual flow looks like this:

  1. Open test.mailslurp.com in a BrowserStack step or browser tab.
  2. Authenticate with your MailSlurp API key.
  3. Create an inbox in the UI and copy the generated email address.
  4. Paste that address into your app's sign-up form in BrowserStack.
  5. Return to the MailSlurp tab to wait for and inspect the OTP email.
  6. Copy the code from the email and enter it into the verification form.

The tradeoff is that the visual route is slower and less deterministic than direct API calls. It is best for exploratory testing, low-code setups, and debugging. For CI pipelines, repeatable OTP checks, and parallel BrowserStack runs, the HTTP API workflow above should stay the primary path.