API

Referencia da API de contrasinais

A referencia de api.password.es: cada parámetro, cada campo da resposta, cada código de erro e os límites. Os exemplos péganse nun terminal tal como están.

Se o que buscas é que é isto, para quen e cando non convén usalo, comeza por a páxina da API.

Os endpoints

Todo pende de https://api.password.es. Dous responden e un aínda non — e ese dío na súa propia resposta.

Xerar un contrasinal

O corpo é opcional: sen el saen 16 caracteres cos catro tipos activados. Con el, o que pidas.

A petición
curl -X POST https://api.password.es/v1/generate \
  -H 'content-type: application/json' \
  -d '{"length":20,"exclude_ambiguous":true}'
A resposta
{
  "passwords": [
    "P#f.aK+w4pcsx]}Gx;*>"
  ],
  "analysis": {
    "length": 20,
    "pool": 83,
    "bits": 127.50078862693852,
    "log10_guesses": 38.08053185185735,
    "crack_time_log10_seconds": 26.08053185185735,
    "crack_time": {
      "value": "3.8 × 10¹⁸",
      "unit": "years"
    },
    "level": 4,
    "level_scale": "time",
    "ceiling": false
  },
  "notice": "Generated on someone else's machine, which is a security antipattern even though we store nothing. For a password you will actually use, the generator at https://password.es/en/ runs entirely in your browser and sends nothing.",
  "_meta": {
    "plan": "anonymous",
    "lang": {
      "messages": "en",
      "links": "en"
    },
    "limits": {
      "burst": {
        "limit": 60,
        "window_seconds": 60
      }
    },
    "quota": {
      "limit": null,
      "remaining": null,
      "reset": "2026-09-01T00:00:00.000Z"
    },
    "docs": "https://password.es/api/"
  }
}

Os parámetros

Todos opcionais. A táboa vai en inglés e é idéntica nas dezaoito linguas, a propósito: quen integra unha API escribe os nomes de campo tal como se escriben, e dezaoito traducións de exclude_ambiguous serían débeda, non alcance.

FieldTypeDefaultNotes
lengthinteger 4–6416How many characters. The same range as the generator on this site.
countinteger 1–201How many passwords to return. passwords is always an array, including with count 1.
lowerbooleantrueInclude a–z (26 characters).
upperbooleantrueInclude A–Z (26 characters).
digitsbooleantrueInclude 0–9 (10 characters).
symbolsbooleantrueInclude ~!@#$%^&*()_+-=[]{};:,./<>? — the same 27 as the slider on the home page, no more.
exclude_ambiguousbooleanfalseDrops 0 O 1 I l | o. Six of them in practice, not seven: | is not in the symbol set to begin with. That is why pool reads 83 above instead of 89.
no_repeatsbooleanfalseAvoids adjacent repeated characters. Not an absolute guarantee: it retries ten times, exactly as the web generator does. At length 64 that lets a repeat through about 0.1% of the time.
langstringenWhich language to answer in. One of the site's eighteen. Also accepted as ?lang= in the URL, which wins over this field; without either, Accept-Language is read. An unknown value is not an error — it falls back to English. See the section below: messages exist in English and Spanish, links in all eighteen.

Que significa cada número

A mesma idea: a referencia en inglés, a explicación ao lado. Ningún destes números é novo — saen todos do mesmo motor que debuxa o medidor da portada.

FieldNotes
passwordsAn array of strings, always — including with count 1.
analysis.lengthHow many characters came back.
analysis.poolThe size of the alphabet the password was drawn from.
analysis.bitsH = L·log2(N), the same formula as the home page. With no_repeats it becomes log2(N)+(L-1)·log2(N-1).
analysis.log10_guessesThe expected work, as a base-10 logarithm: half the keyspace.
analysis.crack_time_log10_secondsAt 1012 guesses/s, offline, fast hash. The same attack model as the rest of the site.
analysis.crack_timeThe same figure in words. unit follows the answer language: years, años
analysis.level0–4. The same scale as the checker, ever since the site unified the two it used to have.
analysis.level_scale"time". Says where the level came from, so that a future divergence is visible instead of having to be inferred by comparing numbers.
analysis.ceilingfalse: the server generated the password, so the figure is exact and not a ceiling. The same flag the checker uses.
noticeThe antipattern warning, in every single response.
_meta.plan"anonymous". The only lane there is; the others arrive with accounts.
_meta.lang{ "messages", "links" } — which language each half actually came back in. They can differ, and that is why the API says so instead of leaving you to guess.
_meta.limits.burstThe rate limit actually enforced: limit requests per window_seconds.
_meta.quotaThe reserved daily-quota slot. limit and remaining are null because nobody counts daily requests yet.
_meta.docsA link back to the documentation.

A lingua da resposta

