# API password.es już odpowiada: jak z niego korzystać

> Jedno wywołanie bez klucza i bez rejestracji, które zwraca hasła i te same liczby, które widzisz na stronie: bity, czas łamania i poziom. Łącznie z tym, czego jeszcze nie robi, i dlaczego wywoływanie go nie zawsze jest dobrym pomysłem.

2026-08-31 · David Carrero · password.es
Original: https://password.es/pl/blog/api-do-generowania-hasel/

---

Ten blog od miesięcy powtarza to samo: [twoje hasło nie powinno opuszczać
przeglądarki](/pl/blog/dlaczego-nie-wysylamy-twojego-hasla/).
[Generator](/pl/) bierze losowość z `crypto.getRandomValues()` na twojej własnej
maszynie, a [sprawdzanie](/pl/sprawdzanie/) analizuje to, co wpisujesz, nie
wysyłając tego nigdzie.

A dziś publikujemy API, które generuje hasła na serwerze.

**Sprzeczność jest oczywista i nie zamierzamy jej zamazywać**: każda odpowiedź
API niesie ostrzeżenie, które mówi dokładnie to. Ale są miejsca, w których nie
ma przeglądarki — skrypt zakładający sto kont, serwer tworzący tymczasowe
poświadczenie, asystent, którego ktoś prosi o hasło, a on je zmyśla — i tam
alternatywą nie jest „przeglądarka": jest nią źle dobrany `random()` albo ciąg
wpisany ręcznie. Po to jest to API.

## Całe wywołanie

Bez klucza, bez rejestracji, bez nagłówków. To wszystko:

`curl -X POST https://api.password.es/v1/generate`

Zwraca hasło o długości 16 znaków i jego analizę. Wykonane w trakcie pisania
tego akapitu: `x*7$9,BUy9PPvOI?`, wzięte z alfabetu 89 znaków, **103,6 bita**
entropii i czas łamania 2,5 × 10¹¹ lat. Poziom 4 na 4.

Żadna z tych liczb nie jest nowa. Pochodzą z tego samego silnika, który rysuje
wskaźnik na stronie głównej: ten sam wzór na [bity](/pl/blog/czym-sa-bity-entropii/),
ten sam model ataku — 10¹² prób na sekundę, offline, szybki hash — i ta sama
skala poziomu co w sprawdzaniu. Gdyby strona i API podawały różne liczby dla
tego samego hasła, jedno z dwojga kłamałoby.

## Co zwraca, pole po polu

Odpowiedź zawiera `passwords` — zawsze tablicę, nawet gdy prosisz o jedno — i
blok `analysis` z `length`, `pool`, `bits`, `log10_guesses`,
`crack_time_log10_seconds`, `crack_time`, `level`, `level_scale` i `ceiling`.

Dwa z nich zasługują na akapit. **`level_scale` mówi, skąd wziął się poziom**
(dziś zawsze `"time"`), żeby przyszła rozbieżność między stroną a API była
widoczna w polu, zamiast trzeba ją było wywnioskować z porównywania liczb. A
**`ceiling` mówi, czy liczba jest dokładna, czy jest sufitem**: w `generate`
zawsze `false`, bo hasło zrobił serwer i wie, z jakiego alfabetu; w sprawdzaniu
na stronie nie zawsze może tak być, bo tam hasło przynosisz ty.

Dalej jest `notice`, ostrzeżenie, i blok `_meta` z planem, zastosowanym
językiem, limitami i odnośnikiem do dokumentacji.

## Opcje

Wszystkie opcjonalne, z nazwami po angielsku, bo kto integruje API, przepisuje
nazwy pól dosłownie: `length` (4–64, domyślnie 16), `count` (1–20), `lower`,
`upper`, `digits`, `symbols`, `exclude_ambiguous`, `no_repeats` i `lang`.

`curl -X POST https://api.password.es/v1/generate -H 'content-type: application/json' -d '{"length":20,"exclude_ambiguous":true}'`

Dwa szczegóły, o których mówi dokumentacja i które warto znać przed integracją.
**`exclude_ambiguous` usuwa sześć znaków, nie siedem**: odrzuca `0 O 1 I l | o`,
ale pionowej kreski i tak nie było w zestawie symboli, więc alfabet spada z 89
do 83, a nie do 82. Dlatego w odpowiedzi `pool` wynosi 83. I **`no_repeats` nie
jest absolutną gwarancją**: ponawia próbę dziesięć razy, dokładnie jak generator
na stronie, a przy 64 znakach sąsiadujące powtórzenie przechodzi w około 0,1 %
przypadków. Powiedzenie tego jest bardziej użyteczne niż obiecywanie czegoś
przeciwnego.

## Język

Domyślnie odpowiada po angielsku, czego spodziewa się ten, kto integruje bez
podania niczego. Zmienia się to przez `?lang=` w URL, `"lang"` w treści albo
nagłówek `Accept-Language`, a przy sprzeczności wygrywa pierwszy. Nieznany język
nie jest błędem: schodzi do angielskiego.

Jest tu asymetria, której nie da się zgadnąć, i dlatego API ją deklaruje:
**komunikaty istnieją po angielsku i hiszpańsku; odnośniki — we wszystkich
osiemnastu językach strony**. Poproszenie o niemiecki daje niemieckie odnośniki
i komunikaty wciąż po angielsku. Nie trzeba zgadywać: `_meta.lang` zawiera
`{ "messages", "links" }` z tym, co zastosowano do każdej połowy.

