Relay REST API

Relay API

Scoped REST API for programmable inbound email inboxes. Create inboxes, read messages, extract authentication artifacts, receive SSE events, and manage signed webhooks.

Version 1.0.0 · Base URL https://www.relaymcp.net/api/v1

Authentication

Create a key in Relay Account settings. Keys are shown once and never stored in plaintext.

Send Authorization: Bearer rl_live_... on every request. Keys are created on /account and shown once.

GET/domains

List available Free mail domains

Auth: Bearer API key with inboxes:read.

200 Available domains. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/domainsrequest.sh
curl "https://www.relaymcp.net/api/v1/domains" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/inboxes

List the authenticated account's inboxes

Auth: Bearer API key with inboxes:read.

ParameterInRequiredDescription
cursorqueryNoCursor returned by the previous page.

200 Cursor-paginated inboxes. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxesrequest.sh
curl "https://www.relaymcp.net/api/v1/inboxes?cursor=CURSOR" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
POST/inboxes

Create an inbox

Auth: Bearer API key with inboxes:write.

Request body

Optional

{
  "name": "build-checks",
  "domain": "mail.example.net"
}

201 Created inbox. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

503 No active mail domain is available. · application/json

POST/inboxesrequest.sh
curl -X POST "https://www.relaymcp.net/api/v1/inboxes" \  -H "Authorization: Bearer $RELAY_API_KEY" \  -H "Content-Type: application/json" \  -d '{"name":"build-checks","domain":"mail.example.net"}'

Try request

Sends a live call to the production API from this page.
GET/inboxes/{inboxId}

Get inbox metadata

Auth: Bearer API key with inboxes:read.

ParameterInRequiredDescription
inboxIdpathYesInbox ID.

200 Inbox metadata. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxes/{inboxId}request.sh
curl "https://www.relaymcp.net/api/v1/inboxes/INBOX_ID" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/inboxes/{inboxId}/attachments/{attachmentId}

Download an attachment

Auth: Bearer API key with messages:read.

ParameterInRequiredDescription
inboxIdpathYesInbox ID.
attachmentIdpathYesAttachment ID.

200 Binary attachment. · application/octet-stream

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxes/{inboxId}/attachments/{attachmentId}request.sh
curl "https://www.relaymcp.net/api/v1/inboxes/INBOX_ID/attachments/ATTACHMENT_ID" \  -H "Authorization: Bearer $RELAY_API_KEY" \  -o "attachment.bin"

Use the sample request for streaming or binary responses in your terminal or HTTP client.

GET/inboxes/{inboxId}/messages

List message previews

Auth: Bearer API key with messages:read.

ParameterInRequiredDescription
inboxIdpathYesInbox ID.
limitqueryNoNumber of messages to return.
cursorqueryNoCursor returned by the previous page.

200 Message preview page. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxes/{inboxId}/messagesrequest.sh
curl "https://www.relaymcp.net/api/v1/inboxes/INBOX_ID/messages?limit=30&cursor=CURSOR" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/inboxes/{inboxId}/messages/{messageId}

Read a full message

Auth: Bearer API key with messages:read.

ParameterInRequiredDescription
inboxIdpathYesInbox ID.
messageIdpathYesMessage ID.

200 Full message with sanitized HTML and attachment metadata. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxes/{inboxId}/messages/{messageId}request.sh
curl "https://www.relaymcp.net/api/v1/inboxes/INBOX_ID/messages/MESSAGE_ID" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/inboxes/{inboxId}/messages/{messageId}/auth

Extract OTP and authentication links

Auth: Bearer API key with messages:read.

ParameterInRequiredDescription
inboxIdpathYesInbox ID.
messageIdpathYesMessage ID.

200 Authentication artifact extraction result. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxes/{inboxId}/messages/{messageId}/authrequest.sh
curl "https://www.relaymcp.net/api/v1/inboxes/INBOX_ID/messages/MESSAGE_ID/auth" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/inboxes/{inboxId}/messages/{messageId}/otp

Extract a one-time password

Auth: Bearer API key with messages:read.

ParameterInRequiredDescription
inboxIdpathYesInbox ID.
messageIdpathYesMessage ID.

200 OTP extraction result. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/inboxes/{inboxId}/messages/{messageId}/otprequest.sh
curl "https://www.relaymcp.net/api/v1/inboxes/INBOX_ID/messages/MESSAGE_ID/otp" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/events

Stream account events over SSE

Connections last up to ten minutes and poll at five-second intervals while the client consumes events. Keys and scopes are revalidated per poll. At most three streams per account are allowed in each server process. Resume after disconnection using the last numeric event ID.

Auth: Bearer API key with events:read.

ParameterInRequiredDescription
afterqueryNoLast event ID already received.
limitqueryNoUpper bound per poll; responses may contain fewer events to respect server byte and batch limits.

200 text/event-stream containing typed events and heartbeat events. · text/event-stream

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/eventsrequest.sh
curl "https://www.relaymcp.net/api/v1/events?after=0&limit=100" \  -H "Authorization: Bearer $RELAY_API_KEY"

Use the sample request for streaming or binary responses in your terminal or HTTP client.

GET/webhooks

List webhook endpoints

