DropMail.me Experimental API
It's in a "public beta" state! Backwards-incompatible changes are still possible!
HTTP Endpoint: https://dropmail.me/api/graphql/${AUTH_TOKEN}
.
WebSocket Endpoint: wss:https://dropmail.me/api/graphql/${AUTH_TOKEN}/websocket
.
API uses GraphQL format. GraphQL schema: schema.graphql.
You can use any unique string of 8 characters or more as ${AUTH_TOKEN}
right now, but we will introduce authentication mechanisms later.
HTTP endpoint expects standard GraphQL parameters: query
, variables
, operationName
and extensions
. Only query
is mandatory.
Both GET
and POST
methods could be used.
For GET
method just add urlencoded parameters to the url as query string: /api/graphql/MY_TOKEN?query=…&variables=…
("variables" should be a JSON object).
POST
accepts application/json
and application/x-www-form-urlencoded
Content-Types. If no "Content-Type
" header provided, we expect the body to be in JSON. See detailed specification.
Response can be returned with Content-Type: application/json
(default) or as streamed multipart/mixed
(when Accept: multipart/mixed
HTTP request header is set). The multipart/mixed
only makes sense to use for subscriptions. See detailed specification.
WebSocket endpoint supports both graphql-ws and Apollo protocols (negotiated via "Sec-WebSocket-Protocol
" header). Please consult your GraphQL client library for details.
Object model
- Domain
- Domain name, like
@dropmail.me
or@10mail.org
for which you can crate email Addresses. Some domains are only available via API, seeDomain.availableVia
. - Session
- Is a server-side storage unit. It stores Addresses and incoming Emails. It has limited lifetime - when session expires all its Addresses and Mails are removed from the server. You can create multiple Sessions and attach multiple Addresses to each Session. By default session's lifetime is 10min and extended each time you access it (by making any query that reads or writes some data to it).
- Address
- Email address, like
[email protected]
,[email protected]
. You can only choose Domain of the address, but "login" part (the one that comes before@
) is assigned by the server automatically and is always unique and belongs to you only. It's always attached to one of the Sessions and it is able to receive mail as long as the Session it's attached to is not expired. If you think you may need to use this address in the future, you should save itsrestoreKey
and use it later withrestoreAddress
operation. - Incoming email that arrived to one of the Addresses and is stored inside the Session. When Session expires, email is removed from our server completely and forever. You can request different parts of the email (like it's plain
text
,headerSubject
,attachments
etc) or get wholeraw
MIME mail ordownloadUrl
to download the raw mail by HTTP. - Attachment
- It's only defined when received Mail has any attachments and we were able to parse it. They can be accessed via
Mail.attachments
field.
Workflow
Creating a Session with single random Address
To create a new sessions, use introduceSession
mutation.
Here we create a new Session with new random Address and asking the server to return session's id, expiration time and new Addresses email address
mutation {
introduceSession {
id,
expiresAt,
addresses {
address
}
}
}
the output of this query would look like this:
{
"data": {
"introduceSession": {
"id": "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK",
"expiresAt": "2021-02-18T04:20:00+00:00",
"addresses": [
{
"address": "[email protected]"
}
]
}
}
}
From now on, you can send mail to [email protected] and server would store it inside the Session with ID "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK".
"expiresAt": "2021-02-18T04:20:00+00:00"
means that this session would self-destruct at this moment (it's always in the future time), unless something happens with it (some query reads from it, or new email received). Each time session is accessed, its expiresAt
is extended. So, in theory, it may stay alive forever.
Fetching the incoming mail
To check for the incoming mail, you have two options
- Periodical polling - periodically (eg, once every 10 second) inspect the contents of the Session using
session(id)
orsessions
query (easier, less efficient) - Subscriptions - to use
sessionMailReceived
subscription (advanced, more efficient)
Periodical polling (basic)
Here we are requesting all (up to 100) mails for a specific session.
query {
session(id: "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK") {
mails{
rawSize,
fromAddr,
toAddr,
downloadUrl,
text,
headerSubject
}
}
}
This query would return an empty array when there are no mails:
{
"data": {
"session": {
"mails": []
}
}
}
And would return a Mail object for each received email, when there are some:
{
"data": {
"session": {
"mails": [
{
"toAddr": "[email protected]",
"text": "Hello\r\n",
"rawSize": 812,
"html": null,
"headerSubject": "Hello",
"fromAddr": "[email protected]",
"downloadUrl": "https://dropmail.me/download/mail/gql:1:9c3316a6-69d2-42fd-a2e2-3f3fd72f494a/vb18co6tn6b4pv10hgr7lhaljcnrhvk5",
}
]
}
}
}
If session has already expired, null
will be returned instead.
{
"data": {
"session": null
},
"errors": [
{
"path": ["session"],
"message": "session_not_found",
"extensions": {
"code": "resolver_error"
}
}
]
}
When you plan to receive multiple emails with the same session, it's recommended to use mailsAfterId(mailId: ID)
field. When no mailId
provided, it returns the same results as mails
. But when some existing mailId
is specified, it would only return mails, received after this mailId
.
So, when you start the session, first you query mailsAfterId
without mailId
(or just mails
), asking it to return Mail.id
as well. When you recieve your first mail, you'll call mailsAfterId
with received mail's id
as a parameter, so, only new - unread mail will be returned.
Subscriptions (advanced)
The benefit of subscriptions is that you don't have to keep sending requests periodically to see if there is a new mail, but the server notifies you immediately when there is a new mail. To use subscriptions you need to rely on more advanced techniques. There are 3 alternatives:
- Subscription via HTTP long-polling
- Subscription via HTTP multipart/mixed streaming
- Subscription via WebSocket
subscription {
sessionMailReceived(id: "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK") {
rawSize,
fromAddr,
toAddr,
downloadUrl,
text,
headerSubject
}
}
To use this command with long-polling method you run it the same way as with any other command, however the server will not reply immediately, but will block until mail is received (up to 3 minutes). It can only return one mail at a time with this method and it always returns the first received mail by default. To get the next one, you need to add mailsAfterId
parameter (works the same way as Query.mailsAfterId).
To use it with multipart/mixed streaming, you need to add Accept: multipart/mixed
HTTP request header. In that case the received emails will be streamed as multipart/mixed document that contains application/json
bodies per-email. It means you would need a MIME parser to extract the data.
To use it with WebSocket (recommended) you need to use a GraphQL client library that supports WebSocket transport. Please consult your library's documentation for details.
Custom addresses
You can create a new session without Address or with one initial Address (that has random or specific Domain). And you can always add more Addresses (with random or specific Domain) to the Session later.
You can't choose the login/username part of the address! It's always unique and generated by the server.
Anyway, first you would need to read the list of all the available domains and their IDs (IDs never change, so you can cache them locally; we add new ones from time to time):
query {
domains {
id,
name,
avaiableVia
}
}
Result:
{
"data": {
"domains": [
{
"name": "dropmail.me",
"id": "RG9tYWluOjE=",
"availableVia": ["API", "TELEGRAM", "WEB"]
},
{
"name": "10mail.org",
"id": "RG9tYWluOjI=",
"availableVia": ["API", "TELEGRAM", "WEB"]
},
<..>
]
}
}
Then you may create a new session with specific domain:
mutation {
introduceSession(input: {withAddress: true,
domainId: "RG9tYWluOjE="}) {
id,
addresses {
address
}
}
}
Or create an empty session and add more addresses later:
mutation {
introduceSession(input: {withAddress: false}) {
id
}
}
mutation {
introduceAddress(input: {sessionId: "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK"}) {
address,
restoreKey
}
}
mutation {
introduceAddress(input: {sessionId: "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK",
domainId: "RG9tYWluOjE="}) {
address,
restoreKey
}
}
Try it from your browser!
Here you can try to query our API right from your browser.
List domains
Introduce session
This request would return a new email address as data.introduceSession.addresses[0].address
, you can try to send emails to it!
What is your ? (data.introduceSession.id
):
List all sessions
You can see all your non-expired sessions, even when you forgot to save the Session ID.
Add one more address to the session
You can have multiple addresses attached to the session.
Query a specific session
Call this API periodically to fetch incoming mail.
Subscribe to new session mail
Use subscriptions to let server notify you about new mail.
Try your own query
Here you can edit your own query and run it.
Code examples
Here we are using CURL command line utility to query the API.
Creating a new session with random email address
$ curl --silent -H "Content-Type: application/x-www-form-urlencoded" https://dropmail.me/api/graphql/MY_TOKEN -d 'query=mutation {introduceSession {id, expiresAt, addresses{id, address}}}' | jq
{
"data": {
"introduceSession": {
"id": "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK",
"expiresAt": "2021-02-18T01:40:02+00:00",
"addresses": [
{
"id": "QWRkcmVzczqcMxamadJC_aLiPz_XL0lKOmRyb2ZAMTBtYWlsLm9yZw",
"address": "[email protected]"
}
]
}
}
}
Now "[email protected]" is active and it can receive emails.
Fetching received emails
Right now there is no way for server to notify you when the new email have arrived, so, you have to do periodic HTTP-polling. We are working on providing alternative ways (long-polling / websockets / web-hooks).
$ curl --silent https://dropmail.me/api/graphql/MY_TOKEN -d 'query=query ($id: ID!) {session(id:$id) {id, expiresAt, mails{id, rawSize, raw, fromAddr, toAddr, receivedAt, downloadUrl, toAddrOrig, decodeStatus, text, headerFrom, headerSubject, html}, addresses{id, address, restoreKey} }}&variables={"id": "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK"}' | jq
{
"data": {
"session": {
"mails": [
{
"toAddrOrig": "[email protected]",
"toAddr": "[email protected]",
"text": "Hello\r\n",
"receivedAt": "2021-02-18T01:30:17+00:00",
"rawSize": 812,
"raw": "MIME-Version: 1.0\r\nMessage-ID: <[email protected]>\r\nSubject: Hello\r\nFrom: Hello <[email protected]>\r\nTo: [email protected]\r\nContent-Type: text/plain; charset=US-ASCII\r\n\r\nHello\r\n",
"id": "TWFpbDqcMxamadJC/aLiPz/XL0lKOnZiMThjbzZ0bjZiNHB2MTBoZ3I3bGhhbGpjbnJodms1",
"html": null,
"headerSubject": "Hello",
"headerFrom": "Hello <[email protected]>",
"fromAddr": "[email protected]",
"downloadUrl": "https://dropmail.me/download/mail/gql:1:9c3316a6-69d2-42fd-a2e2-3f3fd72f494a/vb18co6tn6b4pv10hgr7lhaljcnrhvk5",
"decodeStatus": "OK"
}
],
"id": "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK",
"expiresAt": "2021-02-18T01:41:50+00:00",
"addresses": [
{
"restoreKey": "0c88ea831f8f71bf3885f2b5bddd6c371",
"id": "QWRkcmVzczqcMxamadJC_aLiPz_XL0lKOmRyb2ZAMTBtYWlsLm9yZw",
"address": "[email protected]"
}
]
}
}
}
Same, but more compact:
$ curl --silent https://dropmail.me/api/graphql/MY_TOKEN -d 'query=query ($id: ID!) {session(id:$id) {mails{rawSize, fromAddr, toAddr, downloadUrl, text, headerSubject}} }&variables={"id": "U2Vzc2lvbjqcMxamadJC_aLiPz_XL0lK"}' | jq
{
"data": {
"session": {
"mails": [
{
"toAddr": "[email protected]",
"text": "Hello\r\n",
"rawSize": 812,
"html": null,
"headerSubject": "Hello",
"fromAddr": "[email protected]",
"downloadUrl": "https://dropmail.me/download/mail/gql:1:9c3316a6-69d2-42fd-a2e2-3f3fd72f494a/vb18co6tn6b4pv10hgr7lhaljcnrhvk5",
}
]
}
}
}