Por defecto responde en inglés, que é o que agarda quen integra sen dicir nada. Cámbiase de tres formas, e se non coinciden gaña a primeira: ?lang= no URL, "lang" no corpo e a cabeceira Accept-Language.

Aquí hai unha asimetría que convén saber: as mensaxes existen en inglés e castelán; as ligazóns, nas dezaoito linguas do sitio. Pedir alemán dache as ligazóns en alemán e as mensaxes aínda en inglés.

A petición
curl -X POST 'https://api.password.es/v1/generate?lang=de' \
  -H 'content-type: application/json' \
  -d '{"length":20}'
A resposta
"_meta": {
  "lang": { "messages": "en", "links": "de" }
}

Non hai que adiviñalo: cada resposta declara en _meta.lang que se aplicou a cada metade. E unha lingua que non existe non é un erro — cae ao inglés, e _meta.lang dío.

Comprobar un contrasinal: aínda non

/v1/check devolve 501. Non é un fallo nin un descoido: está así a propósito, e a resposta explica que falta e onde ir mentres tanto. O checker_url apunta ao comprobador do sitio na lingua que pediras.

A petición
curl -X POST https://api.password.es/v1/check \
  -H 'content-type: application/json' \
  -d '{"password":"x"}'
A resposta
{
  "error": "not_implemented",
  "message": "/v1/check does not exist yet. Returning the same numbers as the password.es checker requires its very same pattern engine, and that costs between 11 ms and 3.6 s of CPU per request depending on the input: it is waiting on a plan cap decision and on a length cap. Meanwhile the web checker does exactly this in your browser, sending nothing: https://password.es/en/checker/",
  "checker_url": "https://password.es/en/checker/",
  "docs": "https://password.es/api/",
  "_meta": { "…": "igual que arriba" }
}

Os erros

Todos teñen a mesma forma: un error curto para o código, unha message en prosa —que é o que un asistente de IA lle le ao seu usuario—, ás veces o field que o provocou, un docs e o mesmo _meta de sempre.

HTTPerrorNotes
400invalid_lengthlength outside 4–64. field names it.
400invalid_countcount outside 1–20. field names it.
400empty_alphabetAll four character types turned off, so there is no alphabet to draw from. No field: it is the combination, not one parameter.
400unknown_parameterA parameter this endpoint does not accept. field gives the offending name.
429rate_limitedOver 60 requests in a minute. Carries Retry-After and RateLimit-* headers, and limit / window_seconds in the body.
501not_implementedOnly from /v1/check. Carries checker_url, pointing at the web checker in the answer language.

Os límites

Un só, e é o que se aplica de verdade: 60 peticións por minuto e por IP. Non fai falta crer esta páxina: o número viaxa en cada resposta, dentro de _meta.limits.burst.

Ao pasarse, a resposta é un 429 con Retry-After e cabeceiras RateLimit-*, máis unha mensaxe en prosa que di que facer. Non leva ligazón a rexistro nin a prezos, porque non hai rexistro nin prezos.

En _meta verás ademais un bloque quota cos dous valores en null. Está así a propósito: é o oco reservado para cando existan as contas, e vai baleiro porque hoxe ninguén conta peticións por día. Un límite anunciado e non feito cumprir é peor que non anunciar ningún.

O servidor MCP

MCP é o protocolo co que asistentes como Claude ou ChatGPT usan ferramentas externas. Conecta este enderezo ao teu asistente e poderá xerar contrasinais con estes mesmos números en vez de inventalos. Sen rexistro e sen chave, co mesmo límite de 60 peticións por minuto.

É un servidor sen estado, e convén sabelo se vés doutros servidores MCP: o POST respóndese con JSON e non se abre ningún stream, Mcp-Session-Id non se emite nin se espera, unha notificación respóndese con 202 e sen corpo, e o GET devolve 405. A especificación 2025-06-18 permíteo explicitamente.

curl -X POST https://api.password.es/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"generate_password",
                 "arguments":{"length":20,"lang":"es"}}}'

Publica unha soa ferramenta, generate_password, cos mesmos parámetros da táboa de arriba máis lang. Non hai check_password_strength e non a haberá mentres /v1/check non exista: unha ferramenta que sempre devolve erro non é unha ferramenta, é unha promesa rota dentro do catálogo dun asistente.

O aviso de que isto é un antipatrón viaxa na descrición da ferramenta e en cada resultado. É deliberado: é o que o asistente acaba lendo a quen pediu o contrasinal.

A documentación que len as máquinas

Ademais desta páxina hai unha descrición en OpenAPI 3.1, e esa si está publicada: api.password.es/openapi.json. É o que le un xerador de clientes, un editor con autocompletado ou un axente que queira saber que campos existen sen que llo conte ninguén. Describe os mesmos parámetros da táboa de arriba, os códigos de erro e o porqué do quota baleiro.