CarlyEmail docs

Inboxes

A real address on a real domain.

An inbox is an email address that can send and receive. Its id is the address — pepsi@carlyemail.com — not an opaque handle, so you never have to look one up to know where mail goes.

curl -X POST https://api.carlyemail.com/v0/inboxes \
  -H "Authorization: Bearer $CARLYEMAIL_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"username": "pepsi", "display_name": "Support"}'

Omit username and one is generated. Omit domain and you get the default: carlyemail.com for verified organizations, agents.carlyemail.com for unverified ones.

The domain is decided when the address is minted, and an address is never rewritten afterwards — mail is already in flight to it and threads already reference it. So verifying an account changes where its next inbox lands, and leaves the one it signed up with exactly where it is. An agent that signed up, verified, and expected its address to follow will still be sending from agents.carlyemail.com.

To move onto carlyemail.com, create a second inbox. The verify response names both halves — inbox_domain is where new inboxes go, inboxes_on_signup_domain lists the ones that stay put:

curl -X POST https://api.carlyemail.com/v0/inboxes \
  -H "Authorization: Bearer $CARLYEMAIL_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"username": "pepsi"}'

The old address keeps receiving, so nothing sent to it is lost. Send from whichever one you want to be reached at.

Display names

display_name is the name beside the address when the inbox sends — Support <pepsi@carlyemail.com> rather than the address alone. It is optional, and without one mail goes out as the bare address.

Set it at sign-up, when creating an inbox, or later. Sending an empty string takes it off again.

npx carlyemail name pepsi@carlyemail.com "Support"
npx carlyemail name pepsi@carlyemail.com          # back to the bare address
curl -X PATCH https://api.carlyemail.com/v0/inboxes/pepsi@carlyemail.com \
  -H "Authorization: Bearer $CARLYEMAIL_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"display_name": "Support"}'

The name goes into a mail header, so it is limited to 255 characters and cannot contain control characters — a newline in one would be header injection. Either is refused with 400 invalid_request on the call that set it.

Usernames are globally unique per domain

Two organizations cannot both hold pepsi@carlyemail.com — it is one address on one domain, and mail to it has to go somewhere unambiguous. A collision returns 409 username_unavailable. Bring your own domain if you want a name somebody else has taken; see custom domains.

Deleting

Deleting an inbox deletes its messages. Mail arriving for a deleted address is acknowledged and dropped rather than retried, because retrying an address that does not exist can never succeed.