API

パスワード API リファレンス

api.password.es のリファレンスです。パラメーター、応答のフィールド、エラーコード、そして制限。例はそのまま端末に貼れます。

これが何で、誰のためで、どういうときに使わないほうがよいかを知りたいなら、API のページから始めてください。

エンドポイント

すべて https://api.password.es の下にあります。二つが応答し、一つはまだ——そしてその一つは、自分の応答の中でそう言います。

パスワードを生成する

本文は任意です。なければ四種類の文字を有効にした 16 文字が返り、あれば指定したとおりに返ります。

リクエスト
curl -X POST https://api.password.es/v1/generate \
  -H 'content-type: application/json' \
  -d '{"length":20,"exclude_ambiguous":true}'
レスポンス
{
  "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/"
  }
}

パラメーター

すべて任意です。表は英語のままで、十八の言語すべてで同一にしてあります。意図してそうしています。API を組み込む人はフィールド名を書かれたとおりに打ちますし、exclude_ambiguous の十八通りの訳は、範囲ではなく負債になるからです。

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.

それぞれの数字の意味

同じ考え方です。参照は英語、説明はその隣に。ここにある数字はどれも新しいものではありません——すべて、トップページのメーターを描いているのと同じエンジンから出ています。

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.

応答の言語

既定では英語で応答します。何も指定せずに組み込む人が期待するのがそれだからです。変える方法は三つあり、食い違ったときは先のものが勝ちます。URL の ?lang=、本文の "lang"、そして Accept-Language ヘッダーです。

ここには知っておいたほうがよい非対称があります。メッセージは英語とスペイン語にしかありませんが、リンクはサイトの十八言語すべてにあります。ドイツ語を指定すると、リンクはドイツ語になり、メッセージは英語のままです。

リクエスト
curl -X POST 'https://api.password.es/v1/generate?lang=de' \
  -H 'content-type: application/json' \
  -d '{"length":20}'
レスポンス
"_meta": {
  "lang": { "messages": "en", "links": "de" }
}

推測は要りません。どちらの半分に何が適用されたかを、応答ごとに _meta.lang が明かします。存在しない言語はエラーではなく、英語に落ちて、_meta.lang がそう言います。

パスワードを検査する——まだです

/v1/check501 を返します。不具合でも見落としでもなく、意図してそうしています。応答が、何が足りないのか、そのあいだどこへ行けばよいのかを伝えます。checker_url は、指定した言語のチェッカーを指します。

リクエスト
curl -X POST https://api.password.es/v1/check \
  -H 'content-type: application/json' \
  -d '{"password":"x"}'
レスポンス
{
  "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" }
}

エラー

どれも形は同じです。コードとしての短い error、普通の文章の message——AI アシスタントが利用者に読み上げるのはこれです——、原因になった field(ある場合)、docs、そしていつもの _meta

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.

制限

一つだけ、そして実際に適用されているのはそれだけです。IP ごとに毎分 60 リクエスト。このページを信じる必要はありません。その数字は毎回の応答の _meta.limits.burst に入って届きます。

超えると、Retry-AfterRateLimit-* ヘッダーを添えた 429 が返り、どうすればよいかを普通の文章で伝えます。登録や料金へのリンクは入っていません。登録も料金も存在しないからです。

_meta にはもう一つ、二つの値がどちらも nullquota ブロックがあります。わざとです。アカウントができたときのために空けてある場所で、いまは誰も一日あたりのリクエストを数えていないので空のままにしてあります。掲げておいて守らせない制限は、何も掲げないより悪いのです。

MCP サーバー

MCP は、Claude や ChatGPT のようなアシスタントが外部ツールを使うためのプロトコルです。このアドレスをアシスタントに接続すると、パスワードを作り話で返すのではなく、ここと同じ数値で生成します。登録もキーも不要で、毎分 60 リクエストという制限も同じです。

ステートレスなサーバーです。他の MCP サーバーから来た場合は知っておくとよいでしょう。POST には JSON で応答し、ストリームは開きません。Mcp-Session-Id は発行も要求もしません。通知には本文なしの 202 を返し、GET は 405 を返します。2025-06-18 の仕様はこれを明示的に認めています。

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"}}}'

公開しているツールは 1 つだけgenerate_password で、上の表と同じパラメータに lang が加わります。check_password_strength はありませんし、/v1/check が存在しない限り追加しません。常にエラーを返すツールはツールではなく、アシスタントのカタログの中の破られた約束です。

これがアンチパターンであるという注意書きは、ツールの説明と結果のたびに一緒に届きます。意図的です。アシスタントがパスワードを求めた人に読み上げるのは、その文だからです。

機械が読むドキュメント

このページのほかに OpenAPI 3.1 の記述があり、そちらはもう公開されています。api.password.es/openapi.json です。クライアントの生成器、補完のあるエディター、あるいは誰にも教わらずにどんなフィールドがあるか知りたいエージェントが読むのがこれです。上の表と同じパラメーター、エラーコード、そして quota が空である理由まで書いてあります。