tommy mail API v1
Captures the email your application sends instead of delivering it, whether it went out through a vendor's HTTP API or plain SMTP. Every message is parsed into one canonical model you can read back over the API or browse in the inbox tab, attachments included.
These routes read back what tommy captured, in the shape this content type
wants: filters that only mean something here, and the parts that are bytes
rather than JSON. They read from the same store as the events API, so a
client that sends and immediately fetches sees its own write, and every
entry carries the id of the event behind it.
The events API - /api/v1/events, described in its own document - is the
generic view of the same captures, and is the one to use when what you are
asserting does not depend on the content type. The fake vendor endpoints are
described nowhere here: they are the vendors' specifications, not tommy's.
This document is generated from the server's route table. It cannot describe
a route that does not exist, and CI fails if the checked-in copy stops
matching the code.
Server
/api/v1/mail — This tommy's mail API.
Operations
GET
/messages
Every captured message, newest first.
Parameters
| Name | In | Type | Description |
provider |
query |
string |
Only entries captured by this provider, such as mailjet. |
type |
query |
string |
Only entries of this event type, such as mail.message. |
search |
query |
string |
Case-insensitive substring over the summary and type. |
since |
query |
string |
RFC3339 timestamp, a duration such as 5m, or unix milliseconds. |
limit |
query |
integer |
Maximum number of entries to return. |
offset |
query |
integer |
How many entries to skip. |
to |
query |
string |
Substring of any recipient - To, Cc or Bcc. |
from |
query |
string |
Substring of the sender. |
subject |
query |
string |
Substring of the subject. |
has_attachments |
query |
boolean |
Only messages with, or without, attachments. |
Responses
| Status | Body | Description |
200 |
application/json · array of mail.MessageView
|
Success. |
400 |
application/json · api.Error
|
A query parameter could not be parsed - a malformed since, a negative limit. |
DELETE
/messages
Clear every captured message. Attachment blobs deliberately survive.
Responses
| Status | Body | Description |
204 |
no body |
Done. No body. |
GET
/messages/{id}
One message, with links to its bodies and attachments.
Parameters
| Name | In | Type | Description |
id required |
path |
string |
The event id, as returned by any listing. |
Responses
| Status | Body | Description |
200 |
application/json · mail.MessageView
|
Success. |
404 |
application/json · api.Error
|
No such resource, or it belongs to another plugin. |
GET
/messages/{id}/attachments/{idx}
One attachment, streamed from the blob store with range support.
Parameters
| Name | In | Type | Description |
id required |
path |
string |
The event id, as returned by any listing. |
idx required |
path |
string |
Zero-based index into the attachments or media of that message. |
inline |
query |
boolean |
Force an inline Content-Disposition. |
download |
query |
boolean |
Force an attachment Content-Disposition. |
Responses
| Status | Body | Description |
200 |
application/octet-stream
|
Success. |
400 |
application/json · api.Error
|
A query parameter could not be parsed - a malformed since, a negative limit. |
404 |
application/json · api.Error
|
No such resource, or it belongs to another plugin. |
GET
/messages/{id}/html
The HTML part, served under a no-script CSP because it is untrusted content.
Parameters
| Name | In | Type | Description |
id required |
path |
string |
The event id, as returned by any listing. |
Responses
| Status | Body | Description |
200 |
text/html
|
Success. |
404 |
application/json · api.Error
|
No such resource, or it belongs to another plugin. |
GET
/messages/{id}/raw
The untouched request that produced the message; ?download=1 serves it as an .eml.
Parameters
| Name | In | Type | Description |
id required |
path |
string |
The event id, as returned by any listing. |
download |
query |
boolean |
Serve as a downloadable message/rfc822 attachment. |
Responses
| Status | Body | Description |
200 |
text/plain
|
Success. |
400 |
application/json · api.Error
|
A query parameter could not be parsed - a malformed since, a negative limit. |
404 |
application/json · api.Error
|
No such resource, or it belongs to another plugin. |
GET
/messages/{id}/text
The plain-text part of the message, as text/plain.
Parameters
| Name | In | Type | Description |
id required |
path |
string |
The event id, as returned by any listing. |
Responses
| Status | Body | Description |
200 |
text/plain
|
Success. |
404 |
application/json · api.Error
|
No such resource, or it belongs to another plugin. |
Schemas
api.Error
| Property | Type |
error required | string |
blob.Ref
| Property | Type |
content_type | string |
filename | string |
id required | string |
size required | integer |
mail.Address
| Property | Type |
email required | string |
name | string |
mail.Attachment
| Property | Type |
blob required | blob.Ref |
content_id | string |
content_type | string |
filename | string |
inline | boolean |
size required | integer |
mail.MessageLinks
| Property | Type |
attachments | array of string |
html | string |
raw required | string |
self required | string |
text | string |
mail.MessageView
| Property | Type |
id required | string |
links required | mail.MessageLinks |
message required | mail.Message |
meta | object of any |
provider required | string |
received_at required | string (date-time) |
type required | string |
url | string |