Migrating from Apifon TES
Move from the legacy Apifon TES service with zero changes to your callback consumer.
wemail is the successor to the legacy Apifon TES (Transactional Email Service). Existing TES integrations move over with minimal changes: SMTP submission works as before, the legacy X-TES-* headers keep working, and the Apifon TES webhook bridge delivers callbacks in the exact legacy format so your consumer needs no code changes.
1 · Point SMTP at wemail
Submit to smtp.wemail.io (ports 587 STARTTLS · 465 · 2525) authenticating with your sending domain as username and an API key as password. Message limits: up to 20 MB per message (each attachment up to 5 MB decoded), up to 1,000 recipients across To/Cc/Bcc per message (use the batch API for more), and the same executable/script attachment types are rejected — now at submission with a clear error (see Attachments).
2 · Your X-TES-* headers keep working
| Parameter | Type | Required | Description |
|---|---|---|---|
X-TES-MESSAGE-TAGS | k1=v1, k2=v2 | Optional | Parsed into the message variables (key/value map) exactly like TES parsed it into metadata.tags, and stripped before delivery — recipients never see it. X-Wemail-Variables (JSON) is the native equivalent and wins on key conflicts. |
X-TES-REFERENCE-ID | string | Optional | Round-trips end-to-end like any custom X-* header: delivered on the email, stored, echoed on every webhook under headers, returned by GET /v3/messages/{id}. With the TES bridge enabled it is lifted to the legacy top-level reference_id. |
X-TES-CUSTOM-ID | string | Optional | Same round-trip; with the TES bridge enabled it becomes the legacy per-message custom_id. |
3 · Legacy-format callbacks: the Apifon TES bridge
Enable Console → Bridge → Apifon TES (Legacy) and enter your numeric TES account id. Every webhook the workspace sends is then delivered in the original TES envelope — {type: "EMAIL", url, reference_id, account_id, data: [...]} with the legacy numeric status codes, full message headers, parsed tags and per-event dlr_data — as plain unsigned POSTs expecting a 200, with retries. A workspace has one active bridge at a time.
Event name mapping
| Parameter | Type | Required | Description |
|---|---|---|---|
enroute (code 3) | sent | Optional | The platform accepted the message and dispatch started. |
delivered (code 4) | delivered | Optional | The recipient mail server accepted the message. |
seen (code 10) | opened | Optional | Careful: TES called the tracking-pixel open "seen". |
open (code 11) | clicked | Optional | Careful: TES called a link click "open". |
bounce (code 22) | bounced | Optional | Same bounce_type / bounce_sub_type vocabulary (Transient maps to the legacy temporary). |
complaint (code 67) | complained | Optional | Same complaint_feedback_type values. |
Events with no TES equivalent (queued, rejected, delayed, failed, unsubscribed) are never sent to bridge endpoints. When you later switch to native webhooks you gain those, plus Ed25519 signatures and the tags/headers/variables echo — see Webhooks.