Migrating from Mailosaur
The compatibility work was done against one thing in particular: their SDK authenticates with HTTP Basic, key as the username, empty password. So does this API, for exactly that reason.
# What their client sends, and what we acceptcurl -u "fk_your_key:" https://api.facteur.eu/v1/inboxesWhat maps cleanly
Section titled “What maps cleanly”Searching. POST /api/messages/search becomes POST /v1/messages/search.
The criteria are the same idea — substrings on sender, recipient, subject and
body — and the blocking wait is a wait field in milliseconds rather than a
separate mechanism.
Reading one message. GET /api/messages/{id} becomes
GET /v1/messages/{id}.
Listing servers. Their server is our inbox: GET /api/servers becomes
GET /v1/inboxes. The vocabulary differs because the unit does — an inbox here
belongs to a workspace, which is how access is partitioned.
Where the shapes differ
Section titled “Where the shapes differ”The error envelope. Every failure here is
{ "error": { "code": …, "message": … } }, without exception. Branch on code;
message is human-facing and in French. See Errors.
status on a message. There is no equivalent to read past: a message
accepted over SMTP exists before it is parsed, and this API says so rather than
hiding it. Assert on status === 'parsed', or let the search do it for you — it
filters to parsed messages by default. See Limits and waiting.
Unknown search criteria are refused. A field that is not a criterion answers
400 CRITERIA_UNKNOWN naming it, where an ignored field would have silently
matched everything. If you are porting a search that used a criterion we do not
have, you will find out at the first call rather than at the first false green.
Addresses. Subaddressing works the same way: everything after the + is
yours, and it is what lets two tests share an inbox without racing.
What is not there yet
Section titled “What is not there yet”Attachments, raw .eml download, deliverability analysis, the OTP device
endpoint and the usage route are all listed as upcoming in the conversion table
linked above — with, again, a machine checking that the claim stays true. If one
of them is load-bearing for your suite, that table is where its arrival will show
up first.
There is also no published SDK. Everything here is plain HTTP, which is the honest state of it today.