# 비밀번호 API 레퍼런스 · password.es

> POST /v1/generate의 모든 매개변수, 응답의 각 필드, 오류 코드, api.password.es의 제한. 그대로 동작하는 curl 예시 포함.

password.es · Original: https://password.es/ko/api/docs/

---

# 비밀번호 API 레퍼런스

`api.password.es`의 레퍼런스입니다. 모든 매개변수, 응답의 모든 필드, 모든 오류 코드, 그리고 제한. 예시는 터미널에 그대로 붙여 넣으면 됩니다.

이게 무엇이고, 누구를 위한 것이며, 언제 *쓰지 않는* 게 나은지를 찾는다면 [API 페이지](https://password.es/ko/api/)부터 보십시오.

## 엔드포인트

전부 `https://api.password.es` 아래에 있습니다. 둘은 응답하고 하나는 아직입니다—그리고 그 하나는 자기 응답 안에서 그렇게 말합니다.

- POST/v1/generate 비밀번호를 하나 이상 만들고 그 분석을 돌려줍니다.
- GET/openapi.json API 설명서. OpenAPI 3.1 형식입니다.
- POST/mcp 어시스턴트를 위한 MCP 서버. 도구 하나: `generate_password`.
- POST/v1/check 501 아직 없습니다. 오류가 무엇이 빠졌는지, 그동안 어디로 가면 되는지 알려줍니다.

## 비밀번호 만들기

본문은 선택입니다. 없으면 네 가지 문자 종류를 모두 켠 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`를 열여덟 번 번역하는 일은 범위가 아니라 부채이기 때문입니다.

- Field
- Type
- Default
- Notes
- length
- integer 4–64
- 16
- How many characters. The same range as the generator on this site.
- count
- integer 1–20
- 1
- How many passwords to return. `passwords` is always an array, including with `count` 1.
- lower
- boolean
- true
- Include a–z (26 characters).
- upper
- boolean
- true
- Include A–Z (26 characters).
- digits
- boolean
- true
- Include 0–9 (10 characters).
- symbols
- boolean
- true
- Include `~!@#$%^&*()_+-=[]{};:,./<>?` — the same 27 as the slider on the home page, no more.
- exclude_ambiguous
- boolean
- false
- Drops `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_repeats
- boolean
- false
- Avoids 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.
- lang
- string
- `en`
- Which 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.

## 숫자 하나하나의 뜻

같은 원칙입니다. 참조는 영어로, 설명은 그 옆에. 여기 있는 숫자 중 새로운 것은 하나도 없습니다—모두 첫 화면의 계기판을 그리는 바로 그 엔진에서 나옵니다.

- Field
- Notes
- passwords
- An array of strings, always — including with `count` 1.
- analysis.length
- How many characters came back.
- analysis.pool
- The size of the alphabet the password was drawn from.
- analysis.bits
- `H = L·log2(N)`, the same formula as the home page. With `no_repeats` it becomes `log2(N)+(L-1)·log2(N-1)`.
- analysis.log10_guesses
- The expected work, as a base-10 logarithm: half the keyspace.
- analysis.crack_time_log10_seconds
- At 10^12 guesses/s, offline, fast hash. The same attack model as the rest of the site.
- analysis.crack_time
- The same figure in words. `unit` follows the answer language: `years`, `años`…
- analysis.level
- 0–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.ceiling
- `false`: the server generated the password, so the figure is exact and not a ceiling. The same flag the checker uses.
- notice
- The 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.burst
- The rate limit actually enforced: `limit` requests per `window_seconds`.
- _meta.quota
- The reserved daily-quota slot. `limit` and `remaining` are `null` because nobody counts daily requests yet.
- _meta.docs
- A 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/check`는 `501`을 돌려줍니다. 버그도 실수도 아니라 일부러 그렇게 둔 것이고, 응답이 무엇이 빠졌는지와 그동안 어디로 가면 되는지를 알려줍니다. `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`.

- HTTP
- error
- Notes
- 400
- `invalid_length`
- `length` outside 4–64. `field` names it.
- 400
- `invalid_count`
- `count` outside 1–20. `field` names it.
- 400
- `empty_alphabet`
- All four character types turned off, so there is no alphabet to draw from. No `field`: it is the combination, not one parameter.
- 400
- `unknown_parameter`
- A parameter this endpoint does not accept. `field` gives the offending name.
- 429
- `rate_limited`
- Over 60 requests in a minute. Carries `Retry-After` and `RateLimit-*` headers, and `limit` / `window_seconds` in the body.
- 501
- `not_implemented`
- Only from `/v1/check`. Carries `checker_url`, pointing at the web checker in the answer language.

## 제한

하나뿐이고, 실제로 적용되는 것도 그것뿐입니다. **IP당 분당 60회**. 이 페이지를 믿을 필요는 없습니다. 그 숫자는 모든 응답의 `_meta.limits.burst`에 실려 옵니다.

넘기면 `Retry-After`와 `RateLimit-*` 헤더를 단 `429`가 돌아오고, 무엇을 하면 되는지 평범한 문장으로 알려줍니다. 가입이나 요금제로 가는 링크는 없습니다. 가입도 요금제도 없기 때문입니다.

`_meta`에는 두 값이 모두 `null`인 `quota` 블록도 있습니다. 일부러 그렇게 뒀습니다. 계정이 생길 때를 위해 비워 둔 자리이고, 오늘은 아무도 하루치 요청을 세지 않기 때문에 비어 있습니다. 알려놓고 지키게 하지 않는 제한은 아예 알리지 않느니만 못합니다.

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

공개하는 도구는 **하나뿐**인 `generate_password`이며, 위 표와 같은 매개변수에 `lang`이 추가됩니다. `check_password_strength`는 없고 `/v1/check`가 존재하기 전까지는 만들지 않습니다. 항상 오류를 반환하는 도구는 도구가 아니라 어시스턴트 카탈로그 안의 깨진 약속입니다.

이것이 안티패턴이라는 경고는 도구 설명과 모든 결과에 함께 실립니다. 의도한 것입니다. 어시스턴트가 비밀번호를 요청한 사람에게 결국 읽어 주는 문장이 그것이기 때문입니다.

## 기계가 읽는 문서

이 페이지 말고도 **OpenAPI 3.1** 설명서가 있고, 그건 이미 공개되어 있습니다: [api.password.es/openapi.json](https://api.password.es/openapi.json). 클라이언트 생성기나 자동 완성이 되는 편집기, 또는 누가 알려주지 않아도 어떤 필드가 있는지 알고 싶은 에이전트가 읽는 것이 이것입니다. 위 표와 같은 매개변수, 오류 코드, 그리고 `quota`가 비어 있는 이유까지 담고 있습니다.
