---
title: "Email built into your app - OpenEmail"
description: "Give every record in your app its own address, take arriving mail as a signed webhook, and answer from your own code with a typed client"
url: "https://openemail.uk/use-cases/embedded-email"
---

Mail your app handles

# Your product gets the mail and your code writes back

Every ticket, record or customer can have its own address. Mail sent there reaches your endpoint as a signed event, and your code answers as that address.

[Open mail](https://openemail.uk/mail/inbox) [Get Started](https://openemail.uk/signup.md)[All use cases](https://openemail.uk/use-cases.md)

ticket-8123@in.yourapp.com

Your app

Ticket 8123 ticket-8123@ in.yourapp.com

Ticket 8124 ticket-8124@ in.yourapp.com

Ticket 8125 ticket-8125@ in.yourapp.com

To ticket-8123@ in.yourapp.com

My parcel never arrived.

From ticket-8123@ in.yourapp.com Same address

It is on the way. Tracking below.

Nobody created these addresses. The reply leaves as the one the mail arrived at.

Where it starts

## What this looks like today.

Replies land outside the product

A customer answers a notification, and the reply sits in a shared mailbox rather than on the record.

Somebody creates each address first

A new ticket cannot be written to until a mailbox exists for it, so addresses are set up by hand.

Your server polls for new mail

Nothing tells your code a message has arrived, so a job checks a mailbox on a timer.

How it works

## Running in four steps.

1. 01
   
   Point a domain at OpenEmail
   
   Add the domain and publish the records, and every address on it receives, including ones nobody created.
2. 02
   
   Install the typed client
   
   Add the package to your app, then set a workspace key you can scope and revoke later.
3. 03
   
   Register your endpoint
   
   Pick the events you want, copy the signing secret, and answer each delivery within five seconds.
4. 04
   
   Answer from your own code
   
   Fetch the thread and its files by id, then send from the address the message was delivered to.

What it runs on

## The parts doing the work.

It runs on a documented HTTP API, a typed client, webhooks to your endpoint, catch-all addresses on every domain you point here, and your own branding, files and tracked links.

REST API

A documented HTTP API with issuable, scopable, revocable keys.

/threads?query=invoice

{ "threads": 12 }

Same mailbox, whether a person or a program is holding it.

Typed SDKs

A TypeScript client first, then the rest.

/threads?query=invoice

{ "threads": 12 }

Same mailbox, whether a person or a program is holding it.

Webhooks

Tell your endpoint when mail arrives, instead of making you poll.

/threads?query=invoice

{ "threads": 12 }

Same mailbox, whether a person or a program is holding it.

Catch-all addresses

Every address on the domain receives, including ones that have never been created. One switch closes it.

hello@ yourdomain.com delivered

billing@ yourdomain.com delivered

careers@ yourdomain.com delivered

anything-at-all@ yourdomain.com delivered

oct-2026-signup@ yourdomain.com delivered

Multiple domains

Point several domains at one inbox, subdomains included.

acme.com acme.dev team.acme.com hey.acme.io

Workspace branding

Put your own mark and logo in the sidebar, in place of ours.

acme.com acme.dev studio.acme.com

hello@ acme.com delivered

billing@ acme.com delivered

oct-2026-signup@ acme.com delivered

anything-at-all@ acme.com delivered

Files on your own domain

Download links for the files you send on a subdomain you choose, such as files.yourdomain.com, instead of the OpenEmail address.

Tracking on your own domain

Tracked links and the open pixel on a subdomain you choose, such as links.yourdomain.com, instead of the OpenEmail address.

In practice

## Every piece, walked through.

Four shorter pages sit under this one, one job each: an address per customer, mail out of your code, mail into your code, and an address for every test run, which is still to come.

An address per customer

Give every ticket, record or customer its own address, with nothing to create.

Ticket 8123 ticket-8123@ in.yourapp.com

Ticket 8124 ticket-8124@ in.yourapp.com

To ticket-8123@ in.yourapp.com

From ticket-8123@ in.yourapp.com Same address

Email inside your product

Send, read and organise mail from your own code with a typed client.

await openemail.emails.send({

from: 'receipts@acme.com',

})

id msg\_3e91c7

queued sent delivered

email.opened email.clicked

Email into your app

Mail arriving at your domain reaches your server as a signed webhook, seconds later.

billing@in.yourapp.com Arrived

POST hooks.acme.dev/mail 200

type email.received

to billing@in.yourapp.com

Test your signup mail

Soon

Give each test run its own address and read the mail it receives.

signup-02 @acme.com

Confirm your email 730915

signup-01 @acme.com 418204

signup-02 @acme.com 730915

Questions

## Asked before signing up.

Do I have to create an address before it works?

No. With catch-all on, ticket-8123@in.yourapp.com receives the first time somebody writes to it. Mail to typos and made-up addresses arrives as well, and one switch closes the catch-all.

How does my code hear that mail arrived?

Your endpoint takes a signed webhook seconds after the message lands. The event names the thread and the address it was delivered to, so you fetch the message and its files by id.

Is there a client for my language?

Not yet, unless you write TypeScript. The typed client is TypeScript first and the others follow, so every other language calls the documented HTTP API directly for now.

Nearby

## Other jobs for the same mailbox.

The mail your product sends

Your app posts a message and OpenEmail sends it from your own domain. Every call sits against the key that made it, and every send has an outcome to read.

to buyer@northwind.co

template order-receipt

202 msg\_9f2c7a14

email.sent msg\_9f2c7a14

email.delivered msg\_9f2c7a14

email.opened msg\_9f2c7a14

Hand the inbox to software

Give an agent an address of its own and a key scoped to what it may do. It reads, labels, drafts and sends, and every call it makes is logged.

agent@yourco.com Member

listThreads getThread searchMail sendEmail

Hand out addresses

Every form wants an address. Give each one its own, see which starts getting spam, and switch that one off without touching the rest.

q7k2m9@ pooled domain 58:12

Your verification code 09:41

[All use cases](https://openemail.uk/use-cases.md)
