Skip to main content

API

Clients talk only to the api at https://mail.phonemail.net/api. The full reference, generated from docs-site/static/api/openapi.yaml (OpenAPI 3.1) and validated with Redocly, is in Swagger UI.

Conventions​

TopicRule
AuthAuthorization: Bearer <token> from any /auth/* sign-in call; tokens last 30 days
Client headerSend X-Client: web, portal or mobile; it is recorded as created_via when an account is created
PeopleAnywhere a person is named you may send 9884690127, 09884690127, +919884690127, a PhoneMail address or alias, or any outside email address (e.g. friend@gmail.com)
ErrorsJSON {"error": "human-readable message"} with 400, 401, 403, 404, 409, 422 or 501
PagingLists return newest first; pass the sentAt/lastMessageAt of the last item as before for the next page
Live updatesSocket.IO at path /api/socket.io, auth: {token}; event mail = something new for you

Endpoint groups​

GroupEndpoints
Sign-up and sign-inGET /auth/mode, POST /auth/password/register, POST /auth/password/login, POST /auth/otp/start, POST /auth/otp/verify, POST /auth/join/start, GET /auth/join/{code}
TwilioPOST /twilio/sms (webhook, signed)
ProfileGET /me, PATCH /me, PUT /me/password, POST /me/aliases, DELETE /me/aliases/{alias}
ConversationsGET /conversations, GET /conversations/{id}/messages, GET /threads/{rootId}, GET /lookup
MessagesPOST /messages, POST /messages/{id}/reply, GET /messages/{id}, PATCH /mailbox/{messageId}, GET /folders/{folder}, GET /search
DraftsGET /drafts, POST /drafts, PUT /drafts/{id}, DELETE /drafts/{id}
GroupsPOST /groups, GET /groups/{id}, POST /groups/{id}/members, DELETE /groups/{id}/members/{userId}, POST /groups/{id}/leave, PATCH /groups/{id}/members/{userId}

The internal mail-service contract​

The api forwards mail calls to the Go service with X-Internal-Token and X-User-Id. These are the spec's §7 endpoints; they are not reachable from outside.

Method and pathPurpose
POST /messagesDeliver a new message (spec §6.1)
POST /messages/{id}/replyReply inside a chat (§6.2)
GET /conversations?filter=&before=&limit=Home list
GET /conversations/{id}/messages?before=&limit=Open a chat (marks read)
GET /threads/{rootId}Whole thread in path order
GET /messages/{id}Traditional view with recipients (Bcc filtered)
PATCH /mailbox/{messageId}Read, favourite, folder
GET /folders/{spam or trash}, GET /search?q=, GET /lookup?address=Folders, full-text search, find a direct chat
GET, POST, PUT, DELETE /draftsDrafts
POST /groups, members, leave, rolesGroup management (§6.7)
GET /healthLiveness (also checks the database)

The mail service calls back POST {api}/internal/events after each delivery commits.

Mail protocols (for Postfix and Roundcube)​

PortProtocolUsed by
127.0.0.1:2525SMTP (no auth)Postfix hands over mail for @phonemail.net; unknown recipients get 550
:1143IMAP4rev1 + MOVERoundcube; folders INBOX, Sent, Drafts, Junk, Trash; \Seen, \Flagged, \Answered map to read, starred, replied
:1587SMTP submission, AUTH PLAIN/LOGINRoundcube sending; MAIL FROM must be the signed-in address
:1180HTTP POST /password (form: user, curpass, newpass)Roundcube's password plugin (httpapi driver)

IMAP, submission and the password endpoint listen only on the Docker bridge address (WEBMAIL_BIND).