The research is ready for your review.
", "replyTo": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "metadata": { "taskId": "research-42" }, "delivery": { "submissionId": "00000000-0000-4000-8000-000000000001", "status": "submitted", "failureCode": null }, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z", "purpose": "transactional" } ], "nextCursor": null } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "410": { "$ref": "#/components/responses/Gone" }, "413": { "$ref": "#/components/responses/PayloadTooLarge" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/inboxes/$INBOX_ID/export\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/inboxes/${process.env.INBOX_ID}/export`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Get delivery metrics (/docs/api-reference/getDeliveryMetrics) GET /v1/metrics/delivery Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getDeliveryMetrics", "summary": "Get delivery metrics", "x-mailactor-required-scope": "delivery:read", "parameters": [ { "name": "hours", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 720, "default": 24 } } ], "responses": { "200": { "description": "Delivery metrics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliveryHealthMetrics" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/metrics/delivery\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/metrics/delivery`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Get a domain (/docs/api-reference/getDomain) GET /v1/domains/{domainId} Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getDomain", "summary": "Get a domain", "x-mailactor-required-scope": "domain:manage", "parameters": [ { "name": "domainId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Domain and DNS instructions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendingDomain" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/domains/$DOMAIN_ID\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/domains/${process.env.DOMAIN_ID}`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Get domain usage (/docs/api-reference/getDomainTraffic) GET /v1/domains/{domainId}/traffic Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getDomainTraffic", "summary": "Get domain usage", "x-mailactor-required-scope": "domain:manage", "parameters": [ { "name": "domainId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Domain traffic status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainTrafficView" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/domains/$DOMAIN_ID/traffic\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/domains/${process.env.DOMAIN_ID}/traffic`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Get an inbox (/docs/api-reference/getInbox) GET /v1/inboxes/{inboxId} Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getInbox", "summary": "Get an inbox", "x-mailactor-required-scope": "mailbox:read", "parameters": [ { "name": "inboxId", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/InboxId" } } ], "responses": { "200": { "description": "Inbox", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Inbox" }, "example": { "id": "inb_0123456789abcdef01234567", "localPart": "research-agent", "domainId": null, "domainKind": "managed", "domain": "inbox.mailactor.com", "address": "research-agent@inbox.mailactor.com", "displayName": "Research Agent", "status": "active", "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/inboxes/$INBOX_ID\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/inboxes/${process.env.INBOX_ID}`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Get a submission (/docs/api-reference/getSubmission) GET /v1/submissions/{submissionId} Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getSubmission", "summary": "Get a submission", "x-mailactor-required-scope": "delivery:read", "parameters": [ { "name": "submissionId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Delivery submission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliverySubmission" }, "example": { "id": "00000000-0000-4000-8000-000000000001", "from": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "recipients": [ { "email": "you@example.com", "status": "delivered", "response": "250 2.0.0 Message accepted", "updatedAt": "2026-09-08T12:01:00.000Z" } ], "subject": "Your research update", "metadata": { "taskId": "research-42" }, "status": "delivered", "queueId": "mailactor-example-queue", "response": "250 2.0.0 Message accepted", "failureCode": null, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:01:00.000Z", "purpose": "transactional" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/submissions/$SUBMISSION_ID\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/submissions/${process.env.SUBMISSION_ID}`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Account & access (/docs/api-reference/getTenantAccessProfile) GET /v1/me Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getTenantAccessProfile", "summary": "Account & access", "description": "Available to every valid tenant key without an additional scope. Returns effective policy metadata but never the key secret, hash, prefix, source fingerprint, or operator data.", "responses": { "200": { "description": "Effective tenant access profile", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TenantAccessProfile" }, "example": { "organization": { "id": "00000000-0000-4000-8000-000000000003", "status": "active", "sendLimits": { "messagesPerMinute": 10, "messagesPerDay": 100, "recipientsPerDay": 100 } }, "apiKey": { "id": "00000000-0000-4000-8000-000000000004", "kind": "agent", "scopes": [ "mailbox:manage", "mailbox:read", "mailbox:send", "delivery:read", "webhook:manage" ], "inboxIds": null, "allowedIps": null, "sendMode": "new_and_reply", "allowedRecipientDomains": null, "expiresAt": null, "requestsPerMinute": 60 }, "managedStarter": { "limit": 10, "used": 0, "remaining": 10 }, "platformLimits": { "recipientsPerMessage": 10, "messageContentBytes": 1000000, "inboxes": 10, "domains": 3, "inboxesPerDomain": 5, "webhookEndpoints": 5 } } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/me\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/me`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Get a conversation (/docs/api-reference/getThread) GET /v1/threads/{threadId} Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "getThread", "summary": "Get a conversation", "x-mailactor-required-scope": "mailbox:read", "parameters": [ { "name": "threadId", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ThreadId" } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "cursor", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Thread and messages", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Thread" }, "example": { "id": "thr_0123456789abcdef01234567", "inboxId": "inb_0123456789abcdef01234567", "subject": "Your research update", "participants": [ "research-agent@inbox.mailactor.com", "you@example.com" ], "messageCount": 2, "lastMessageAt": "2026-09-08T12:01:00.000Z", "messages": [ { "id": "msg_0123456789abcdef01234567", "inboxId": "inb_0123456789abcdef01234567", "threadId": "thr_0123456789abcdef01234567", "direction": "inbound", "internetMessageId": "The research is ready for your review.
", "replyTo": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "metadata": { "taskId": "research-42" }, "delivery": { "submissionId": "00000000-0000-4000-8000-000000000001", "status": "submitted", "failureCode": null }, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z", "purpose": "transactional" } ], "nextCursor": null } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "410": { "$ref": "#/components/responses/Gone" }, "413": { "$ref": "#/components/responses/PayloadTooLarge" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/threads/$THREAD_ID\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/threads/${process.env.THREAD_ID}`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List complaints (/docs/api-reference/listComplaints) GET /v1/complaints Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listComplaints", "summary": "List complaints", "x-mailactor-required-scope": "delivery:read", "responses": { "200": { "description": "Complaints", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplaintList" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/complaints\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/complaints`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List domains (/docs/api-reference/listDomains) GET /v1/domains Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listDomains", "summary": "List domains", "x-mailactor-required-scope": "domain:manage", "responses": { "200": { "description": "Registered domains", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainList" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/domains\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/domains`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List conversations (/docs/api-reference/listInboxThreads) GET /v1/inboxes/{inboxId}/threads Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listInboxThreads", "summary": "List conversations", "x-mailactor-required-scope": "mailbox:read", "parameters": [ { "name": "inboxId", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/InboxId" } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "cursor", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Cursor-paginated thread summaries", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ThreadPage" }, "example": { "threads": [ { "id": "thr_0123456789abcdef01234567", "inboxId": "inb_0123456789abcdef01234567", "subject": "Your research update", "participants": [ "research-agent@inbox.mailactor.com", "you@example.com" ], "messageCount": 2, "lastMessageAt": "2026-09-08T12:01:00.000Z" } ], "nextCursor": null } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "413": { "$ref": "#/components/responses/PayloadTooLarge" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/inboxes/$INBOX_ID/threads\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/inboxes/${process.env.INBOX_ID}/threads`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List inboxes (/docs/api-reference/listInboxes) GET /v1/inboxes Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listInboxes", "summary": "List inboxes", "x-mailactor-required-scope": "mailbox:read", "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "cursor", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Cursor-paginated inboxes", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxPage" }, "example": { "inboxes": [ { "id": "inb_0123456789abcdef01234567", "localPart": "research-agent", "domainId": null, "domainKind": "managed", "domain": "inbox.mailactor.com", "address": "research-agent@inbox.mailactor.com", "displayName": "Research Agent", "status": "active", "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" } ], "nextCursor": null } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/inboxes\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/inboxes`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List delivery events (/docs/api-reference/listSubmissionEvents) GET /v1/submissions/{submissionId}/events Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listSubmissionEvents", "summary": "List delivery events", "x-mailactor-required-scope": "delivery:read", "parameters": [ { "name": "submissionId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Delivery events", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliveryEventList" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/submissions/$SUBMISSION_ID/events\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/submissions/${process.env.SUBMISSION_ID}/events`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List submissions (/docs/api-reference/listSubmissions) GET /v1/submissions Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listSubmissions", "summary": "List submissions", "x-mailactor-required-scope": "delivery:read", "responses": { "200": { "description": "Delivery submissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliverySubmissionList" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/submissions\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/submissions`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List suppressions (/docs/api-reference/listSuppressions) GET /v1/suppressions Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listSuppressions", "summary": "List suppressions", "x-mailactor-required-scope": "delivery:read", "responses": { "200": { "description": "Suppressions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuppressionList" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/suppressions\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/suppressions`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # List webhooks (/docs/api-reference/listWebhooks) GET /v1/webhooks Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "listWebhooks", "summary": "List webhooks", "x-mailactor-required-scope": "webhook:manage", "parameters": [ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "cursor", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Webhook endpoints", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookPage" }, "example": { "endpoints": [ { "id": "whk_0123456789abcdef01234567", "url": "https://your-app.example.com/webhooks/mailactor", "events": [ "message.received" ], "status": "active", "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" } ], "nextCursor": null } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X GET \\\n \"https://api.mailactor.com/v1/webhooks\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/webhooks`, {\n method: 'GET',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Register a domain (/docs/api-reference/registerDomain) POST /v1/domains Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "registerDomain", "summary": "Register a domain", "x-mailactor-required-scope": "domain:manage", "description": "Returns TXT ownership, DKIM and MX instructions. Inbound and outbound capabilities verify independently.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "required": [ "domain" ], "properties": { "domain": { "type": "string", "format": "hostname", "minLength": 1, "maxLength": 253, "description": "A fully qualified customer-owned hostname. Mailactor trims, removes one trailing dot, converts IDNs to ASCII, and lowercases it.", "example": "agents.example.com" } } }, "example": { "domain": "agents.example.com" } } } }, "responses": { "201": { "description": "Domain and DNS instructions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendingDomain" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "409": { "$ref": "#/components/responses/Conflict" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X POST \\\n \"https://api.mailactor.com/v1/domains\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"domain\": \"agents.example.com\"\n}'" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/domains`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY, 'Content-Type': \"application/json\" },\n body: JSON.stringify({\n \"domain\": \"agents.example.com\"\n}),\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Reply to a message (/docs/api-reference/replyToThread) POST /v1/threads/{threadId}/replies Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "replyToThread", "summary": "Reply to a message", "x-mailactor-required-scope": "mailbox:send", "parameters": [ { "name": "threadId", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ThreadId" } }, { "name": "idempotency-key", "in": "header", "required": true, "schema": { "type": "string", "minLength": 8, "maxLength": 200, "pattern": "^[A-Za-z0-9._:-]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "anyOf": [ { "required": [ "targetMessageId", "text" ], "title": "Plain text" }, { "required": [ "targetMessageId", "html" ], "title": "HTML" } ], "required": [ "targetMessageId" ], "properties": { "targetMessageId": { "$ref": "#/components/schemas/MessageId", "description": "Bind the reply to this exact message. Clients must supply the selected message ID so concurrent arrivals cannot change the recipient." }, "text": { "type": "string" }, "html": { "type": "string" }, "metadata": { "$ref": "#/components/schemas/Metadata" }, "purpose": { "type": "string", "enum": [ "transactional", "marketing" ], "description": "Optional declared purpose. Omitted replies remain unclassified for backward compatibility." } } }, "example": { "targetMessageId": "msg_0123456789abcdef01234567", "text": "Thanks, Alex. I have everything I need.", "purpose": "transactional" } } } }, "responses": { "202": { "description": "Durable reply and delivery submission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MailboxSendResult" }, "example": { "message": { "id": "msg_2123456789abcdef01234567", "inboxId": "inb_0123456789abcdef01234567", "threadId": "thr_0123456789abcdef01234567", "direction": "outbound", "internetMessageId": "The research is ready for your review.
", "replyTo": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "metadata": { "taskId": "research-42" }, "purpose": "transactional" } } } }, "responses": { "202": { "description": "Durable mailbox message and delivery submission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MailboxSendResult" }, "example": { "message": { "id": "msg_1123456789abcdef01234567", "inboxId": "inb_0123456789abcdef01234567", "threadId": "thr_0123456789abcdef01234567", "direction": "outbound", "internetMessageId": "The research is ready for your review.
", "replyTo": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "metadata": { "taskId": "research-42" }, "delivery": { "submissionId": "00000000-0000-4000-8000-000000000001", "status": "submitted", "failureCode": null }, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z", "purpose": "transactional" }, "submission": { "id": "00000000-0000-4000-8000-000000000001", "from": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "recipients": [ { "email": "you@example.com", "status": "pending", "response": null, "updatedAt": "2026-09-08T12:00:00.000Z" } ], "subject": "Your research update", "metadata": { "taskId": "research-42" }, "status": "pending", "queueId": null, "response": null, "failureCode": null, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z", "purpose": "transactional" }, "replayed": false } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "409": { "$ref": "#/components/responses/Conflict" }, "410": { "description": "The requested mailbox content was deleted and cannot be returned.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": "idempotency_result_expired", "message": "The original mailbox result was deleted; this idempotency key cannot be reused" } } } }, "413": { "$ref": "#/components/responses/PayloadTooLarge" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\n# Generate once per logical action; preserve this key for retries.\nexport IDEMPOTENCY_KEY=\"request-$(uuidgen)\"\ncurl --fail-with-body --silent --show-error -X POST \\\n \"https://api.mailactor.com/v1/inboxes/$INBOX_ID/messages\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\" \\\n -H \"idempotency-key: $IDEMPOTENCY_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"to\": [\n {\n \"email\": \"you@example.com\",\n \"name\": \"Alex\"\n }\n ],\n \"subject\": \"Your research update\",\n \"text\": \"The research is ready for your review.\",\n \"html\": \"The research is ready for your review.
\",\n \"replyTo\": {\n \"email\": \"research-agent@inbox.mailactor.com\",\n \"name\": \"Research Agent\"\n },\n \"metadata\": {\n \"taskId\": \"research-42\"\n },\n \"purpose\": \"transactional\"\n}'" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\n// Save this value with the operation and reuse it for retries.\nconst idempotencyKey = `request-${crypto.randomUUID()}`;\nconst response = await fetch(`https://api.mailactor.com/v1/inboxes/${process.env.INBOX_ID}/messages`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY, 'idempotency-key': idempotencyKey, 'Content-Type': \"application/json\" },\n body: JSON.stringify({\n \"to\": [\n {\n \"email\": \"you@example.com\",\n \"name\": \"Alex\"\n }\n ],\n \"subject\": \"Your research update\",\n \"text\": \"The research is ready for your review.\",\n \"html\": \"The research is ready for your review.
\",\n \"replyTo\": {\n \"email\": \"research-agent@inbox.mailactor.com\",\n \"name\": \"Research Agent\"\n },\n \"metadata\": {\n \"taskId\": \"research-42\"\n },\n \"purpose\": \"transactional\"\n}),\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Submit a message (/docs/api-reference/submitEmail) POST /v1/send Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "submitEmail", "summary": "Submit a message", "x-mailactor-required-scope": "delivery:send", "parameters": [ { "name": "idempotency-key", "in": "header", "required": true, "schema": { "type": "string", "minLength": 8, "maxLength": 200, "pattern": "^[A-Za-z0-9._:-]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "required": [ "from", "to", "subject" ], "anyOf": [ { "required": [ "from", "to", "subject", "text" ], "title": "Plain text" }, { "required": [ "from", "to", "subject", "html" ], "title": "HTML" } ], "properties": { "from": { "$ref": "#/components/schemas/Mailbox" }, "to": { "type": "array", "minItems": 1, "maxItems": 1000, "description": "The current deployment limit is returned by GET /v1/me as platformLimits.recipientsPerMessage.", "items": { "$ref": "#/components/schemas/Mailbox" } }, "subject": { "type": "string", "minLength": 1, "maxLength": 998, "pattern": "\\S" }, "text": { "type": "string" }, "html": { "type": "string" }, "replyTo": { "$ref": "#/components/schemas/Mailbox" }, "headers": { "type": "object", "additionalProperties": false, "maxProperties": 3, "properties": { "x-campaign": { "type": "string", "maxLength": 998, "pattern": "^[^\\r\\n]*$" }, "x-campaign-id": { "type": "string", "maxLength": 998, "pattern": "^[^\\r\\n]*$" }, "x-entity-ref-id": { "type": "string", "maxLength": 998, "pattern": "^[^\\r\\n]*$" } }, "description": "Only these three non-routing customer headers are accepted." }, "metadata": { "$ref": "#/components/schemas/Metadata" }, "purpose": { "type": "string", "enum": [ "transactional", "marketing" ], "description": "Optional declared purpose. Marketing delivery is rejected until marketing-specific consent, unsubscribe, and suppression controls exist." } } }, "example": { "from": { "email": "agent@agents.example.com" }, "to": [ { "email": "you@example.com" } ], "subject": "Hello from Mailactor", "text": "A message from my verified domain.", "purpose": "transactional" } } } }, "responses": { "202": { "description": "Durable delivery submission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliverySubmissionAccepted" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "409": { "$ref": "#/components/responses/Conflict" }, "413": { "$ref": "#/components/responses/PayloadTooLarge" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\n# Generate once per logical action; preserve this key for retries.\nexport IDEMPOTENCY_KEY=\"request-$(uuidgen)\"\ncurl --fail-with-body --silent --show-error -X POST \\\n \"https://api.mailactor.com/v1/send\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\" \\\n -H \"idempotency-key: $IDEMPOTENCY_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"from\": {\n \"email\": \"agent@agents.example.com\"\n },\n \"to\": [\n {\n \"email\": \"you@example.com\"\n }\n ],\n \"subject\": \"Hello from Mailactor\",\n \"text\": \"A message from my verified domain.\",\n \"purpose\": \"transactional\"\n}'" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\n// Save this value with the operation and reuse it for retries.\nconst idempotencyKey = `request-${crypto.randomUUID()}`;\nconst response = await fetch(`https://api.mailactor.com/v1/send`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY, 'idempotency-key': idempotencyKey, 'Content-Type': \"application/json\" },\n body: JSON.stringify({\n \"from\": {\n \"email\": \"agent@agents.example.com\"\n },\n \"to\": [\n {\n \"email\": \"you@example.com\"\n }\n ],\n \"subject\": \"Hello from Mailactor\",\n \"text\": \"A message from my verified domain.\",\n \"purpose\": \"transactional\"\n}),\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Validate an address (/docs/api-reference/validateEmail) POST /v1/validate Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "validateEmail", "summary": "Validate an address", "x-mailactor-required-scope": "validation:use", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "required": [ "email" ], "properties": { "email": { "type": "string", "format": "email", "maxLength": 320 } } }, "example": { "email": "alex@example.com" } } } }, "responses": { "200": { "description": "Validation result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailValidationResult" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X POST \\\n \"https://api.mailactor.com/v1/validate\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"alex@example.com\"\n}'" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/validate`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY, 'Content-Type': \"application/json\" },\n body: JSON.stringify({\n \"email\": \"alex@example.com\"\n}),\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Validate in bulk (/docs/api-reference/validateEmailsBulk) POST /v1/validate/bulk Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "validateEmailsBulk", "summary": "Validate in bulk", "x-mailactor-required-scope": "validation:use", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "required": [ "emails" ], "properties": { "emails": { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "minLength": 1, "maxLength": 320 } } } }, "example": { "emails": [ "alex@example.com", "sam@example.com" ] } } } }, "responses": { "200": { "description": "Validation results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ValidationResultList" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X POST \\\n \"https://api.mailactor.com/v1/validate/bulk\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"emails\": [\n \"alex@example.com\",\n \"sam@example.com\"\n ]\n}'" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/validate/bulk`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY, 'Content-Type': \"application/json\" },\n body: JSON.stringify({\n \"emails\": [\n \"alex@example.com\",\n \"sam@example.com\"\n ]\n}),\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Verify domain DNS (/docs/api-reference/verifyDomain) POST /v1/domains/{domainId}/verify Resolve component references with https://docs.mailactor.com/openapi.json. ```json { "operationId": "verifyDomain", "summary": "Verify domain DNS", "x-mailactor-required-scope": "domain:manage", "parameters": [ { "name": "domainId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Checks plus independent capabilities.outbound and capabilities.inbound results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainVerification" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/Unavailable" } }, "x-codeSamples": [ { "lang": "bash", "label": "cURL", "source": "# Set the API key and replace resource IDs with your saved IDs.\ncurl --fail-with-body --silent --show-error -X POST \\\n \"https://api.mailactor.com/v1/domains/$DOMAIN_ID/verify\" \\\n -H \"x-api-key: $MAILACTOR_API_KEY\"" }, { "lang": "js", "label": "JavaScript", "source": "// Node.js: configure your key and saved resource IDs in the environment.\nconst response = await fetch(`https://api.mailactor.com/v1/domains/${process.env.DOMAIN_ID}/verify`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.MAILACTOR_API_KEY },\n});\n// Handle errors before reading the success response.\nif (!response.ok) throw new Error(`Mailactor returned ${response.status}`);\nconst contentType = response.headers.get(\"content-type\") ?? \"\";\nconst result = response.status === 204 ? null : contentType.includes(\"application/json\")\n ? await response.json() : await response.arrayBuffer();" } ] } ``` # Connect your own domain (/docs/domains/setup) Customer-domain inboxes let you send and receive as an address such as `research-agent@agents.example.com`. They do not consume the managed starter allowance, but verified-domain policy and traffic limits still apply. You need control of the domain's DNS, `domain:manage` to configure it, and `mailbox:manage` to create an inbox. Use an organization enabled for customer-domain inboxes; if your trial is restricted, contact the team. ## 1. Register a dedicated subdomain [#1-register-a-dedicated-subdomain] We recommend a dedicated subdomain such as `agents.example.com`, especially if your root domain already uses Google Workspace or Microsoft 365. ```bash curl --fail-with-body --silent --show-error \ "$MAILACTOR_API_URL/v1/domains" \ -H "x-api-key: $MAILACTOR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"domain":"agents.example.com"}' ``` Save the returned domain `id` as `DOMAIN_ID`. After a lost response, list domains and match the normalized domain name before registering again. ## 2. Publish the returned DNS records [#2-publish-the-returned-dns-records] The domain response includes `dnsRecords`. Publish each record exactly as returned. TXT records use `name` and `value`; MX records also include `priority`. The instructions cover ownership, DKIM, and inbound mail routing. Follow any additional onboarding instructions for SPF and DMARC. Your DNS provider may append your zone name automatically, so check whether it expects a relative or fully qualified record name.The research is ready for your review.
", "replyTo": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "metadata": { "taskId": "research-42" }, "purpose": "transactional" } ``` | Field | Required | Shape | | ---------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `to` | Yes | Array of `{email, name?}` objects. At least one; use `/v1/me` → `platformLimits.recipientsPerMessage` for your live cap (schema maximum 1,000). | | `subject` | Yes | String, 1–998 characters, not whitespace-only. | | `text` | One of `text` / `html` | Plain-text string. | | `html` | One of `text` / `html` | HTML string. Both body formats are allowed. | | `replyTo` | No | One `{email, name?}` object; directs normal email replies. Omit to receive replies at the inbox's sender address. | | `metadata` | No | Up to 20 string values, keys 1–100 characters, values at most 500 characters. | | `purpose` | No | `transactional` or `marketing`. Marketing currently fails closed with HTTP 422; omission is recorded as `unclassified`. | Every mailbox needs a valid `email`; optional `name` is 1–200 characters. Unknown fields are rejected. There are no outbound attachment, CC, or BCC fields. The sender is your inbox's returned `address`; you do not supply `from`. Treat outgoing HTML as application-authored content, and respect the live `messageContentBytes` limit. ## Save the response identifiers [#save-the-response-identifiers] | Field | Use | | ------------------ | ------------------------------------------- | | `message.id` | Identify the email in your mailbox. | | `message.threadId` | Read this conversation and receive replies. | | `submission.id` | Track outbound delivery. | A `202` response means accepted for asynchronous delivery. Poll the [submission endpoint](/docs/reliability/delivery) for the outcome. A mailbox message's `delivery.status: "submitted"` does not mean the recipient's server accepted it. ### HTTP 202 example [#http-202-example] The example above can return this complete envelope. `replayed: false` means a new operation; `true` means the same operation was recovered by its idempotency key. Status may already have advanced when you read a replay. ```json title="Response: sendInboxMessage 202" { "message": { "id": "msg_1123456789abcdef01234567", "inboxId": "inb_0123456789abcdef01234567", "threadId": "thr_0123456789abcdef01234567", "direction": "outbound", "purpose": "transactional", "internetMessageId": "The research is ready for your review.
", "replyTo": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "metadata": { "taskId": "research-42" }, "delivery": { "submissionId": "00000000-0000-4000-8000-000000000001", "status": "submitted", "failureCode": null }, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" }, "submission": { "id": "00000000-0000-4000-8000-000000000001", "from": { "email": "research-agent@inbox.mailactor.com", "name": "Research Agent" }, "recipients": [ { "email": "you@example.com", "status": "pending", "response": null, "updatedAt": "2026-09-08T12:00:00.000Z" } ], "subject": "Your research update", "metadata": { "taskId": "research-42" }, "purpose": "transactional", "status": "pending", "queueId": null, "response": null, "failureCode": null, "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" }, "replayed": false } ``` ## Retry safely [#retry-safely] For an interrupted or retryable request, use the **same idempotency key and semantic body**. Do not create a new key merely because the first response was lost. A new key represents a new message and can send a duplicate. If the retry deadline expires, retain the key and body and report acceptance as unknown. There is no lookup endpoint by idempotency key; matching a message by subject or content is not proof that it belongs to this operation. [Idempotency and safe retries](/docs/reliability/idempotency) ## Choose the correct sending route [#choose-the-correct-sending-route] `POST /v1/inboxes/{inboxId}/messages` stores a mailbox message and creates the thread needed for normal inbox workflows. `POST /v1/send` is a lower-level delivery endpoint for integrations supplying their own authorized From mailbox. It requires `delivery:send` and a verified sending domain. It does not create the inbox conversation for you. Never switch routes when retrying one logical send. [Full inbox send reference](/docs/api-reference/sendInboxMessage) # Create an inbox (/docs/inboxes/create) An inbox is an email identity within your organization. It keeps its address and conversations across API requests. Required scope: `mailbox:manage`. Set `MAILACTOR_API_URL` and `MAILACTOR_API_KEY` as shown in [quickstart](/docs/quickstart). Examples below use illustrative IDs and values; use the values returned for your organization. ## Use a managed address [#use-a-managed-address] ```bash curl --fail-with-body --silent --show-error \ "$MAILACTOR_API_URL/v1/inboxes" \ -H "x-api-key: $MAILACTOR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"localPart":"research-agent","displayName":"Research Agent"}' ``` Omit `domainId` to use the managed domain. Save the returned `id` and `address` instead of constructing either yourself. On the production starter domain, the requested local part becomes an address such as `research-agent@inbox.mailactor.com`. ## Request fields [#request-fields] | Field | Required | Shape | | ------------- | ------------------------- | ----------------------------------------------------------------------- | | `localPart` | No; set it for automation | String, 1–64 characters; naming rules below. Omission generates a name. | | `displayName` | No | Nonempty string, at most 200 characters. | | `domainId` | No | UUID of your verified domain; omit for a managed address. | Unknown fields are rejected. Success is **201 Created**, returning the inbox directly, without an `inbox` wrapper. A managed inbox has `domainId: null`. ```json title="Response: createInbox 201" { "id": "inb_0123456789abcdef01234567", "localPart": "research-agent", "domainId": null, "domainKind": "managed", "domain": "inbox.mailactor.com", "address": "research-agent@inbox.mailactor.com", "displayName": "Research Agent", "status": "active", "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" } ``` ## Choose a name [#choose-a-name] Use a lowercase ASCII local part with letters, digits, dots, underscores, or hyphens. It must start and end with a letter or digit, contain no consecutive dots, and be at most 64 characters. Names such as `admin`, `postmaster`, `abuse`, `security`, `support`, and `noreply` are reserved. Managed addresses share one namespace, so another organization may already own your preferred name. Choose a distinctive name when you receive a conflict. `displayName` is optional and is limited to 200 characters. ## Use your own domain [#use-your-own-domain] First [register and verify your domain](/docs/domains/setup). Then supply its ID: ```json title="Request: createInbox" { "localPart": "research-agent", "displayName": "Research Agent", "domainId": "00000000-0000-4000-8000-000000000001" } ``` Replace the example UUID with your registered domain's actual ID. Confirm that the response has `domainKind: "customer"` and the expected `domainId`. ## Recover from an interrupted request [#recover-from-an-interrupted-request] Inbox creation does not require an idempotency key. Always choose a `localPart` in automated workflows. If the connection fails, [list every inbox page](/docs/inboxes/manage). Match the requested `localPart` and `domainKind: "managed"`, or the exact `domainId` for a customer domain; take the exact address from the matching response. Do not infer ownership from a `409`: names are shared across organizations. If a complete inventory contains no match, retry the same create input after waits of 1, 2, 4, then at most 5 seconds, honoring a longer `Retry-After` when present. Choose a deadline, for example 60 seconds for this reconciliation phase; this is an application budget, not an API guarantee. For `409 inbox_address_unavailable`, choose a different name as a new creation attempt only after the full inventory contains no match. For `409 inbox_limit_exceeded`, stop and resolve your organization's inbox limit; changing the name will not help. If your read permission is missing or the inventory is incomplete, report the result as unresolved. A key restricted to existing inbox IDs may not be allowed to create new inboxes. The managed starter sending allowance is shared across the organization; creating additional inboxes does not reset it. [Full request and response reference](/docs/api-reference/createInbox) A shared-name conflict uses this error envelope; branch on `error`, not the diagnostic `message`: ```json title="Response: createInbox 409" { "error": "inbox_address_unavailable", "message": "The requested inbox address is unavailable" } ``` # Manage inboxes (/docs/inboxes/manage) After onboarding, you can manage your own organization's inboxes through the API. Use `mailbox:read` for reads and exports, and `mailbox:manage` for deletion. Set `MAILACTOR_API_URL` and `MAILACTOR_API_KEY` as shown in [quickstart](/docs/quickstart). Examples below use illustrative IDs and values; use the values returned for your organization. ## List your inboxes [#list-your-inboxes] ```bash curl --fail-with-body --silent --show-error \ "$MAILACTOR_API_URL/v1/inboxes?limit=20" \ -H "x-api-key: $MAILACTOR_API_KEY" ``` The response contains `inboxes` and `nextCursor`. Results are newest-first. [Follow pagination](/docs/reliability/pagination) until `nextCursor` is `null` when you need a complete inventory. ```json title="Response: listInboxes 200" { "inboxes": [ { "id": "inb_0123456789abcdef01234567", "localPart": "research-agent", "domainId": null, "domainKind": "managed", "domain": "inbox.mailactor.com", "address": "research-agent@inbox.mailactor.com", "displayName": "Research Agent", "status": "active", "createdAt": "2026-09-08T12:00:00.000Z", "updatedAt": "2026-09-08T12:00:00.000Z" } ], "nextCursor": null } ``` ## Inspect one inbox [#inspect-one-inbox] ```bash curl --fail-with-body --silent --show-error \ "$MAILACTOR_API_URL/v1/inboxes/$INBOX_ID" \ -H "x-api-key: $MAILACTOR_API_KEY" ``` Success is `200`, with the same direct [Inbox object shown after creation](/docs/inboxes/create). It includes the exact address, domain, `domainKind`, display name, status, and timestamps. The current public API does not provide an inbox rename, address change, or pause/resume endpoint. ## Export mailbox content [#export-mailbox-content] ```bash curl --fail-with-body --silent --show-error \ "$MAILACTOR_API_URL/v1/inboxes/$INBOX_ID/export?limit=20" \ -H "x-api-key: $MAILACTOR_API_KEY" ``` An export page contains `formatVersion`, `inbox`, `messages`, and `nextCursor`. Save every page. This is a paginated view rather than a point-in-time snapshot; concurrent changes require reconciliation. Attachment metadata is included with messages, not raw MIME or attachment bytes. Store exports securely: they contain message content. For a complete export example, including inbound and outbound messages, see [the export response](/docs/api-reference/exportInbox#response-examples). Continue until `nextCursor: null`; a successful first page is not a complete export. The API cannot guarantee an atomic “export everything, then delete” for an active inbox: there is no snapshot or pause endpoint. Stop application sends and coordinate with senders before export, repeat complete passes with message-ID deduplication, and check for new arrivals before deletion. This reduces the race but does not eliminate it. If your task requires guaranteed lossless export, retain the inbox and report that the guarantee is unsupported. Delete only when the task explicitly accepts this limitation. Download eligible attachments separately before deleting if your backup needs bytes. Quarantined attachments cannot be exported as bytes through the public API. ## Delete an inbox [#delete-an-inbox]