Microsoft Power Automate integration
Documentation navigation
Connect MailSlurp email and SMS events to Microsoft Power Automate so messages can start flows, pass data to other apps, and reduce manual handling.
Get JSON to import
If you want a reusable custom connector, import the MailSlurp OpenAPI JSON definition.
- OpenAPI JSON URL: https://api.mailslurp.com/v2/api-docs/
- Swagger UI: https://swagger.mailslurp.com
You can either import directly from URL in Power Automate, or download JSON first:
curl -L "https://api.mailslurp.com/v2/api-docs/" -o mailslurp-openapi.json
Then in Power Automate:
- Go to Custom connectors.
- Select New custom connector.
- Choose Import an OpenAPI file (or import from URL).
- Upload
mailslurp-openapi.jsonor paste the OpenAPI URL. - Configure API key auth using header name
x-api-key. - Save and test the connector actions.
HTTP Request integration
You can also call MailSlurp directly with built-in HTTP actions (without a custom connector):
- Add an HTTP action.
- Set method and URL for the MailSlurp endpoint.
- Add
x-api-keyin request headers. - Use Parse JSON on the response body for typed outputs.
How to get JSON for Parse JSON
- Run the HTTP action once with sample input.
- Open the run history and copy the response
bodyJSON. - Add a Parse JSON action and choose Generate from sample.
- Paste the copied JSON.
Typical flow for OTP or email verification
- Create an inbox for the current run.
- Submit that email address to your app workflow.
- Wait for the latest matching email.
- Extract code or link content.
- Continue flow logic and assertions.
Important actions
Here are common actions for creating inboxes, waiting for messages, and extracting codes:
Create inboxes
/inboxes/withDefaults
Create 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 examples
HTTP
POST /inboxes/withDefaults HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: */*
cURL
Requires cURL 7.76+ and a POSIX shell. Tested with cURL 8.12.1.
(
set -eu
response_file=$(mktemp)
trap 'rm -f "$response_file"' EXIT
status=$(curl --silent --show-error \
--request POST \
--url 'https://api.mailslurp.com/inboxes/withDefaults' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: */*' \
--output "$response_file" \
--write-out '%{http_code}')
case "$status" in
2??) mv "$response_file" 'response.bin' ;;
*) printf 'HTTP %s\n' "$status" >&2; cat "$response_file" >&2; exit 1 ;;
esac
)
JavaScript (HTTP)
Requires Node.js 22+. Tested with Node.js 22.14.0.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://api.mailslurp.com/inboxes/withDefaults", {
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Accept": "*/*"
},
redirect: "manual",
signal: AbortSignal.timeout(60000),
});
const responseBytes = Buffer.from(await response.arrayBuffer());
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${responseBytes.toString("utf8")}`);
}
await writeFile("response.bin", responseBytes);
Python (HTTP)
Requires Python 3.9+. Tested with Python 3.9.21.
import http.client
from pathlib import Path
from urllib.parse import urlsplit
url = urlsplit("https://api.mailslurp.com/inboxes/withDefaults")
headers = {
"x-api-key": "YOUR_API_KEY",
"Accept": "*/*"
}
connection_class = http.client.HTTPSConnection if url.scheme == "https" else http.client.HTTPConnection
connection = connection_class(url.hostname, url.port, timeout=60)
try:
path = (url.path or "/") + ("?" + url.query if url.query else "")
connection.request("POST", path, headers=headers)
response = connection.getresponse()
response_bytes = response.read()
if not 200 <= response.status < 300:
raise RuntimeError(f"HTTP {response.status}: {response_bytes.decode('utf-8', errors='replace')}")
Path("response.bin").write_bytes(response_bytes)
finally:
connection.close()
Wait for email
/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
| 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 | Email | OK |
HTTP examples
HTTP
GET /waitForLatestEmail HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Accept: */*
cURL
Requires cURL 7.76+ and a POSIX shell. Tested with cURL 8.12.1.
(
set -eu
response_file=$(mktemp)
trap 'rm -f "$response_file"' EXIT
status=$(curl --silent --show-error \
--request GET \
--url 'https://api.mailslurp.com/waitForLatestEmail' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: */*' \
--output "$response_file" \
--write-out '%{http_code}')
case "$status" in
2??) mv "$response_file" 'response.bin' ;;
*) printf 'HTTP %s\n' "$status" >&2; cat "$response_file" >&2; exit 1 ;;
esac
)
JavaScript (HTTP)
Requires Node.js 22+. Tested with Node.js 22.14.0.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://api.mailslurp.com/waitForLatestEmail", {
method: "GET",
headers: {
"x-api-key": "YOUR_API_KEY",
"Accept": "*/*"
},
redirect: "manual",
signal: AbortSignal.timeout(60000),
});
const responseBytes = Buffer.from(await response.arrayBuffer());
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${responseBytes.toString("utf8")}`);
}
await writeFile("response.bin", responseBytes);
Python (HTTP)
Requires Python 3.9+. Tested with Python 3.9.21.
import http.client
from pathlib import Path
from urllib.parse import urlsplit
url = urlsplit("https://api.mailslurp.com/waitForLatestEmail")
headers = {
"x-api-key": "YOUR_API_KEY",
"Accept": "*/*"
}
connection_class = http.client.HTTPSConnection if url.scheme == "https" else http.client.HTTPConnection
connection = connection_class(url.hostname, url.port, timeout=60)
try:
path = (url.path or "/") + ("?" + url.query if url.query else "")
connection.request("GET", path, headers=headers)
response = connection.getresponse()
response_bytes = response.read()
if not 200 <= response.status < 300:
raise RuntimeError(f"HTTP {response.status}: {response_bytes.decode('utf-8', errors='replace')}")
Path("response.bin").write_bytes(response_bytes)
finally:
connection.close()
Extract content
/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
| Name | Type | Required | Description |
|---|---|---|---|
emailId | string:uuid | Yes | ID of email to match against |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
pattern | string | Yes | Java 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 https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for more information of available patterns. |
{
"pattern": "value"
}
Responses
| Status | Schema | Description |
|---|---|---|
200 | EmailContentMatchResult | OK |
HTTP examples
HTTP
POST /emails/00000000-0000-4000-8000-000000000000/contentMatch HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
{
"pattern": "value"
}
cURL
Requires cURL 7.76+ and a POSIX shell. Tested with cURL 8.12.1.
(
set -eu
response_file=$(mktemp)
request_body=$(mktemp)
trap 'rm -f "$response_file" "$request_body"' EXIT
{
printf '%b' '{\0012 "pattern": "value"\0012}'
} > "$request_body"
status=$(curl --silent --show-error \
--request POST \
--url 'https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/contentMatch' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--output "$response_file" \
--write-out '%{http_code}' \
--data-binary "@$request_body")
case "$status" in
2??) mv "$response_file" 'response.bin' ;;
*) printf 'HTTP %s\n' "$status" >&2; cat "$response_file" >&2; exit 1 ;;
esac
)
JavaScript (HTTP)
Requires Node.js 22+. Tested with Node.js 22.14.0.
import { writeFile } from "node:fs/promises";
const body = Buffer.concat([
Buffer.from("{\n \"pattern\": \"value\"\n}", "utf8")
]);
const response = await fetch("https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/contentMatch", {
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "*/*"
},
body,
redirect: "manual",
signal: AbortSignal.timeout(60000),
});
const responseBytes = Buffer.from(await response.arrayBuffer());
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${responseBytes.toString("utf8")}`);
}
await writeFile("response.bin", responseBytes);
Python (HTTP)
Requires Python 3.9+. Tested with Python 3.9.21.
import http.client
from pathlib import Path
from urllib.parse import urlsplit
url = urlsplit("https://api.mailslurp.com/emails/00000000-0000-4000-8000-000000000000/contentMatch")
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "*/*"
}
body = b"".join([
"{\n \"pattern\": \"value\"\n}".encode("utf-8")
])
connection_class = http.client.HTTPSConnection if url.scheme == "https" else http.client.HTTPConnection
connection = connection_class(url.hostname, url.port, timeout=60)
try:
path = (url.path or "/") + ("?" + url.query if url.query else "")
connection.request("POST", path, body=body, headers=headers)
response = connection.getresponse()
response_bytes = response.read()
if not 200 <= response.status < 300:
raise RuntimeError(f"HTTP {response.status}: {response_bytes.decode('utf-8', errors='replace')}")
Path("response.bin").write_bytes(response_bytes)
finally:
connection.close()
Reliability tips
- Create a fresh inbox per run to avoid cross-test message collisions.
- Use bounded timeouts and branch on timeout/failure conditions.
- Keep API keys in environment/connection secrets, not inline flow steps.
- Add retries only for transient failures, not for invalid input errors.
Related links
Running this code needs an API key. Get one free