Using the API
Create an API key, call the management API, connect Bitwarden through the SimpleLogin-compatible API, and read mail with JMAP.
eoinbox has two public APIs:
- the management API at
https://api.eoinbox.com/v1for domains, addresses, identities, keys and your account; - JMAP at
https://mail.eoinbox.comfor the mail itself.
The full list of endpoints is in the API reference.
Create an API key
- Open Settings → API keys → Create key.
- Name it, and choose only the scopes it needs, for example
addresses:writefor a script that creates aliases. - Optionally set an expiry date and limit the key to specific domains.
- Copy the key. It starts with
eo_and is shown only once.
Available scopes: account:read, account:write, domains:read, domains:write, addresses:read, addresses:write, identities:read, identities:write, tokens:write, webhooks:write.
Make a request
Send the key in the Authorization header:
curl https://api.eoinbox.com/v1/domains \
-H "Authorization: Bearer eo_your_key"
Create an alias:
curl -X POST https://api.eoinbox.com/v1/addresses \
-H "Authorization: Bearer eo_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1c0d7e-shop-signup" \
-d '{"domainId": "dom_...", "localPart": "shop", "note": "online shop"}'
Create a masked alias with a random name:
curl -X POST https://api.eoinbox.com/v1/addresses/random \
-H "Authorization: Bearer eo_your_key" \
-H "Content-Type: application/json" \
-d '{"note": "signed up at example-shop"}'
Without domainId, the masked alias is created on alias.eoinbox.com.
Conventions
- JSON in and out, UTF-8.
- Errors look like this, with a machine-readable
code:
Common codes:{ "error": { "code": "plan_limit", "message": "Alias limit reached", "details": { "limit": 50 } } }unauthorized,insufficient_scope,not_found,validation_failed,conflict,plan_limit,rate_limited. - Pagination: lists accept
?limit=50&cursor=...and return{ "items": [...], "nextCursor": "..." }.nextCursorisnullon the last page. - Idempotency: send an
Idempotency-Keyheader withPOSTrequests and you can safely retry for 24 hours without creating duplicates. - Rate limits apply per key. On
429, wait and retry.
Bitwarden
Bitwarden's password generator can create a new alias on your domain each time you sign up somewhere. It talks to eoinbox through our SimpleLogin-compatible API.
- In eoinbox, create an API key with the
addresses:writescope. To control which domain new aliases use, restrict the key to that domain. - In Bitwarden, open the Generator and select Username.
- Choose Forwarded email alias as the type and SimpleLogin as the service.
- Paste your eoinbox key into API key.
- Set the server URL (labelled for self-hosted servers) to
https://api.eoinbox.com/compat/simplelogin. - Click Generate. A new alias appears in your eoinbox address list, with a note about where it was made.
Labels in Bitwarden may differ slightly between the browser extension, desktop and mobile apps.
SimpleLogin and addy.io compatibility
Other tools that support SimpleLogin or addy.io can use eoinbox the same way:
| Service | Base URL | Authentication |
|---|---|---|
| SimpleLogin | https://api.eoinbox.com/compat/simplelogin | Authentication: eo_your_key |
| addy.io | https://api.eoinbox.com/compat/addy | Authorization: Bearer eo_your_key |
Both cover the alias part of those APIs: creating random and custom aliases, listing, enabling, disabling and deleting them. They use the same eoinbox API keys. For anything else, use the management API.
Mail data with JMAP
Reading, searching and writing mail uses JMAP (RFC 8620 and RFC 8621), the same API our webmail uses. Point any JMAP library at https://mail.eoinbox.com and authenticate with your API key. Sending mail requires the corresponding scope.
Webhooks (after launch)
Webhooks notify your server when something happens: message.received, address.created, address.updated, domain.status_changed and message.bounced. Each request carries an Eoinbox-Signature header:
Eoinbox-Signature: t=1767225600,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
v1 is the hex HMAC-SHA256 of t + "." + body, using the webhook secret. Check the signature and reject requests with an old timestamp.