MailSlurp deliverability test API
Documentation navigation
Run MailSlurp deliverability tests across controlled email and phone cohorts, define expected outcomes, and inspect message evidence when a check fails.
Deliverability tests give QA, release, and operations teams a pass/fail view of whether the right messages reached the right inboxes or phone numbers during a launch, canary, or campaign run. They are designed for higher-level verification than a single wait call in one test.
When to use this feature
Use deliverability tests when you need to answer questions like:
- Did every selected inbox receive the expected email volume?
- Did every selected phone number receive the expected SMS?
- Did messages arrive from the expected sender?
- Did the campaign subject line or recipient matching logic behave the way we intended?
If you only need to wait for one message in one test, use Wait for methods instead.
Typical workflow
- Create a test with the right scope, selector, and expectations.
- Start the test manually or from its schedule.
- Trigger traffic from your app, ESP, or release workflow.
- Poll status and review pass/fail results as messages arrive.
- Investigate unmatched inboxes or phone numbers before scaling up the send.
Example: create an inbox-scoped test
// Define an inbox-scoped deliverability test with explicit inbox targets and a minimum-count expectation.
const createdTest = await deliverabilityTestController.createDeliverabilityTest({
createDeliverabilityTestOptions: {
name: `deliverability-test-${Date.now()}`,
description: 'admin-sdk deliverability progression test',
scope: 'INBOX',
selector: {
type: 'EXPLICIT',
entityIds: [inboxA.id!, inboxB.id!]
},
expectations: [
{
name: 'expect-1-each',
minCount: 1
}
],
maxDurationSeconds: 300
}
});
deliverabilityTestId = createdTest.id;
Example: start a test run
// Start the deliverability test so progress polling can begin.
const startedTest = await deliverabilityTestController.startDeliverabilityTest({
testId: createdTest.id
});
expect(['SCHEDULED', 'RUNNING']).toContain(startedTest.status);
Scope and selector choices
You run a deliverability test in one scope at a time:
- Inbox scope for inbound email delivery
- Phone scope for inbound SMS delivery
Selectors determine which entities participate:
- all entities in scope
- explicit entity lists
- pattern-based selection when you want a naming or addressing convention to define the cohort
Start with a canary cohort before you widen the selector.
What you can validate
Deliverability tests are strongest when you care about expectation-based delivery signals such as:
- minimum message counts
- sender matching
- recipient matching
- subject matching
They are not a replacement for deeper content review. Pair them with:
- Email audit for link and image checks
- Device previews for rendering review
- Campaign Probe for live campaign capture
Progress and results
During execution you can review:
- completion percentage
- matched versus unmatched entities
- run state such as scheduled, running, paused, completed, failed, or stopped
Example: check for completion
// Poll until the test reaches COMPLETE with all entities matched.
const completedPoll = await waitForDeliverabilityPoll(
createdTest.id,
(poll) =>
poll.test.status === 'COMPLETE' &&
poll.test.matchedEntities === 2 &&
poll.test.unmatchedEntities === 0,
240_000,
currentStep
);
expect(completedPoll.test.completionPercentage).toEqual(100);
Example: fetch test results
// Fetch final result rows and verify each selected inbox satisfied the expectation.
const finalResults = await deliverabilityTestController.getDeliverabilityTestResults({
testId: createdTest.id,
size: 50
});
expect(finalResults.content.length).toEqual(2);
expect(finalResults.test.status).toEqual('COMPLETE');
expect(finalResults.test.matchedEntities).toEqual(2);
expect(finalResults.test.unmatchedEntities).toEqual(0);
expect(finalResults.content.map((result) => result.entityId).sort()).toEqual(
[inboxA.id!, inboxB.id!].sort()
);
for (const result of finalResults.content) {
expect(result.matched).toEqual(true);
expect(result.matchedExpectationCount).toEqual(result.totalExpectationCount);
expect(result.expectationResults.length).toEqual(1);
expect(result.expectationResults[0].passed).toEqual(true);
expect(result.expectationResults[0].actualCount).toBeGreaterThanOrEqual(1);
}
Use unmatched-only views first when triaging failures. That is the fastest way to find which inboxes or phone numbers missed expectations.
Recommended operating model
- Define a small cohort and strict expectations.
- Verify sender and subject filters before launch.
- Expand the test to the broader release or campaign segment.
- Pair the results with monitoring if the send will continue after launch.
Related docs
Load testing with k6, JMeter and Locust
Separate traffic generation from receipt evaluation. Your load tool drives the application; the MailSlurp test records whether the selected inboxes or phones receive the expected messages. A MailSlurp simulation can exercise delivery infrastructure, while an external send from your application measures that application's full sending path.
| Tool | Start here | What to add for your workload |
|---|---|---|
| k6 | Email signup example | Configure virtual users/stages and thresholds; the sample defaults to one iteration. |
| JMeter | Email load example | Set the thread count, ramp and expected recipients for your application. |
| JMeter SMS | Delivery and simulation guide | Choose EXTERNAL for your own sender or SIMULATOR for generated traffic; exclude the simulation sender from targets. |
| Locust | Python example | Configure user count and spawn rate, and record message-wait duration separately from the signup HTTP request. |
Use the dashboard walkthrough to configure the same cohorts manually. Give each worker an inbox or phone lease when testing individual authentication journeys; use explicit cohort IDs when evaluating delivery across a fixed set.
Set the measurement window
Create and start the delivery test before triggering traffic. Set a maximum duration that includes the load ramp and expected delivery lag. Use exact sender, recipient and subject expectations to avoid counting unrelated messages. Keep API rate limits and available message/phone allowances in view when choosing concurrency.
Record request-to-receipt timing in the load harness if latency is an acceptance criterion. A cohort meeting its count expectation does not by itself establish a p95 delivery-latency target. Do not count a successful send API response as proof of receipt.
Pause, stop and export
Use a bounded polling interval; status evaluation has a five-second cache window. Stop a test deliberately when the job is abandoned, and inspect unmatched results before retrying. Export terminal test reports for the build and use CSV for per-entity analysis.
/test/deliverability/{testId}/status
Poll load-test status
Poll test progress. Evaluation is throttled with a 5-second cache window to protect backing data stores.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
testId | string:uuid | Yes |
Responses
| Status | Schema | Description |
|---|---|---|
200 | DeliverabilityPollStatusResultDto | OK |
HTTP examples
HTTP
GET /test/deliverability/00000000-0000-4000-8000-000000000000/status 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/test/deliverability/00000000-0000-4000-8000-000000000000/status' \
--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/test/deliverability/00000000-0000-4000-8000-000000000000/status", {
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/test/deliverability/00000000-0000-4000-8000-000000000000/status")
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()
/test/deliverability/{testId}/results
Get load-test entity results
Get paged per-entity expectation results with optional matched/unmatched filtering.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
testId | string:uuid | Yes |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
matched | boolean | No | |
page | integer:int32 | No | |
size | integer:int32 | No | |
sort | enum: ASC | DESC | No | Values: ASC, DESC |
Responses
| Status | Schema | Description |
|---|---|---|
200 | DeliverabilityEntityResultPageDto | OK |
HTTP examples
HTTP
GET /test/deliverability/00000000-0000-4000-8000-000000000000/results 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/test/deliverability/00000000-0000-4000-8000-000000000000/results' \
--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/test/deliverability/00000000-0000-4000-8000-000000000000/results", {
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/test/deliverability/00000000-0000-4000-8000-000000000000/results")
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()
/test/deliverability/{testId}/results/export
Export load-test entity results as CSV
Export per-entity deliverability results including expectation-level pass/fail counts. The latest status is evaluated with the same polling safeguards before export.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
testId | string:uuid | Yes |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
matched | boolean | No |
Responses
| Status | Schema | Description |
|---|---|---|
200 | Response | OK |
HTTP examples
HTTP
GET /test/deliverability/00000000-0000-4000-8000-000000000000/results/export 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/test/deliverability/00000000-0000-4000-8000-000000000000/results/export' \
--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/test/deliverability/00000000-0000-4000-8000-000000000000/results/export", {
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/test/deliverability/00000000-0000-4000-8000-000000000000/results/export")
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()
/test/deliverability/{testId}/report/export
Export load-test report as PDF
Export a PDF report for a terminal load test (COMPLETE, FAILED, or STOPPED), including configuration, summary outcomes, and detailed entity-level results.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
testId | string:uuid | Yes |
Responses
| Status | Schema | Description |
|---|---|---|
200 | Response | OK |
HTTP examples
HTTP
GET /test/deliverability/00000000-0000-4000-8000-000000000000/report/export 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/test/deliverability/00000000-0000-4000-8000-000000000000/report/export' \
--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/test/deliverability/00000000-0000-4000-8000-000000000000/report/export", {
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/test/deliverability/00000000-0000-4000-8000-000000000000/report/export")
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()
Simulation jobs have their own lifecycle and progress. Keep their ID alongside the delivery test ID, and stop or cancel the simulation when you no longer want it to send traffic.
/test/deliverability/{testId}/simulation-jobs
Create deliverability simulation job
Create and start a simulation job for a running load test. Only one active simulation job is allowed per user.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
testId | string:uuid | Yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
senderInboxId | string:uuid | No | Sender inbox ID for INBOX scope tests |
senderPhoneId | string:uuid | No | Sender phone ID for PHONE scope tests |
email | DeliverabilitySimulationEmailOptions | No | |
sms | DeliverabilitySimulationSmsOptions | No | |
delayMs | integer:int64 | No | Delay between individual sends in milliseconds |
batchSize | integer:int32 | No | Maximum sends processed per scheduler batch |
sendsPerTarget | integer:int64 | No | Optional fixed sends per target. If omitted this is derived from test expectations. |
{
"senderInboxId": "00000000-0000-4000-8000-000000000000",
"senderPhoneId": "00000000-0000-4000-8000-000000000000",
"email": {
"fromOverride": "value",
"subject": "Hello from MailSlurp",
"bodyTemplate": "Hello from MailSlurp"
},
"sms": {
"bodyTemplate": "Hello from MailSlurp"
},
"delayMs": 250,
"batchSize": 10
}
Responses
| Status | Schema | Description |
|---|---|---|
200 | DeliverabilitySimulationJobDto | OK |
HTTP examples
HTTP
POST /test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs HTTP/1.1
Host: api.mailslurp.com
x-api-key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
{}
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' '{}'
} > "$request_body"
status=$(curl --silent --show-error \
--request POST \
--url 'https://api.mailslurp.com/test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs' \
--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("{}", "utf8")
]);
const response = await fetch("https://api.mailslurp.com/test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs", {
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/test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs")
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
"Accept": "*/*"
}
body = b"".join([
"{}".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()
/test/deliverability/{testId}/simulation-jobs/{jobId}/cancel
Cancel deliverability simulation job
Cancel a running or paused simulation job.
Request, parameters, and responses
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
testId | string:uuid | Yes | |
jobId | string:uuid | Yes |
Responses
| Status | Schema | Description |
|---|---|---|
200 | DeliverabilitySimulationJobDto | OK |
HTTP examples
HTTP
POST /test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs/00000000-0000-4000-8000-000000000000/cancel 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/test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs/00000000-0000-4000-8000-000000000000/cancel' \
--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/test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs/00000000-0000-4000-8000-000000000000/cancel", {
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/test/deliverability/00000000-0000-4000-8000-000000000000/simulation-jobs/00000000-0000-4000-8000-000000000000/cancel")
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()
Use inbox placement for real provider folder outcomes. Use these load tests for receipt expectations across your selected MailSlurp inboxes and phones.
Running this code needs an API key. Get one free