Inbound API methods
Sidemail enables you to receive emails on your verified domains via inbound routes. An inbound route defines which email addresses on your domain should accept incoming mail and how they should respond. When a matching email arrives, Sidemail stores it and optionally fires an email.received webhook.
Available API endpoints:
GET https://api.sidemail.io/v1/inbound/routes— List all inbound routesPOST https://api.sidemail.io/v1/inbound/routes— Create an inbound routePATCH https://api.sidemail.io/v1/inbound/routes/{routeId}— Update an inbound routeDELETE https://api.sidemail.io/v1/inbound/routes/{routeId}— Delete an inbound routeGET https://api.sidemail.io/v1/inbound/emails— List received emailsGET https://api.sidemail.io/v1/inbound/emails/{receivedEmailId}— Retrieve a received email
Inbound Route Object
An inbound route object represents a rule for accepting inbound email on a specific domain and address.
id(string): Unique identifier of the inbound route.domain(string): The domain to receive email on (e.g., "example.com"). Must be a verified domain or its subdomain.localPart(string): The local part before the@sign. Use"*"for a catch-all route that accepts all addresses on the domain.isCatchAll(boolean): Whether the route is a catch-all (i.e.localPartis"*").responseMode(string): How the mail server responds during the SMTP transaction. One of"accept","reject-temp","reject-perm".isEnabled(boolean): Whether the route is active.createdAt(string): ISO8601 date string when the route was created.updatedAt(string): ISO8601 date string when the route was last updated.
Example Inbound Route Object
{
"id": "67e4f2b6d4b7a63a0f6f2e11",
"domain": "example.com",
"localPart": "*",
"isCatchAll": true,
"responseMode": "accept",
"isEnabled": true,
"createdAt": "2026-03-27T12:00:00.000Z",
"updatedAt": "2026-03-27T12:00:00.000Z"
}
Received Email Object
A received email object represents a single inbound email received by Sidemail.
id(string): Unique identifier of the received email.destination(string): The SMTP envelope recipient address that matched the inbound route.from(object): Sender information withemail(string) andname(string or null).to(array): Header "To" recipients. Each item hasemailandname.cc(array): Header "Cc" recipients. Each item hasemailandname.replyTo(array): Header "Reply-To" addresses. Each item hasemailandname.subject(string): Email subject line.text(string): Plain text body of the email.htmlAvailable(boolean): Whether the email contains an HTML part.attachments(array): Attachment metadata. Each item hasname(string),contentType(string), andsize(number, bytes).headers(object): Raw email headers.auth(object): Authentication results (SPF, DKIM, etc.).envelope(object): SMTP envelope data.inboundRouteId(string): Identifier of the inbound route that matched.spam(object): Spam analysis results withscore(number),threshold(number),isSpam(boolean),action(string), andsymbols(array of strings).receivedAt(string): ISO8601 date string when the email was received.previewHtmlUrl(string or null): Opaque short-lived URL to preview the HTML version. Present only whenhtmlAvailableis true.rawEmailUrl(string or null): Opaque short-lived signed URL to download the raw email (RFC 822).
Example Received Email Object
{
"id": "67e4f2b6d4b7a63a0f6f2e11",
"destination": "[email protected]",
"from": { "email": "[email protected]", "name": "John" },
"to": [{ "email": "[email protected]", "name": "Support" }],
"cc": [{ "email": "[email protected]", "name": null }],
"replyTo": [{ "email": "[email protected]", "name": "Billing" }],
"subject": "Invoice Q1",
"text": "Hello, please find invoice attached...",
"htmlAvailable": true,
"attachments": [
{ "name": "invoice-q1.pdf", "contentType": "application/pdf", "size": 84320 }
],
"headers": {},
"auth": {},
"envelope": {},
"inboundRouteId": "67e4f2b6d4b7a63a0f6f2e10",
"spam": {
"score": 2.4,
"threshold": 15,
"isSpam": false,
"action": "accept",
"symbols": ["R_SPF_ALLOW", "R_DKIM_ALLOW", "MIME_GOOD"]
},
"receivedAt": "2026-03-27T12:01:18.921Z",
"previewHtmlUrl": "https://signed-url.example/...",
"rawEmailUrl": "https://signed-url.example/..."
}
List all inbound routes
GET https://api.sidemail.io/v1/inbound/routes
Returns a list of all inbound routes in the project.
curl https://api.sidemail.io/v1/inbound/routes \
-H "Authorization: Bearer replace-with-your-api-key"
Response:
{
"data": [
{
"id": "67e4f2b6d4b7a63a0f6f2e11",
"domain": "example.com",
"localPart": "*",
"isCatchAll": true,
"responseMode": "accept",
"isEnabled": true,
"createdAt": "2026-03-27T12:00:00.000Z",
"updatedAt": "2026-03-27T12:00:00.000Z"
}
]
}
Create an inbound route
POST https://api.sidemail.io/v1/inbound/routes
Creates a new inbound route. The domain must be a verified domain in your project, or a subdomain of one.
curl -X POST https://api.sidemail.io/v1/inbound/routes \
-H "Content-Type: application/json" \
-H "Authorization: Bearer replace-with-your-api-key" \
-d '{
"domain": "example.com",
"localPart": "*",
"responseMode": "accept",
"isEnabled": true
}'
Parameters:
domain(string, required): The domain to receive email on. Must be a verified domain or its subdomain.localPart(string, optional, default:"*"): The local part of the email address (before@). Use"*"to create a catch-all route. Maximum 128 characters. Cannot contain@.responseMode(string, optional, default:"accept"): How the mail server should respond. One of:"accept"— Accept and store the email."reject-temp"— Temporarily reject (4xx SMTP response). The sending server may retry."reject-perm"— Permanently reject (5xx SMTP response).
isEnabled(boolean, optional, default:true): Whether the route should be active.
Response:
{
"created": {
"id": "67e4f2b6d4b7a63a0f6f2e11",
"domain": "example.com",
"localPart": "*",
"isCatchAll": true,
"responseMode": "accept",
"isEnabled": true,
"createdAt": "2026-03-27T12:00:00.000Z",
"updatedAt": "2026-03-27T12:00:00.000Z"
}
}
Update an inbound route
PATCH https://api.sidemail.io/v1/inbound/routes/:routeId
Updates an existing inbound route. You can change responseMode and isEnabled. At least one field must be provided.
curl -X PATCH https://api.sidemail.io/v1/inbound/routes/67e4f2b6d4b7a63a0f6f2e11 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer replace-with-your-api-key" \
-d '{
"responseMode": "reject-perm",
"isEnabled": false
}'
Parameters:
responseMode(string, optional): One of"accept","reject-temp","reject-perm".isEnabled(boolean, optional): Whether the route is active.
Response:
{
"updated": {
"id": "67e4f2b6d4b7a63a0f6f2e11",
"domain": "example.com",
"localPart": "*",
"isCatchAll": true,
"responseMode": "reject-perm",
"isEnabled": false,
"createdAt": "2026-03-27T12:00:00.000Z",
"updatedAt": "2026-03-27T12:05:00.000Z"
}
}
Delete an inbound route
DELETE https://api.sidemail.io/v1/inbound/routes/:routeId
Deletes an inbound route. Existing received emails are not affected.
curl -X DELETE https://api.sidemail.io/v1/inbound/routes/67e4f2b6d4b7a63a0f6f2e11 \
-H "Authorization: Bearer replace-with-your-api-key"
Response:
{
"deleted": true
}
List received emails
GET https://api.sidemail.io/v1/inbound/emails
Returns a paginated list of received inbound emails, sorted by most recent first.
curl "https://api.sidemail.io/v1/inbound/emails?limit=20" \
-H "Authorization: Bearer replace-with-your-api-key"
Parameters:
limit(number, optional, default:20): Number of results to return. Min 1, max 100.paginationCursorNext(string, optional): Cursor for fetching the next page of results.paginationCursorPrev(string, optional): Cursor for fetching the previous page of results.
Response:
{
"data": [
{
"id": "67e4f2b6d4b7a63a0f6f2e11",
"destination": "[email protected]",
"from": { "email": "[email protected]", "name": "John" },
"to": [{ "email": "[email protected]", "name": "Support" }],
"cc": [],
"replyTo": [],
"subject": "Invoice Q1",
"receivedAt": "2026-03-27T12:01:18.921Z",
"spam": { "score": 2.4 },
"inboundRouteId": "67e4f2b6d4b7a63a0f6f2e10"
}
],
"hasMore": false,
"paginationCursorNext": null,
"paginationCursorPrev": null,
"limit": 20
}
The list endpoint returns a summary of each email. To get the full email detail including body, attachments, and spam analysis, use the retrieve endpoint.
Retrieve a received email
GET https://api.sidemail.io/v1/inbound/emails/:receivedEmailId
Returns the full detail of a single received email, including text body, attachment metadata, spam analysis, and short-lived preview/download URLs.
curl https://api.sidemail.io/v1/inbound/emails/67e4f2b6d4b7a63a0f6f2e11 \
-H "Authorization: Bearer replace-with-your-api-key"
Response:
{
"id": "67e4f2b6d4b7a63a0f6f2e11",
"destination": "[email protected]",
"from": { "email": "[email protected]", "name": "John" },
"to": [{ "email": "[email protected]", "name": "Support" }],
"cc": [{ "email": "[email protected]", "name": null }],
"replyTo": [{ "email": "[email protected]", "name": "Billing" }],
"subject": "Invoice Q1",
"text": "Hello, please find invoice attached...",
"htmlAvailable": true,
"attachments": [
{ "name": "invoice-q1.pdf", "contentType": "application/pdf", "size": 84320 }
],
"headers": {},
"auth": {},
"envelope": {},
"inboundRouteId": "67e4f2b6d4b7a63a0f6f2e10",
"spam": {
"score": 2.4,
"threshold": 15,
"isSpam": false,
"action": "accept",
"symbols": ["R_SPF_ALLOW", "R_DKIM_ALLOW", "MIME_GOOD"]
},
"receivedAt": "2026-03-27T12:01:18.921Z",
"previewHtmlUrl": "https://signed-url.example/...",
"rawEmailUrl": "https://signed-url.example/..."
}
previewHtmlUrl and rawEmailUrl are short-lived. Fetch fresh URLs by calling this endpoint again when needed.
To access attachment content, download the raw email via rawEmailUrl and parse it with a MIME parser (e.g., mailparser for Node.js). The attachments array in the response contains metadata only (name, content type, size in bytes).
Webhooks
When an inbound route receives an email, Sidemail fires an email.received webhook event. See the webhooks documentation for setup instructions and the full event payload.