Auth: Bearer API key with webhooks:read.

200 Webhook endpoints. The signing secret is never returned after creation. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/webhooksrequest.sh
curl "https://www.relaymcp.net/api/v1/webhooks" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
POST/webhooks

Create a signed webhook endpoint

Auth: Bearer API key with webhooks:write.

Request body

Required

{
  "url": "https://hooks.example.com/relay",
  "events": [
    "inbox.message.received"
  ]
}

201 Created webhook. Save the one-time secret. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

POST/webhooksrequest.sh
curl -X POST "https://www.relaymcp.net/api/v1/webhooks" \  -H "Authorization: Bearer $RELAY_API_KEY" \  -H "Content-Type: application/json" \  -d '{"url":"https://hooks.example.com/relay","events":["inbox.message.received"]}'

Try request

Sends a live call to the production API from this page.
DELETE/webhooks/{webhookId}

Delete a webhook endpoint

Auth: Bearer API key with webhooks:write.

ParameterInRequiredDescription
webhookIdpathYesWebhook ID.

200 Webhook deleted. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

DELETE/webhooks/{webhookId}request.sh
curl -X DELETE "https://www.relaymcp.net/api/v1/webhooks/WEBHOOK_ID" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.
GET/webhooks/{webhookId}

List webhook delivery history

Auth: Bearer API key with webhooks:read.

ParameterInRequiredDescription
webhookIdpathYesWebhook ID.

200 Recent deliveries. · application/json

400 Invalid request. · application/json

401 Missing, invalid, revoked, or expired API key. · application/json

403 The API key does not have the required scope or access. · application/json

404 Resource not found. · application/json

409 The requested resource conflicts with an existing resource. · application/json

429 Rate limit exceeded. · application/json

GET/webhooks/{webhookId}request.sh
curl "https://www.relaymcp.net/api/v1/webhooks/WEBHOOK_ID" \  -H "Authorization: Bearer $RELAY_API_KEY"

Try request

Sends a live call to the production API from this page.

Schemas

Component schemas from the OpenAPI document.

Error

ErrorError.json
{  "error": "string",  "code": "string"}

Domain

DomainDomain.json
{  "id": "string",  "name": "string",  "tier": "free"}

Inbox

InboxInbox.json
{  "id": "string",  "address": "string",  "owned": true}

CreateInboxRequest

CreateInboxRequestCreateInboxRequest.json
{  "name": "string",  "domain": "string"}

InboxPage

InboxPageInboxPage.json
{  "inboxes": [    {      "id": "string",      "address": "string",      "owned": true    }  ],  "nextCursor": null}

MessagePreview

MessagePreviewMessagePreview.json
{  "id": "string",  "sender": null,  "sender_address": null,  "subject": null,  "preview": null,  "created": 0,  "time": "2026-01-01T00:00:00.000Z",  "size_bytes": 0,  "source": null,  "attachment_count": 0}

Message

MessageMessage.json
{  "id": "string",  "sender": null,  "sender_address": null,  "subject": null,  "preview": null,  "created": 0,  "time": "2026-01-01T00:00:00.000Z",  "size_bytes": 0,  "source": null,  "attachment_count": 0,  "recipient": null,  "body": null,  "html": null,  "message_id": null,  "attachments": [    {      "id": null,      "filename": null,      "content_type": null,      "size_bytes": null,      "sha256": null    }  ]}

MessagePage

MessagePageMessagePage.json
{  "messages": [    {      "id": "string",      "sender": null,      "sender_address": null,      "subject": null,      "preview": null,      "created": 0,      "time": "2026-01-01T00:00:00.000Z",      "size_bytes": 0,      "source": null,      "attachment_count": 0    }  ],  "nextCursor": null}

Attachment

AttachmentAttachment.json
{  "id": "string",  "filename": "string",  "content_type": "string",  "size_bytes": 0,  "sha256": "string"}

OtpResult

OtpResultOtpResult.json
{  "found": true,  "ambiguous": true,  "code": null,  "confidence": "none"}

AuthArtifacts

AuthArtifactsAuthArtifacts.json
{  "otp": {    "found": true,    "ambiguous": true,    "code": null,    "confidence": "none"  },  "links": [    "string"  ],  "magicLink": null}

CreateWebhookRequest

CreateWebhookRequestCreateWebhookRequest.json
{  "url": "string",  "events": [    "string"  ]}

Webhook

WebhookWebhook.json
{  "id": "string",  "url": "string",  "events": [    "string"  ],  "active": true,  "created": 0,  "updated": 0}

CreatedWebhook

CreatedWebhookCreatedWebhook.json
{  "id": "string",  "url": "string",  "events": [    "string"  ],  "active": true,  "created": 0,  "updated": 0,  "secret": "string"}

WebhookDelivery

WebhookDeliveryWebhookDelivery.json
{  "id": "string",  "endpoint_id": "string",  "event_id": 0,  "attempt": 0,  "state": "string",  "next_attempt": null,  "response_status": null,  "last_error": null,  "created": 0,  "delivered": null}

Machine-readable contract: /openapi.json

FROM THE COLLECTIONS

Implementation guides and deeper context

Longer technical guides that expand on the API reference, MCP tools, security model, and testing patterns.