Dieses Blog wiederholt seit Monaten dasselbe: dein Passwort sollte deinen
Browser nicht verlassen.
Der Generator holt seinen Zufall aus crypto.getRandomValues() auf
deiner eigenen Maschine, und der Passwort-Checker
analysiert, was du tippst, ohne es irgendwohin zu schicken.
Und heute veröffentlichen wir eine API, die Passwörter auf einem Server erzeugt.
Der Widerspruch ist offensichtlich, und wir werden ihn nicht beschönigen:
Jede Antwort der API trägt einen Hinweis, der genau das sagt. Aber es gibt
Stellen, an denen es keinen Browser gibt — ein Skript, das hundert Konten
anlegt, ein Server, der eine temporäre Zugangsdatei erzeugt, ein Assistent, den
jemand nach einem Passwort fragt und der es sich ausdenkt — und dort ist die
Alternative nicht „der Browser“: Sie ist ein schlecht gewähltes random() oder
eine von Hand getippte Zeichenkette. Dafür ist das hier da.
Der ganze Aufruf
Ohne Schlüssel, ohne Anmeldung, ohne Header. Das ist alles:
curl -X POST https://api.password.es/v1/generate
Zurück kommt ein Passwort mit 16 Zeichen und seine Analyse. Ausgeführt, während
dieser Absatz geschrieben wurde: x*7$9,BUy9PPvOI?, aus einem Alphabet von 89
Zeichen, 103,6 Bit Entropie und eine Knackzeit von 2,5 × 10¹¹ Jahren. Stufe
4 von 4.
Keine dieser Zahlen ist neu. Sie kommen aus derselben Maschinerie, die den Balken auf der Startseite zeichnet: dieselbe Bit-Formel, dasselbe Angriffsmodell — 10¹² Versuche pro Sekunde, offline, schneller Hash — und dieselbe Stufenskala wie der Checker. Wenn Website und API für dasselbe Passwort verschiedene Zahlen lieferten, würde eine von beiden lügen.
Was zurückkommt, Feld für Feld
Die Antwort enthält passwords — immer ein Array, auch wenn du nur eines
anforderst — und einen Block analysis mit length, pool, bits,
log10_guesses, crack_time_log10_seconds, crack_time, level,
level_scale und ceiling.
Zwei davon verdienen einen Absatz. level_scale sagt, woher die Stufe kommt
(heute immer "time"), damit eine künftige Abweichung zwischen Website und API
im Feld sichtbar wird, statt aus dem Vergleich von Zahlen erschlossen werden zu
müssen. Und ceiling sagt, ob die Zahl exakt oder eine Obergrenze ist: bei
generate steht dort immer false, weil der Server das Passwort gemacht hat
und sein Alphabet kennt; beim Checker der Website geht das nicht immer, denn
dort bringst du das Passwort mit.
Dann folgen notice, der Hinweis, und ein Block _meta mit dem Plan, der
angewendeten Sprache, den Limits und einem Link zurück zur Dokumentation.
Die Optionen
Alle optional, und auf Englisch benannt, weil wer eine API einbindet, die
Feldnamen genau so abtippt: length (4–64, Standard 16), count (1–20),
lower, upper, digits, symbols, exclude_ambiguous, no_repeats und
lang.
curl -X POST https://api.password.es/v1/generate -H 'content-type: application/json' -d '{"length":20,"exclude_ambiguous":true}'
Zwei Details, die die Dokumentation nennt und die man vor dem Einbinden kennen
sollte. exclude_ambiguous entfernt sechs Zeichen, nicht sieben: Es wirft
0 O 1 I l | o heraus, aber der senkrechte Strich war von vornherein nicht im
Symbolsatz, also sinkt das Alphabet von 89 auf 83 und nicht auf 82. Deshalb
steht in der Antwort pool 83. Und no_repeats ist keine absolute
Garantie: Es versucht es zehnmal, genau wie der Generator der Website, und bei
64 Zeichen rutscht eine unmittelbare Wiederholung in etwa 0,1 % der Fälle durch.
Das zu sagen ist nützlicher, als das Gegenteil zu versprechen.
Die Sprache
Standardmäßig antwortet sie auf Englisch, was erwartet, wer ohne weitere Angabe
einbindet. Ändern lässt sich das mit ?lang= in der URL, mit "lang" im Body
oder mit dem Header Accept-Language; widersprechen sie sich, gewinnt das
erste. Eine unbekannte Sprache ist kein Fehler: Sie fällt auf Englisch zurück.
Hier gibt es eine Asymmetrie, die man nicht erraten kann, und deshalb erklärt
die API sie: Die Meldungen gibt es auf Englisch und Spanisch; die Links in
allen achtzehn Sprachen der Website. Wer Deutsch anfordert, bekommt deutsche
Links und Meldungen weiterhin auf Englisch. Man muss nichts vermuten:
_meta.lang liefert { "messages", "links" } mit dem, was auf jede Hälfte
angewendet wurde.
Der MCP-Server
MCP ist das Protokoll, mit dem ein Assistent — Claude, ChatGPT — externe
Werkzeuge benutzt. https://api.password.es/mcp ist ein MCP-Server ohne
Anmeldung und ohne Schlüssel, und er veröffentlicht ein einziges Werkzeug:
generate_password, mit denselben Parametern wie oben.
Das ist der Teil, der uns am wichtigsten ist, und zwar nicht aus technischen
Gründen: Ein Assistent, der nirgends ein Passwort herbekommt, denkt sich
eines aus, und was dabei herauskommt, ist nicht zufällig, sondern das, was das
Modell für passwortförmig hält. Mit angeschlossenem Server hört er auf zu
improvisieren und gibt eines zurück, das mit crypto.getRandomValues() erzeugt
wurde — mit Analyse und mit dem Hinweis, der in der Werkzeugbeschreibung und in
jedem Ergebnis steckt. Genau diesen Hinweis liest der Assistent am Ende
demjenigen vor, der nach dem Passwort gefragt hat, und deshalb steht er dort.
Wenn du von anderen MCP-Servern kommst, eine Sache: dieser ist zustandslos.
Der POST wird mit JSON beantwortet und öffnet keinen Stream, Mcp-Session-Id
wird weder ausgegeben noch erwartet, eine Notification bekommt 202 ohne Body,
und GET liefert 405. Die Spezifikation 2025-06-18 erlaubt das ausdrücklich, aber
wer Sitzungen und SSE erwartet, debuggt im Blindflug, wenn es ihm niemand sagt.
Was sie nicht kann
/v1/check liefert 501. Das ist weder ein Versehen noch ein halbfertiger
Endpunkt: Es ist Absicht, und die Antwort selbst erklärt, warum. Dieselben
Zahlen wie der Checker zu liefern, verlangt genau dieselbe Mustererkennung, die
auf der Website läuft, und die kostet je nach Eingabe zwischen 11 ms und 3,6 s
CPU pro Anfrage. Bei einem Dienst ohne Anmeldung und ohne Schlüssel ist diese
Spanne eine Produktentscheidung — wo die Längenobergrenze liegt —, die noch
nicht gefallen ist. Bis dahin trägt der 501 ein checker_url, das auf den
Checker der Website in der angeforderten Sprache zeigt, der genau das tut, ohne
etwas zu senden.
Konten gibt es ebenfalls nicht, auch keine Schlüssel und keine Tarife. Und weil es sie nicht gibt, findet sich in der ganzen API kein einziger Link zu einer Registrierung: nicht einmal im Fehler bei überschrittenem Limit, wo ihn alle hinsetzen.
Die Limits
Eines, und es ist das, was wirklich durchgesetzt wird: 60 Anfragen pro Minute
und IP. Man muss dieser Seite nicht glauben: Die Zahl reist in jeder Antwort
mit, in _meta.limits.burst. Wer darüber liegt, bekommt einen 429 mit
Retry-After und RateLimit-*-Headern.
In _meta steht außerdem ein Block quota mit Werten auf null. Das ist der
reservierte Platz für den Tag, an dem es Konten gibt, und er bleibt absichtlich
leer: Ein angekündigtes und nicht durchgesetztes Limit ist schlimmer als gar
keines, denn wer einbindet, hält sich daran und programmiert gegen eine Zahl,
die niemand zählt.
Und trotzdem: zweimal überlegen
Eine API, die Passwörter erzeugt, ist im Kern ein Antipattern: Das Passwort läuft über das Netz und durch eine Maschine, die nicht deine ist. Dass wir nichts speichern, ändert nicht die Form des Problems, nur unseren Anteil daran — und du weißt bereits, was ein Versprechen wert ist, das du nicht überprüfen kannst.
Deshalb lebt der Hinweis nicht nur auf dieser Seite: Er reist in jeder Antwort mit, in der angeforderten Sprache. Und deshalb steht dieser Absatz hier und nicht versteckt am Ende der Dokumentation. Für ein Passwort, das du selbst benutzen wirst, läuft der Generator dieser Website vollständig in deinem Browser und schickt nichts. Die API ist für das andere: für das, was ohne jemanden vor einem Bildschirm passiert.
Die Details stehen auf zwei Seiten. Was die API ist erklärt, für wen
sie gedacht ist, was heute antwortet und was nicht. Die
Referenz hat die neun Parameter, alle Felder einzeln erklärt,
die Fehlercodes und die Limits; das ist die Seite, die man neben dem Editor
offen hat. Und wenn eine Maschine es lesen soll, gibt es openapi.json.
Quellen: die API selbst, am 31. August 2026 gegen die Produktion geprüft —
POST /v1/generate, POST /v1/check (501), POST /mcp und GET /openapi.json
· die Zahlen der Analyse stammen aus derselben Maschinerie wie Generator und
Checker von password.es · das Angriffsmodell sind 10¹² Versuche pro Sekunde,
offline und mit schnellem Hash, dasselbe wie im Rest der Website · der
MCP-Server implementiert die Spezifikation 2025-06-18 mit zustandslosem
Streamable-HTTP-Transport.
Foto von Stanislav Kondratiev · Pexels