API for test automation
Automated tests keep failing at the same point: the application sends a confirmation e-mail, and the test run cannot reach it. This interface solves that in three calls — create an inbox, wait, read the message.
You need an access key for it. You get one right here, free and without an account: enter an e-mail address, take the key, done.
Get an access key
Free and immediate. All we need is an e-mail address — in case we have to reach you about abuse, and so it is clear who a key belongs to.
Quick start
Three calls, nothing more. The key belongs in every one of them.
# Der Schluessel gehoert in jeden Aufruf.
export GETSEND_KEY="gs_..."
# 1. Postfach anlegen
curl -s -X POST https://www.getsend.xyz/api/v1/inboxes \
-H "Authorization: Bearer $GETSEND_KEY"
# {
# "address": "a7k2m9x4p1q8w3z6@getsend.xyz",
# "messages_url": "https://www.getsend.xyz/api/v1/inboxes/a7k2m9x4p1q8w3z6/messages"
# }
# 2. Postfach abfragen
curl -s -H "Authorization: Bearer $GETSEND_KEY" \
https://www.getsend.xyz/api/v1/inboxes/a7k2m9x4p1q8w3z6/messages
# 3. Nachricht mit Inhalt lesen
curl -s -H "Authorization: Bearer $GETSEND_KEY" \
https://www.getsend.xyz/api/v1/inboxes/a7k2m9x4p1q8w3z6/messages/193Endpoints
| Methode | Pfad | OK |
|---|---|---|
POST | /api/v1/inboxes | 201 |
GET | /api/v1/inboxes | 200 |
GET | /api/v1/inboxes/{adresse}/messages | 200 |
GET | /api/v1/inboxes/{adresse}/messages/{id} | 200 |
DELETE | /api/v1/inboxes/{adresse}/messages/{id} | 200 |
In test tools
Cypress
// cypress/support/getsend.js
const API = 'https://www.getsend.xyz/api/v1'
const KEY = Cypress.env('GETSEND_KEY') // nie im Quelltext ablegen
const kopf = { Authorization: `Bearer ${KEY}` }
Cypress.Commands.add('neuesPostfach', () =>
cy.request({ method: 'POST', url: `${API}/inboxes`, headers: kopf }).its('body'))
// Wartet, bis eine Nachricht da ist -- Mail braucht ein paar Sekunden.
Cypress.Commands.add('warteAufMail', (box, versuche = 20) => {
const lokal = box.address.split('@')[0]
const holen = (rest) =>
cy.request({ url: `${API}/inboxes/${lokal}/messages`, headers: kopf })
.then((r) => {
if (r.body.count > 0) return r.body.messages[0]
if (rest <= 1) throw new Error('Keine Mail eingetroffen')
return cy.wait(3000).then(() => holen(rest - 1))
})
return holen(versuche)
})
// Im Test:
it('bestaetigt die Registrierung', () => {
cy.neuesPostfach().then((box) => {
cy.visit('/registrierung')
cy.get('#email').type(box.address)
cy.get('form').submit()
cy.warteAufMail(box).then((m) => {
const lokal = box.address.split('@')[0]
cy.request({ url: `${API}/inboxes/${lokal}/messages/${m.id}`, headers: kopf })
.then((r) => {
const link = r.body.text.match(/https?:\/\/\S+/)[0]
cy.visit(link)
cy.contains('Konto bestaetigt')
})
})
})
})Python / Selenium
# Selenium, pytest oder jedes andere Werkzeug -- die Schnittstelle
# ist ein gewoehnlicher HTTP-Aufruf.
import os, re, time, requests
API = "https://www.getsend.xyz/api/v1"
KOPF = {"Authorization": "Bearer " + os.environ["GETSEND_KEY"]}
def neues_postfach():
return requests.post(f"{API}/inboxes", headers=KOPF, timeout=10).json()
def warte_auf_mail(box, versuche=20, pause=3):
lokal = box["address"].split("@")[0]
for _ in range(versuche):
r = requests.get(f"{API}/inboxes/{lokal}/messages", headers=KOPF, timeout=10).json()
if r["count"]:
mid = r["messages"][0]["id"]
return requests.get(f"{API}/inboxes/{lokal}/messages/{mid}",
headers=KOPF, timeout=10).json()
time.sleep(pause)
raise AssertionError("Keine Mail eingetroffen")
box = neues_postfach()
driver.find_element(By.ID, "email").send_keys(box["address"])
driver.find_element(By.CSS_SELECTOR, "form").submit()
mail = warte_auf_mail(box)
link = re.search(r"https?://\S+", mail["text"]).group(0)
driver.get(link)Limits
Messages are deleted after seven days. Per key, 60 new inboxes and 3000 requests per hour are allowed; beyond that the interface answers with 429 and a Retry-After header.
The service accepts mail for getsend.xyz only. There are no custom domains.
This is a small service on a single server. That is enough for a test run during development; it is not meant as a building block of a production application, and we do not promise availability.
What the key does — and what it does not
An inbox you create through the interface belongs to your key. Another key cannot reach it, even if it knows the address.
That does not hold for the web interface: getSend has always shown any inbox whose address you type in there. Anyone who knows your address still sees the messages in a browser. That is why generated addresses are 16 characters long and practically unguessable — and why nothing confidential belongs in these inboxes.
Treat the key like a password. It belongs in an environment variable, not in your source code and not in a public repository.