A API do password.es já responde: como se usa

Publicado a por David Carrero

Este blogue repete a mesma coisa há meses: a tua palavra-passe não devia sair do navegador. O gerador tira o acaso de crypto.getRandomValues() na tua própria máquina e o verificador analisa o que escreves sem o enviar para lado nenhum.

E hoje publicamos uma API que gera palavras-passe num servidor.

A contradição é evidente e não vamos disfarçá-la: cada resposta da API leva um aviso que diz exatamente isso. Mas há sítios onde não existe navegador — um script que cria cem contas, um servidor que produz uma credencial temporária, um assistente a quem alguém pede uma palavra-passe e que a inventa — e aí a alternativa não é «o navegador»: é um random() mal escolhido ou uma cadeia escrita à mão. É para isso que isto serve.

A chamada inteira

Sem chave, sem registo, sem cabeçalhos. É isto tudo:

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

Devolve uma palavra-passe de 16 caracteres e a sua análise. Executada enquanto se escrevia este parágrafo: x*7$9,BUy9PPvOI?, tirada de um alfabeto de 89 caracteres, 103,6 bits de entropia e um tempo de quebra de 2,5 × 10¹¹ anos. Nível 4 em 4.

Nenhum destes números é novo. Saem do mesmo motor que desenha o medidor da página inicial: a mesma fórmula dos bits, o mesmo modelo de ataque — 10¹² tentativas por segundo, offline, hash rápido — e a mesma escala de nível do verificador. Se o site e a API dessem números diferentes para a mesma palavra-passe, um dos dois estaria a mentir.

O que devolve, campo a campo

A resposta traz passwords — sempre um array, mesmo que peças uma só — e um bloco analysis com length, pool, bits, log10_guesses, crack_time_log10_seconds, crack_time, level, level_scale e ceiling.

Dois deles merecem um parágrafo. level_scale diz de onde saiu o nível (hoje sempre "time"), para que uma divergência futura entre o site e a API se veja no campo em vez de ter de ser deduzida comparando números. E ceiling diz se o valor é exato ou um teto: em generate é sempre false, porque a palavra-passe foi feita pelo servidor e ele sabe com que alfabeto; no verificador do site nem sempre pode sê-lo, porque aí a palavra-passe trazes-la tu.

Depois vem notice, o aviso, e um bloco _meta com o plano, o idioma aplicado, os limites e uma ligação para a documentação.

As opções

Todas opcionais, e com os nomes em inglês porque quem integra uma API escreve os campos tal e qual: length (4–64, por omissão 16), count (1–20), lower, upper, digits, symbols, exclude_ambiguous, no_repeats e lang.

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

Dois detalhes que a documentação explica e que convém saber antes de integrar. exclude_ambiguous retira seis caracteres, não sete: descarta 0 O 1 I l | o, mas a barra vertical não estava no conjunto de símbolos à partida, por isso o alfabeto desce de 89 para 83 e não para 82. É por isso que a resposta diz pool 83. E no_repeats não é uma garantia absoluta: tenta dez vezes, exatamente como o gerador do site, e a 64 caracteres uma repetição contígua passa cerca de 0,1 % das vezes. Dizê-lo é mais útil do que prometer o contrário.

O idioma

Por omissão responde em inglês, que é o que espera quem integra sem dizer nada. Muda-se com ?lang= no URL, com "lang" no corpo ou com o cabeçalho Accept-Language, e se houver conflito ganha o primeiro. Um idioma que não existe não é erro: cai para inglês.

Há aqui uma assimetria que não se adivinha, e por isso a API declara-a: as mensagens existem em inglês e espanhol; as ligações, nos dezoito idiomas do site. Pedir alemão dá ligações em alemão e mensagens ainda em inglês. Não é preciso supor: _meta.lang traz { "messages", "links" } com o que foi aplicado a cada metade.

O servidor MCP

