API

Tài liệu tham chiếu API mật khẩu

Tài liệu tham chiếu của api.password.es: từng tham số, từng trường của phản hồi, từng mã lỗi và các giới hạn. Các ví dụ dán thẳng vào terminal là chạy.

Nếu bạn muốn biết đây là gì, dành cho ai và khi nào không nên dùng, hãy bắt đầu từ trang API.

Các endpoint

Mọi thứ nằm dưới https://api.password.es. Hai cái trả lời và một cái thì chưa — và cái chưa đó tự nói ra trong phản hồi của chính nó.

Tạo một mật khẩu

Phần thân là tuỳ chọn: không có nó thì ra 16 ký tự với cả bốn loại đều bật. Có nó thì ra đúng thứ bạn yêu cầu.

Yêu cầu
curl -X POST https://api.password.es/v1/generate \
  -H 'content-type: application/json' \
  -d '{"length":20,"exclude_ambiguous":true}'
Phản hồi
{
  "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/"
  }
}

Các tham số

Tất cả đều không bắt buộc. Bảng để bằng tiếng Anh và giống hệt nhau ở cả mười tám ngôn ngữ, một cách có chủ đích: người tích hợp một API gõ tên trường đúng như nó được viết, và mười tám bản dịch của exclude_ambiguous sẽ là nợ, không phải phạm vi.

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.

Mỗi con số nghĩa là gì

Cũng vậy: phần tra cứu bằng tiếng Anh, phần giải thích ở bên cạnh. Không con số nào ở đây là mới — tất cả đều ra từ chính bộ máy vẽ thanh đo ở trang chủ.

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.

Ngôn ngữ của phản hồi

Mặc định nó trả lời bằng tiếng Anh, đúng như người tích hợp mà không nói gì sẽ mong đợi. Có ba cách đổi, và nếu chúng khác nhau thì cách đầu thắng: ?lang= trên URL, "lang" trong thân, và header Accept-Language.

Ở đây có một điểm lệch nên biết: thông điệp chỉ có tiếng Anh và tiếng Tây Ban Nha; còn liên kết thì có đủ mười tám ngôn ngữ của trang. Yêu cầu tiếng Đức sẽ cho bạn liên kết tiếng Đức còn thông điệp vẫn tiếng Anh.

Yêu cầu
curl -X POST 'https://api.password.es/v1/generate?lang=de' \
  -H 'content-type: application/json' \
  -d '{"length":20}'
Phản hồi
"_meta": {
  "lang": { "messages": "en", "links": "de" }
}

Không phải đoán: mỗi phản hồi đều khai báo trong _meta.lang điều gì đã áp cho từng nửa. Và một ngôn ngữ không tồn tại không phải là lỗi — nó rơi về tiếng Anh, và _meta.lang nói rõ.

Kiểm tra một mật khẩu: chưa

/v1/check trả về 501. Không phải lỗi cũng không phải quên: cố ý như vậy, và phản hồi giải thích còn thiếu gì và trong lúc chờ thì đi đâu. checker_url trỏ tới trình kiểm tra của trang, đúng ngôn ngữ bạn yêu cầu.

Yêu cầu
curl -X POST https://api.password.es/v1/check \
  -H 'content-type: application/json' \
  -d '{"password":"x"}'
Phản hồi
{
  "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" }
}

Các lỗi

Tất cả đều cùng một hình dạng: một error ngắn làm mã, một message bằng lời —đó là thứ một trợ lý AI đọc cho người dùng nghe—, đôi khi là field gây ra nó, một docs và vẫn _meta như mọi khi.

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.

Giới hạn

Chỉ một, và đó là giới hạn thực sự được áp dụng: 60 yêu cầu mỗi phút cho mỗi IP. Bạn không cần tin trang này: con số đó đi kèm trong mọi phản hồi, ở _meta.limits.burst.

Vượt quá thì phản hồi là 429 kèm Retry-After và các header RateLimit-*, cộng thêm một thông báo bằng lời nói rõ phải làm gì. Trong đó không có liên kết tới đăng ký hay bảng giá, bởi vì không có đăng ký và không có bảng giá.

Trong _meta bạn còn thấy một khối quota với cả hai giá trị đều là null. Cố ý như vậy: đó là chỗ dành sẵn cho khi có tài khoản, và để trống vì hôm nay không ai đếm số yêu cầu mỗi ngày. Một giới hạn được công bố mà không được thực thi còn tệ hơn là không công bố gì cả.

Máy chủ MCP

MCP là giao thức mà các trợ lý như Claude hay ChatGPT dùng để gọi công cụ bên ngoài. Kết nối địa chỉ này với trợ lý của bạn và nó sẽ tạo mật khẩu với đúng những con số này thay vì bịa ra. Không cần đăng ký, không cần khóa, và cùng giới hạn 60 yêu cầu mỗi phút.

Đây là máy chủ không lưu trạng thái, và bạn nên biết điều đó nếu đến từ các máy chủ MCP khác: POST được trả lời bằng JSON và không mở luồng nào, Mcp-Session-Id không được phát ra cũng không được chờ đợi, một thông báo được trả lời bằng 202 và không có thân, còn GET trả về 405. Đặc tả 2025-06-18 cho phép điều này một cách rõ ràng.

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

Nó công bố một công cụ duy nhất, generate_password, với cùng các tham số như bảng ở trên cộng thêm lang. Không có check_password_strength và sẽ không có chừng nào /v1/check chưa tồn tại: một công cụ luôn trả về lỗi thì không phải công cụ, mà là một lời hứa bị phá vỡ trong danh mục của trợ lý.

Lời cảnh báo rằng đây là một phản mẫu đi kèm trong mô tả công cụ và trong mọi kết quả. Đó là chủ ý: đó là điều mà trợ lý cuối cùng sẽ đọc cho người đã yêu cầu mật khẩu.

Tài liệu dành cho máy đọc

Ngoài trang này còn có một bản mô tả OpenAPI 3.1, và bản đó thì đã công bố thật: api.password.es/openapi.json. Đó là thứ mà một trình sinh mã client, một trình soạn thảo có gợi ý tự động hay một tác nhân đọc để biết có những trường nào mà không cần ai chỉ. Nó mô tả đúng các tham số trong bảng ở trên, các mã lỗi và lý do quota để trống.