Inbound addresses Live
Inbound addresses are the email addresses that, when emailed, become tickets in your workspace. Three flavours: an auto-generated address per workspace, custom localparts on our shared subdomain, or addresses on your own custom domain.
Address kinds
| Kind | Example | Setup |
|---|---|---|
auto | [email protected] | Created for every workspace on signup. Always works. |
subdomain | [email protected] | Pick any local-part; we route on the workspace subdomain. |
custom_domain | [email protected] | Requires a verified email domain. |
List addresses
All addresses configured in the workspace.
Code samples
curl 'https://app.message.com/api/v1/inbound-addresses' \
-H 'Authorization: Bearer YOUR_WORKSPACE_JWT'const res = await fetch('https://app.message.com/api/v1/inbound-addresses', {
headers: { Authorization: 'Bearer ' + token }
});
const { addresses } = await res.json();import requests
r = requests.get(
"https://app.message.com/api/v1/inbound-addresses",
headers={"Authorization": f"Bearer {token}"},
)
addresses = r.json()["addresses"]require "net/http"
require "json"
uri = URI("https://app.message.com/api/v1/inbound-addresses")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{token}"
http.request(req)
end
addresses = JSON.parse(res.body)["addresses"]<?php
$ctx = stream_context_create([
"http" => ["method" => "GET", "header" => "Authorization: Bearer $token"]
]);
$addresses = json_decode(file_get_contents("https://app.message.com/api/v1/inbound-addresses", false, $ctx), true)["addresses"];Create an address
| Field | Type | Description |
|---|---|---|
| kindrequired | enum | One of auto, subdomain, custom_domain. |
| localPartoptional | string | Subdomain only. The part before the @ sign. 1 to 64 chars. |
| addressoptional | string | Custom-domain only. Full address. The domain must be verified first. |
| departmentIdoptional | uuid | Route inbound mail at this address to this department. |
{
"kind": "subdomain",
"localPart": "support",
"departmentId": "uuid"
}{
"id": "uuid",
"kind": "subdomain",
"address": "[email protected]",
"departmentId": "uuid",
"verified": true,
"createdAt": "2026-05-13T15:30:00Z"
}Update routing
Change the department, or update the local-part on a subdomain address. The address string regenerates accordingly.
Delete an address
Mail to a deleted address bounces with a permanent failure. Existing tickets stay in the inbox.
Sending a test email
The fastest way to verify routing is to email the address from your phone. The inbound webhook fires within a few seconds; check Settings → Logs for the trace if nothing arrives. Most failures are SPF or DMARC misconfiguration on the sending side.
If you forward from Gmail or Microsoft 365, see the tutorials: Gmail forwarding and Microsoft 365 forwarding.
Errors
| Code | When |
|---|---|
400 invalid_body | Payload validation failed. |
409 conflict | An address with this local-part / address already exists. |
422 domain_unverified | Custom-domain address attempted without a verified domain. |
Common pitfalls
- Using a free email provider for the local-part on a custom domain. Forwarding from Gmail to message.com works; using a Gmail address as your inbound address does not. You need a domain you control.
- Forgetting SPF / DKIM / DMARC. Custom-domain inbound needs working DNS. The dashboard surfaces a checklist; verify all three are green.
- Routing to a deleted department. The inbound webhook will still create a ticket but it lands in the workspace queue, not a specific dept.