Choose the domain a site sends email from
set_site_email_sending_domain
Chooses the domain a site sends its email from, one of its verified email domains or its built-in sending domain.
Pass the domain exactly as emailDomains.items in get_site_email_settings lists it, or an empty string for the built-in sending domain. Always pass domain, even as an empty string, because leaving it out is refused with Enter a valid domain, such as example.com!
The part in front of the @ (fromLocal) stays the same, so every later message goes out from that part at the new domain. That resets how mailboxes recognize the site, so the tool tells the client to change it only when you ask.
Only a verified domain can be chosen, and any other is refused with Only a verified email domain can send email! Should a chosen domain stop being verified later, the site sends from its built-in address until it is verified again, which fromFallback reports. Replies to an address on the chosen domain reach that domain's own mailboxes unless receiving is on for it or a reply-to is set.
It needs the Manage domains permission and works on every plan, except that a paused domain cannot be chosen and is refused with Email domains are paused until the workspace is on a paid plan again! See Choose the domain the site sends from.
Request
Call it with a POST to https://api.modulify.ai/v1/set_site_email_sending_domain, sending the inputs below as a JSON object. The token needs the config:write scope.
It makes changes, so send an Idempotency-Key header whenever you might retry it. A retry with the same key gets the first answer back instead of running again.
curl -X POST https://api.modulify.ai/v1/set_site_email_sending_domain \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"projectId":"PROJECT_ID"}'Over MCP, the same method is the set_site_email_sending_domain tool.
Inputs
| Input | Type | Required | Description |
|---|---|---|---|
projectId |
string | Yes | The site id. |
domain |
string | No | A verified email domain of the site, as emailDomains.items lists it, or an empty string to send from the built-in sending domain. Always pass it, because leaving it out is refused. |
Response
Every call answers with the JSON envelope of success, message, data, code and version. data holds the result described above, and on a method that returns a total, count carries it. The response headers carry the call's X-Request-Id and what is left of your per-minute budget in X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Errors explains every status code a call can answer with.