MCP é o protocolo com que um assistente — Claude, ChatGPT — usa ferramentas externas. https://api.password.es/mcp é um servidor MCP sem registo e sem chave, e publica uma única ferramenta: generate_password, com os mesmos parâmetros de cima.

É a parte que mais nos importa, e não pelo lado técnico: um assistente que não tem de onde tirar uma palavra-passe inventa-a, e o que sai dali não é aleatório, é aquilo que o modelo considera que tem forma de palavra-passe. Com o servidor ligado deixa de improvisar e devolve uma feita com crypto.getRandomValues(), com a sua análise e com o aviso incluído na descrição da ferramenta e em cada resultado. Esse aviso é exatamente o que o assistente acaba por ler a quem pediu a palavra-passe, e é por isso que está lá.

Se vens de outros servidores MCP, um dado só: este não tem estado. O POST é respondido com JSON e não abre nenhum stream, Mcp-Session-Id não é emitido nem esperado, uma notificação recebe 202 sem corpo e o GET devolve 405. A especificação 2025-06-18 permite isso explicitamente, mas quem espera sessões e SSE vai depurar às cegas se ninguém lho disser.

O que não faz

/v1/check devolve 501. Não é um descuido nem um endpoint a meio: está assim de propósito, e a própria resposta explica porquê. Devolver os mesmos números do verificador exige o mesmo motor de padrões que corre no site, e isso custa entre 11 ms e 3,6 s de CPU por pedido consoante o que lhe mandes. Num serviço sem registo e sem chave, essa amplitude é uma decisão de produto — onde pôr o teto de comprimento — que ainda não foi tomada. Entretanto, o 501 traz um checker_url que aponta para o verificador do site no idioma pedido, que faz exatamente isto sem enviar nada.

Também não existem contas, nem chaves, nem planos. E como não existem, não há uma única ligação para um registo em toda a API: nem sequer no erro de limite excedido, que é onde toda a gente a põe.

Os limites

Um, e é o que se aplica mesmo: 60 pedidos por minuto e por IP. Não é preciso acreditar nesta página: o número viaja dentro de cada resposta, em _meta.limits.burst. Ao passar aparece um 429 com Retry-After e cabeçalhos RateLimit-*.

Em _meta verás ainda um bloco quota com os valores a null. É o espaço reservado para quando houver contas, e vai vazio de propósito: um limite anunciado e não aplicado é pior do que não anunciar nenhum, porque quem integra respeita-o e programa contra um número que ninguém está a contar.

E mesmo assim, pensa duas vezes

Uma API que gera palavras-passe é, no fundo, um antipadrão: a palavra-passe viaja pela rede e passa por uma máquina que não é a tua. Nós não guardarmos nada não muda a forma do problema, só a nossa parte dele — e já sabes o que vale uma promessa que não podes comprovar.

Por isso o aviso não vive só nesta página: viaja em cada resposta, no idioma que pedires. E por isso este parágrafo está aqui e não escondido no fim da documentação. Para uma palavra-passe que vais usar tu, o gerador deste site corre inteiro no teu navegador e não envia nada. A API é para a outra coisa: o que acontece sem ninguém à frente de um ecrã.

Os detalhes estão em duas páginas. O que é a API conta para quem é, o que responde hoje e o que não. A referência tem os nove parâmetros, todos os campos explicados um a um, os códigos de erro e os limites; é a que se abre com o editor ao lado. E se o que queres é que uma máquina a leia, há o openapi.json.


Fontes: a própria API, verificada contra produção a 31 de agosto de 2026 — POST /v1/generate, POST /v1/check (501), POST /mcp e GET /openapi.json · os números da análise saem do mesmo motor do gerador e do verificador do password.es · o modelo de ataque é 10¹² tentativas por segundo, offline e com hash rápido, o mesmo do resto do site · o servidor MCP implementa a especificação 2025-06-18 com transporte Streamable HTTP sem estado.

Foto de Stanislav Kondratiev · Pexels

← Voltar ao blog