Examples use fictional data. Every company, person, address and count in them is invented, and their domains use the reserved .example TLD.
Autopilot
Sending
Domains, mailboxes and suppressions. Salvo warms new domains for you and refuses to send faster than a domain has earned.
10 endpoints
/v1/domainsList sending domains
Domains with DNS state, warm-up day, reputation and the daily ceiling each one currently allows.
curl "https://beamro.com/api/v1/domains" \
-H "x-api-key: $SALVO_API_KEY"{
"rows": [
{
"id": "dom_3k8v1n6m0q4x7b2t9w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"domain": "outreach-harlowmeadow.example",
"status": "warming",
"pool": "dedicated",
"dns": {
"spf": true,
"dkim": true,
"dmarc": true,
"mx": true,
"tracking_cname": false
},
"dns_records": [
{
"type": "TXT",
"host": "@",
"value": "v=spf1 include:spf.salvo.example ~all",
"ok": true
},
{
"type": "CNAME",
"host": "salvo._domainkey",
"value": "dkim.salvo.example",
"ok": true
},
{
"type": "TXT",
"host": "_dmarc",
"value": "v=DMARC1; p=none; rua=mailto:dmarc@outreach-harlowmeadow.example",
"ok": true
},
{
"type": "CNAME",
"host": "link",
"value": "track.salvo.example",
"ok": false
}
],
"warmup_day": 11,
"reputation": 94,
"daily_limit": 60,
"created_at": "2026-08-20T10:00:00.000Z"
}
]
}/v1/domainsAdd a sending domain
Registers a domain and returns the DNS records to publish. Use a separate domain from the one you receive business mail on — that is the whole point of the exercise.
Body parameters
| Field | Type | Description |
|---|---|---|
| domainreq | string | Domain to send from, e.g. outreach-yourbrand.example. |
| pool | string | shared (default) or dedicated. Dedicated pools warm slower and land harder. |
curl -X POST "https://beamro.com/api/v1/domains" \
-H "x-api-key: $SALVO_API_KEY" \
-H "content-type: application/json" \
-d '{
"domain": "outreach-harlowmeadow.example",
"pool": "dedicated"
}'{
"id": "dom_3k8v1n6m0q4x7b2t9w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"domain": "outreach-harlowmeadow.example",
"status": "dns_pending",
"pool": "dedicated",
"dns": {
"spf": false,
"dkim": false,
"dmarc": false,
"mx": false,
"tracking_cname": false
},
"dns_records": [
{
"type": "TXT",
"host": "@",
"value": "v=spf1 include:spf.salvo.example ~all",
"ok": false
},
{
"type": "CNAME",
"host": "salvo._domainkey",
"value": "dkim.salvo.example",
"ok": false
},
{
"type": "TXT",
"host": "_dmarc",
"value": "v=DMARC1; p=none; rua=mailto:dmarc@outreach-harlowmeadow.example",
"ok": false
},
{
"type": "CNAME",
"host": "link",
"value": "track.salvo.example",
"ok": false
}
],
"warmup_day": 0,
"reputation": 0,
"daily_limit": 0,
"created_at": "2026-08-20T10:00:00.000Z"
}/v1/domains/{domain_id}/verifyVerify DNS
Re-checks every record and flips the domain into warming once SPF, DKIM, DMARC and MX all pass.
Path parameters
| Field | Type | Description |
|---|---|---|
| domain_idreq | string | Domain identifier. |
curl -X POST "https://beamro.com/api/v1/domains/dom_3k8v1n6m0q4x7b2t9w/verify" \
-H "x-api-key: $SALVO_API_KEY"{
"id": "dom_3k8v1n6m0q4x7b2t9w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"domain": "outreach-harlowmeadow.example",
"status": "warming",
"pool": "dedicated",
"dns": {
"spf": true,
"dkim": true,
"dmarc": true,
"mx": true,
"tracking_cname": false
},
"dns_records": [
{
"type": "TXT",
"host": "@",
"value": "v=spf1 include:spf.salvo.example ~all",
"ok": true
},
{
"type": "CNAME",
"host": "salvo._domainkey",
"value": "dkim.salvo.example",
"ok": true
},
{
"type": "TXT",
"host": "_dmarc",
"value": "v=DMARC1; p=none; rua=mailto:dmarc@outreach-harlowmeadow.example",
"ok": true
},
{
"type": "CNAME",
"host": "link",
"value": "track.salvo.example",
"ok": false
}
],
"warmup_day": 11,
"reputation": 94,
"daily_limit": 60,
"created_at": "2026-08-20T10:00:00.000Z"
}/v1/mailboxesList mailboxes
Every mailbox, its health score and how much of today it has already used.
curl "https://beamro.com/api/v1/mailboxes" \
-H "x-api-key: $SALVO_API_KEY"{
"rows": [
{
"id": "mbx_5k2v8n1q4x7m0b3t6w",
"domain_id": "dom_3k8v1n6m0q4x7b2t9w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"email": "devon@outreach-harlowmeadow.example",
"display_name": "Devon Aikhurst",
"provider": "smtp",
"daily_limit": 40,
"sent_today": 18,
"health": 97,
"status": "warming",
"last_error": null,
"created_at": "2026-08-20T10:04:00.000Z"
}
]
}/v1/mailboxesAdd a mailbox
Attaches a sending identity to a verified domain. Daily limits are clamped to what the domain has warmed up to. A mailbox sends only through its own SMTP login — send the smtp object here, or add it later with Update a mailbox.
Body parameters
| Field | Type | Description |
|---|---|---|
| emailreq | string | Full address on a domain you have added. |
| domain_idreq | string | Domain this mailbox belongs to. |
| display_name | string | Name recipients see in the from line. |
| provider | string | smtp, gmail, outlook, postmark or ses. |
| daily_limit | number | Ceiling for this mailbox. Never exceeds the domain limit. |
| smtp | object | The SMTP login this mailbox sends through: host, port, user and password. All four are needed before it can send; the password is stored, never returned. |
| smtp.host | string | Your mail provider’s SMTP host, e.g. smtp.mailhost.example. Must be a public host. |
| smtp.port | number | 465 (TLS from the first byte), 587 or 2525 (STARTTLS), or 25. |
| smtp.user | string | The login name, usually the full mailbox address. |
| smtp.password | string | The password or app password for that login. |
curl -X POST "https://beamro.com/api/v1/mailboxes" \
-H "x-api-key: $SALVO_API_KEY" \
-H "content-type: application/json" \
-d '{
"email": "devon@outreach-harlowmeadow.example",
"domain_id": "dom_3k8v1n6m0q4x7b2t9w",
"display_name": "Devon Aikhurst",
"provider": "smtp",
"daily_limit": 40,
"smtp": {
"host": "smtp.mailhost.example",
"port": 465,
"user": "devon@outreach-harlowmeadow.example",
"password": "app-password-from-your-provider"
}
}'{
"id": "mbx_5k2v8n1q4x7m0b3t6w",
"domain_id": "dom_3k8v1n6m0q4x7b2t9w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"email": "devon@outreach-harlowmeadow.example",
"display_name": "Devon Aikhurst",
"provider": "smtp",
"daily_limit": 40,
"sent_today": 0,
"health": 100,
"status": "warming",
"last_error": null,
"created_at": "2026-08-20T10:04:00.000Z",
"needs_smtp": false
}needs_smtp: true, is left out of the sending rotation, and a campaign cannot start until at least one mailbox can send. The relay must be a public host that asks for the login (authentication is always required), and it may not be this platform’s own private relay — that is refused with a 400. Test a mailbox after saving its login to see the provider’s answer./v1/mailboxes/{mailbox_id}Update a mailbox
Pause a mailbox, rename the sender, lower the daily limit — or give it the SMTP login it sends through. A mailbox listed with needs_smtp: true cannot send until it has one.
Path parameters
| Field | Type | Description |
|---|---|---|
| mailbox_idreq | string | Mailbox identifier. |
Body parameters
| Field | Type | Description |
|---|---|---|
| display_name | string | Name in the from line. |
| daily_limit | number | New ceiling. |
| status | string | active, warming, paused or error. |
| smtp | object | The SMTP login this mailbox sends through: host, port, user and password. All four are needed before it can send; the password is stored, never returned. Only the fields you send change. |
| smtp.host | string | Your mail provider’s SMTP host, e.g. smtp.mailhost.example. Must be a public host. Only the fields you send change. |
| smtp.port | number | 465 (TLS from the first byte), 587 or 2525 (STARTTLS), or 25. Only the fields you send change. |
| smtp.user | string | The login name, usually the full mailbox address. Only the fields you send change. |
| smtp.password | string | The password or app password for that login. Only the fields you send change. |
curl -X PATCH "https://beamro.com/api/v1/mailboxes/mbx_5k2v8n1q4x7m0b3t6w" \
-H "x-api-key: $SALVO_API_KEY" \
-H "content-type: application/json" \
-d '{
"smtp": {
"host": "smtp.mailhost.example",
"port": 465,
"user": "devon@outreach-harlowmeadow.example",
"password": "app-password-from-your-provider"
}
}'{
"id": "mbx_5k2v8n1q4x7m0b3t6w",
"domain_id": "dom_3k8v1n6m0q4x7b2t9w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"email": "devon@outreach-harlowmeadow.example",
"display_name": "Devon Aikhurst",
"provider": "smtp",
"daily_limit": 40,
"sent_today": 18,
"health": 97,
"status": "warming",
"last_error": null,
"created_at": "2026-08-20T10:04:00.000Z",
"needs_smtp": false
}needs_smtp: true, is left out of the sending rotation, and a campaign cannot start until at least one mailbox can send. The relay must be a public host that asks for the login (authentication is always required), and it may not be this platform’s own private relay — that is refused with a 400. Test a mailbox after saving its login to see the provider’s answer./v1/mailboxes/{mailbox_id}/testTest a mailbox
Opens a real connection and sends a probe. Returns the provider error verbatim when it fails, which is usually what you need to fix it. A mailbox with no SMTP login of its own answers ok: false with code mailbox_not_configured.
Path parameters
| Field | Type | Description |
|---|---|---|
| mailbox_idreq | string | Mailbox identifier. |
curl -X POST "https://beamro.com/api/v1/mailboxes/mbx_5k2v8n1q4x7m0b3t6w/test" \
-H "x-api-key: $SALVO_API_KEY"{
"ok": true
}/v1/suppressionsList suppressions
Addresses and domains that will never be contacted again, and why — this workspace’s own entries, the platform rules, and platform-wide opt-outs for addresses this workspace has as leads or has written to. Every platform-wide opt-out is checked before every send, listed or not. Newest first.
Query parameters
| Field | Type | Description |
|---|---|---|
| q | string | Only entries whose address or domain contains this text. |
| limit | integer | 1–1000, default 200. |
| offset | integer | Entries to skip, for paging. |
curl "https://beamro.com/api/v1/suppressions" \
-H "x-api-key: $SALVO_API_KEY"{
"rows": [
{
"id": "sup_8n2k5v1q7x4m0b3t6w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"value": "marisol@stonecroftbarn.example",
"kind": "email",
"reason": "unsubscribe",
"created_at": "2026-08-22T16:04:11.000Z"
},
{
"id": "sup_1x7m4k0v9n2q6b3t8w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"value": "competitor.example",
"kind": "domain",
"reason": "manual",
"created_at": "2026-08-06T11:20:00.000Z"
}
],
"total": 2,
"limit": 100,
"offset": 0
}/v1/suppressionsAdd a suppression
Block an address or a whole domain. Takes effect immediately, including for mail already queued.
Body parameters
| Field | Type | Description |
|---|---|---|
| valuereq | string | Email address or bare domain. |
| kind | string | email (default) or domain. |
| reason | string | manual (default) or bounce. Unsubscribes and complaints are recorded by the recipient’s own action, not through this endpoint. |
curl -X POST "https://beamro.com/api/v1/suppressions" \
-H "x-api-key: $SALVO_API_KEY" \
-H "content-type: application/json" \
-d '{
"value": "competitor.example",
"kind": "domain",
"reason": "manual"
}'{
"id": "sup_1x7m4k0v9n2q6b3t8w",
"org_id": "org_4k1p8w2ne6ts0ybc7j",
"value": "competitor.example",
"kind": "domain",
"reason": "manual",
"created_at": "2026-08-31T12:41:09.000Z"
}/v1/suppressions/:idRemove a suppression
Removes an entry the workspace made itself (manual or bounce). A platform-wide opt-out answers 403 global_suppression_readonly, and a recipient’s own unsubscribe or complaint answers 403 objection_readonly — those are not the workspace’s to lift.
Path parameters
| Field | Type | Description |
|---|---|---|
| idreq | string | Suppression identifier from the list. |
curl -X DELETE "https://beamro.com/api/v1/suppressions/sup_1x7m4k0v9n2q6b3t8w" \
-H "x-api-key: $SALVO_API_KEY"{
"ok": true
}