AuralisDocs
OperationsInbound messages

Land an inbound email as a ticket or reply

Land an inbound email as a new ticket or a reply on an existing one.

/v1/ingest/emailNo credential
Operation id
ingest_email
Access
Public by design. No credential is required or consulted.
POST/v1/ingest/email

Land an inbound email as a new ticket or a reply on an existing one.

This is the contract a mail provider posts to. Forward the parsed message, including the RFC 5322 headers, and the runtime decides whether it opens a ticket or threads onto one.

message_id is the idempotency key. Redelivering a message with the same id lands no second ticket and no second reply. A retrying provider is safe, and the retry is not charged against the rate limit. Send it.

Threading uses in_reply_to first, then references, then the subject. Without those headers a reply becomes a new ticket, which is the usual cause of one conversation arriving as several tickets.

A customer is matched on from_email and created if there is none, so an address that has never written before still lands on a real customer record.

was_created says which happened. ticket_id names the ticket either way.

This operation only receives. The reply leg is elsewhere: a reply event added to the ticket is what sends mail back, and only for a workspace configured for outbound email. Check outbound_supported on GET /v1/channels for whether that is the case here.

A 429 means come back later, with Retry-After in seconds. Nothing was written and the same message replayed afterwards is accepted.

The threading, idempotency and identity rules this endpoint has always followed now live in the shared channel pipeline, and the mail-specific part of them lives in the mail adapter. Behaviour is unchanged and the response shape is unchanged; what changed is that every other channel gets the same guarantees from the same code rather than a second copy of it.

Tenancy: public and unauthenticated by design. No credential and no role is required or consulted; the workspace is resolved from the request itself (a body tenant_id, a URL token, or an agent id).

Access: no credential.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

A canonical inbound email payload. Postmark, SES, Mailgun all post similar JSON; we accept this lowest-common-denominator shape and document the mapping in docs/integrations/email.md when written.

tenant_id carries the routing for an unauthenticated provider post, and a provider post must send it.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/ingest/email" \  -H "Content-Type: application/json" \  -d '{    "tenant_id": "73fc37a9-8235-56c7-a296-772adf8f6dbe",    "from_email": "sam.okafor@northwind.example",    "from_name": "Sam Okafor",    "to_email": "support@northwind.example",    "subject": "Re: Card declined at checkout",    "text_body": "It happened again this morning.",    "message_id": "<abc123@mail.northwind.example>",    "in_reply_to": "<def456@mail.northwind.example>",    "references": "<def456@mail.northwind.example>",    "raw_headers": {      "X-Spam-Score": "0.1"    }  }'
{  "ticket_id": "5e8b0c31-7a4d-4f92-b6c8-1d3e2a5f7b90",  "customer_id": "9f1d6c4e-6b6e-4b31-9a5b-2f1c9a4d5e60",  "was_created": false}