Aquest blog fa mesos que repeteix el mateix: la teva contrasenya no hauria de
sortir del navegador. El
generador treu l’atzar de crypto.getRandomValues() a la teva pròpia
màquina i el comprovador analitza el que escrius sense
enviar-ho enlloc.
I avui publiquem una API que genera contrasenyes en un servidor.
La contradicció és evident i no la dissimularem: cada resposta de l’API
porta un avís que diu exactament això. Però hi ha llocs on no hi ha navegador
—un script que dóna d’alta cent comptes, un servidor que fabrica una credencial
temporal, un assistent a qui algú demana una contrasenya i se la inventa— i allà
l’alternativa no és «el navegador»: és un random() mal triat o una cadena
escrita a mà. Per això existeix això.
La crida sencera
Sense clau, sense registre, sense capçaleres. Això és tot:
curl -X POST https://api.password.es/v1/generate
Retorna una contrasenya de 16 caràcters i la seva anàlisi. Executada mentre
s’escrivia aquest paràgraf: x*7$9,BUy9PPvOI?, treta d’un alfabet de 89
caràcters, 103,6 bits d’entropia i un temps de trencament de 2,5 × 10¹¹
anys. Nivell 4 de 4.
Cap d’aquests números és nou. Surten del mateix motor que dibuixa el mesurador de la portada: la mateixa fórmula de bits, el mateix model d’atac —10¹² intents per segon, sense connexió, hash ràpid— i la mateixa escala de nivell del comprovador. Si el web i l’API donessin números diferents per a la mateixa contrasenya, un dels dos estaria mentint.
Què retorna, camp a camp
La resposta porta passwords —sempre un array, encara que en demanis una sola—
i un bloc analysis amb length, pool, bits, log10_guesses,
crack_time_log10_seconds, crack_time, level, level_scale i ceiling.
Dos mereixen un paràgraf. level_scale diu d’on ha sortit el nivell (avui
sempre "time"), perquè una divergència futura entre el web i l’API es vegi al
camp en comptes d’haver-la de deduir comparant números. I ceiling diu si la
xifra és exacta o un sostre: a generate sempre és false, perquè la
contrasenya l’ha feta el servidor i sap amb quin alfabet; al comprovador del web
no sempre pot ser-ho, perquè allà la contrasenya la portes tu.
Després ve notice, l’avís, i un bloc _meta amb el pla, l’idioma aplicat, els
límits i un enllaç a la documentació.
Les opcions
Totes opcionals, i amb els noms en anglès perquè qui integra una API escriu els
camps tal qual: length (4–64, per defecte 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}'
Dos detalls que la documentació explica i que convé saber abans d’integrar-ho.
exclude_ambiguous treu sis caràcters, no set: descarta 0 O 1 I l | o,
però la barra vertical no era al joc de símbols d’entrada, així que l’alfabet
baixa de 89 a 83 i no a 82. Per això la resposta diu pool 83. I no_repeats
no és una garantia absoluta: torna a provar deu vegades, exactament com el
generador del web, i a 64 caràcters s’hi cola una repetició contigua al voltant
del 0,1 % de les vegades. Dir-ho és més útil que prometre el contrari.
L’idioma
Per defecte respon en anglès, que és el que espera qui integra sense dir res. Es
canvia amb ?lang= a l’URL, amb "lang" al cos o amb la capçalera
Accept-Language, i si es contradiuen guanya el primer. Un idioma que no
existeix no és un error: cau a l’anglès.
Aquí hi ha una asimetria que no s’endevina, i per això l’API la declara: els
missatges existeixen en anglès i castellà; els enllaços, en els divuit idiomes
del lloc. Demanar alemany et dóna els enllaços en alemany i els missatges
encara en anglès. No cal suposar-ho: _meta.lang porta
{ "messages", "links" } amb el que s’ha aplicat a cada meitat.
El servidor MCP
MCP és el protocol amb què un assistent —Claude, ChatGPT— fa servir eines
externes. https://api.password.es/mcp és un servidor MCP sense registre i
sense clau, i publica una sola eina: generate_password, amb els mateixos
paràmetres de dalt.
És la part que més ens importa, i no pel costat tècnic: un assistent que no té
d’on treure una contrasenya se la inventa, i el que en surt no és aleatori, és
el que el model considera que té forma de contrasenya. Amb el servidor connectat
deixa d’improvisar i en retorna una feta amb crypto.getRandomValues(), amb la
seva anàlisi i amb l’avís inclòs a la descripció de l’eina i a cada resultat.
Aquest avís és justament el que l’assistent acaba llegint a qui li ha demanat la
contrasenya, i per això hi és.
Si véns d’altres servidors MCP, una sola dada: aquest no té estat. El POST
es respon amb JSON i no obre cap stream, Mcp-Session-Id ni s’emet ni s’espera,
una notificació es respon amb 202 sense cos i el GET retorna 405. L’especificació
2025-06-18 ho permet explícitament, però qui espera sessions i SSE depurarà a
cegues si ningú l’hi diu.
El que no fa
/v1/check retorna 501. No és un descuit ni un endpoint a mig fer: està
així a propòsit, i la mateixa resposta explica per què. Retornar els mateixos
números que el comprovador exigeix el mateix motor de patrons que corre al web,
i això costa entre 11 ms i 3,6 s de CPU per petició segons què li enviïs. En un
servei sense registre i sense clau, aquesta forquilla és una decisió de producte
—on es posa el sostre de longitud— que encara no s’ha pres. Mentrestant, el 501
porta un checker_url que apunta al comprovador del web en l’idioma que hagis
demanat, que fa exactament això sense enviar res.
Tampoc existeixen els comptes, ni les claus, ni els plans. I com que no existeixen, no hi ha ni un sol enllaç a un registre a tota l’API: ni tan sols a l’error de límit superat, que és on tothom el posa.
Els límits
Un, i és el que s’aplica de veritat: 60 peticions per minut i per IP. No cal
creure’s aquesta pàgina: el número viatja dins de cada resposta, a
_meta.limits.burst. Si te’l passes surt un 429 amb Retry-After i capçaleres
RateLimit-*.
A _meta hi veuràs a més un bloc quota amb els valors a null. És el forat
reservat per quan hi hagi comptes, i va buit a propòsit: un límit anunciat i
no aplicat és pitjor que no anunciar-ne cap, perquè qui integra el respecta i
programa contra un número que ningú està comptant.
I tot i així, pensa-t’ho dues vegades
Una API que genera contrasenyes és, al capdavall, un antipatró: la contrasenya viatja per la xarxa i passa per una màquina que no és la teva. Que nosaltres no guardem res no canvia la forma del problema, només la nostra part —i ja saps què val una promesa que no pots comprovar.
Per això l’avís no viu només en aquesta pàgina: viatja a cada resposta, en l’idioma que demanis. I per això aquest paràgraf és aquí i no amagat al final de la documentació. Per a una contrasenya que faràs servir tu, el generador d’aquest lloc corre sencer al teu navegador i no envia res. L’API és per a l’altra cosa: el que passa sense ningú davant d’una pantalla.
Els detalls són a dues pàgines. Què és l’API explica per a qui és,
què respon avui i què no. La referència té els nou paràmetres,
tots els camps explicats un a un, els codis d’error i els límits; és la que
s’obre amb l’editor al costat. I si el que vols és que ho llegeixi una màquina,
hi ha openapi.json.
Fonts: la mateixa API, verificada contra producció el 31 d’agost de 2026 —
POST /v1/generate, POST /v1/check (501), POST /mcp i GET /openapi.json ·
els números de l’anàlisi surten del mateix motor que el generador i el
comprovador de password.es · el model d’atac és 10¹² intents per segon, sense
connexió i amb hash ràpid, el mateix que la resta del lloc · el servidor MCP
implementa l’especificació 2025-06-18 amb transport Streamable HTTP sense estat.
Foto de Stanislav Kondratiev · Pexels