## Serwer MCP

MCP to protokół, którym asystent — Claude, ChatGPT — korzysta z zewnętrznych
narzędzi. `https://api.password.es/mcp` to serwer MCP bez rejestracji i bez
klucza, publikujący jedno narzędzie: `generate_password`, z tymi samymi
parametrami co wyżej.

To część, na której zależy nam najbardziej, i nie z powodów technicznych:
**asystent, który nie ma skąd wziąć hasła, zmyśla je**, a to, co z tego wychodzi,
nie jest losowe — jest tym, co model uważa za wyglądające jak hasło. Z
podłączonym serwerem przestaje improwizować i zwraca hasło zrobione przez
`crypto.getRandomValues()`, z analizą i z ostrzeżeniem zawartym w opisie
narzędzia i w każdym wyniku. To ostrzeżenie jest właśnie tym, co asystent
ostatecznie odczytuje temu, kto poprosił o hasło, i dlatego tam jest.

Jeśli przychodzisz z innych serwerów MCP, jedna rzecz: **ten jest bezstanowy.**
POST dostaje odpowiedź JSON i nie otwiera żadnego strumienia, `Mcp-Session-Id`
nie jest ani wystawiany, ani oczekiwany, powiadomienie dostaje 202 bez treści, a
GET zwraca 405. Specyfikacja 2025-06-18 wprost na to pozwala, ale kto oczekuje
sesji i SSE, będzie debugował po omacku, jeśli nikt mu tego nie powie.

## Czego nie robi

**`/v1/check` zwraca 501.** To nie przeoczenie ani niedokończony endpoint: jest
tak celowo, a sama odpowiedź tłumaczy dlaczego. Zwrócenie tych samych liczb co
sprawdzanie wymaga tego samego silnika wzorców, który działa na stronie, a to
kosztuje od 11 ms do 3,6 s CPU na żądanie, zależnie od tego, co się wyśle. W
usłudze bez rejestracji i bez klucza ten rozrzut to decyzja produktowa — gdzie
postawić limit długości — której jeszcze nie podjęto. Tymczasem 501 niesie
`checker_url` wskazujący sprawdzanie na stronie w żądanym języku, które robi
dokładnie to i nic nie wysyła.

Nie ma też kont, kluczy ani planów. A skoro nie istnieją, w całym API nie ma ani
jednego odnośnika do rejestracji: nawet w błędzie przekroczonego limitu, gdzie
wszyscy go umieszczają.

## Limity

Jeden, i to ten faktycznie egzekwowany: **60 żądań na minutę na IP**. Nie trzeba
wierzyć tej stronie: liczba podróżuje w każdej odpowiedzi, w
`_meta.limits.burst`. Po przekroczeniu przychodzi 429 z `Retry-After` i
nagłówkami `RateLimit-*`.

W `_meta` zobaczysz też blok `quota` z wartościami `null`. To miejsce
zarezerwowane na czas, gdy pojawią się konta, i jest puste celowo: **limit
ogłoszony i nieegzekwowany jest gorszy niż brak limitu**, bo ten, kto integruje,
przestrzega go i programuje wobec liczby, której nikt nie liczy.

## A i tak — zastanów się dwa razy

API generujące hasła jest w gruncie rzeczy antywzorcem: hasło wędruje przez sieć
i przechodzi przez maszynę, która nie jest twoja. To, że nic nie przechowujemy,
nie zmienia kształtu problemu, tylko naszą jego część — a wiesz już, ile warta
jest [obietnica, której nie możesz sprawdzić](/pl/blog/dlaczego-nie-wysylamy-twojego-hasla/).

Dlatego ostrzeżenie nie mieszka tylko na tej stronie: podróżuje w każdej
odpowiedzi, w języku, o który poprosisz. I dlatego ten akapit jest tutaj, a nie
schowany na końcu dokumentacji. **Do hasła, którego użyjesz sam,
[generator](/pl/) tej strony działa w całości w twojej przeglądarce i nic nie
wysyła.** API jest do tego drugiego: do tego, co dzieje się, gdy nikogo nie ma
przed ekranem.

Szczegóły są na dwóch stronach. [Czym jest API](/pl/api/) mówi, dla kogo jest,
co odpowiada dziś, a co nie. [Dokumentacja](/pl/api/docs/) ma dziewięć
parametrów, wszystkie pola wyjaśnione jedno po drugim, kody błędów i limity; to
ta, którą otwiera się obok edytora. A jeśli chcesz, żeby przeczytała to maszyna,
jest `openapi.json`.

---

*Źródła: samo API, zweryfikowane wobec produkcji 31 sierpnia 2026 —
`POST /v1/generate`, `POST /v1/check` (501), `POST /mcp` i `GET /openapi.json` ·
liczby analizy pochodzą z tego samego silnika co generator i sprawdzanie na
password.es · model ataku to 10¹² prób na sekundę, offline i z szybkim hashem,
ten sam co w reszcie strony · serwer MCP implementuje specyfikację 2025-06-18 z
bezstanowym transportem Streamable HTTP.*
