# Referensi API kata sandi · password.es

> Semua parameter POST /v1/generate, setiap field tanggapan, kode galat, dan batas api.password.es. Dengan contoh curl yang benar-benar jalan.

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

---

# Referensi API kata sandi

Referensi `api.password.es`: setiap parameter, setiap field tanggapan, setiap kode galat, dan batasnya. Contohnya ditempel ke terminal apa adanya.

Kalau yang Anda cari itu apa, untuk siapa, dan kapan sebaiknya *tidak* dipakai, mulailah dari [halaman API](https://password.es/id/api/).

## Endpoint-nya

Semuanya bergantung pada `https://api.password.es`. Dua menjawab dan satu belum — dan yang belum itu mengatakannya dalam tanggapannya sendiri.

- POST/v1/generate Membuat satu atau beberapa kata sandi dan mengembalikan analisisnya.
- GET/openapi.json Deskripsi API, dalam OpenAPI 3.1.
- POST/mcp Server MCP untuk asisten. Satu alat: `generate_password`.
- POST/v1/check 501 Belum ada. Galatnya menjelaskan apa yang kurang dan ke mana harus pergi sementara ini.

## Membuat kata sandi

Badan permintaan opsional: tanpa itu keluar 16 karakter dengan keempat jenis aktif. Dengan itu, sesuai yang Anda minta.

Permintaan

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

Tanggapan

```
{
  "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/"
  }
}
```

## Parameternya

Semuanya opsional. Tabelnya dalam bahasa Inggris dan sama persis di kedelapan belas bahasa, dengan sengaja: yang mengintegrasikan sebuah API mengetik nama field persis seperti tertulis, dan delapan belas terjemahan `exclude_ambiguous` akan jadi utang, bukan cakupan.

- 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.

## Arti setiap angka

Gagasan yang sama: rujukannya dalam bahasa Inggris, penjelasannya di sebelah. Tak satu pun angka ini baru — semuanya keluar dari mesin yang sama yang menggambar meteran di halaman depan.

- 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.

## Bahasa tanggapan

Secara bawaan ia menjawab dalam bahasa Inggris, yang memang diharapkan orang yang mengintegrasikan tanpa berkata apa-apa. Ada tiga cara mengubahnya, dan kalau berbeda yang pertama menang: `?lang=` di URL, `"lang"` di badan, dan header `Accept-Language`.

Ada ketimpangan yang perlu diketahui di sini: **pesan tersedia dalam bahasa Inggris dan Spanyol; tautan, dalam kedelapan belas bahasa situs.** Meminta bahasa Jerman memberi Anda tautan Jerman dan pesan yang masih Inggris.

Permintaan

```
curl -X POST 'https://api.password.es/v1/generate?lang=de' \
  -H 'content-type: application/json' \
  -d '{"length":20}'
```

Tanggapan

```
"_meta": {
  "lang": { "messages": "en", "links": "de" }
}
```

Tak perlu menebak: setiap tanggapan menyatakan di `_meta.lang` apa yang diterapkan pada masing-masing bagian. Dan bahasa yang tidak ada bukan galat — ia jatuh ke Inggris, dan `_meta.lang` mengatakannya.

## Memeriksa kata sandi: belum

`/v1/check` mengembalikan `501`. Ini bukan bug dan bukan kelalaian: memang disengaja, dan tanggapannya menjelaskan apa yang kurang dan ke mana harus pergi sementara ini. `checker_url` menunjuk ke pemeriksa situs dalam bahasa yang Anda minta.

Permintaan

```
curl -X POST https://api.password.es/v1/check \
  -H 'content-type: application/json' \
  -d '{"password":"x"}'
```

Tanggapan

```
{
  "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" }
}
```

## Galat

Semuanya berbentuk sama: `error` pendek sebagai kode, `message` dalam bahasa biasa —itulah yang dibacakan asisten AI kepada penggunanya—, kadang `field` penyebabnya, sebuah `docs`, dan `_meta` yang sama seperti biasa.

- 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.

## Batasnya

Satu saja, dan itulah yang benar-benar diberlakukan: **60 permintaan per menit per IP**. Anda tidak perlu percaya halaman ini: angkanya ikut di setiap tanggapan, di dalam `_meta.limits.burst`.

Kalau terlampaui, tanggapannya adalah `429` dengan `Retry-After` dan header `RateLimit-*`, ditambah pesan biasa yang menjelaskan apa yang harus dilakukan. Tidak ada tautan ke pendaftaran atau harga di dalamnya, karena memang tidak ada pendaftaran dan tidak ada harga.

Di `_meta` Anda juga akan melihat blok `quota` dengan kedua nilainya `null`. Itu disengaja: tempat yang dicadangkan untuk saat akun sudah ada, dan dibiarkan kosong karena hari ini tidak ada yang menghitung permintaan per hari. Batas yang diumumkan tapi tidak ditegakkan lebih buruk daripada tidak mengumumkan batas sama sekali.

## Server MCP

MCP adalah protokol yang dipakai asisten seperti Claude atau ChatGPT untuk menggunakan alat eksternal. Hubungkan alamat ini ke asisten Anda dan ia akan membuat kata sandi dengan angka yang sama persis, bukan mengarangnya. Tanpa pendaftaran dan tanpa kunci, dengan batas yang sama: 60 permintaan per menit.

Ini server **tanpa status**, dan berguna diketahui jika Anda datang dari server MCP lain: POST dijawab dengan JSON tanpa membuka stream, `Mcp-Session-Id` tidak dikirim maupun diharapkan, notifikasi dijawab `202` tanpa isi, dan GET mengembalikan `405`. Spesifikasi 2025-06-18 mengizinkannya secara eksplisit.

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

Ia menerbitkan **satu alat saja**, `generate_password`, dengan parameter yang sama seperti tabel di atas ditambah `lang`. Tidak ada `check_password_strength` dan tidak akan ada selama `/v1/check` belum ada: alat yang selalu mengembalikan galat bukanlah alat, melainkan janji yang tidak ditepati di dalam katalog sebuah asisten.

Peringatan bahwa ini adalah antipola ikut dalam deskripsi alat dan dalam setiap hasil. Itu disengaja: itulah yang akhirnya dibacakan asisten kepada orang yang meminta kata sandi.

## Dokumentasi yang dibaca mesin

Selain halaman ini ada deskripsi **OpenAPI 3.1**, dan yang itu memang sudah terbit: [api.password.es/openapi.json](https://api.password.es/openapi.json). Itulah yang dibaca oleh generator klien, editor dengan pelengkapan otomatis, atau agen yang ingin tahu field apa saja yang ada tanpa diberi tahu siapa pun. Ia menjelaskan parameter yang sama dengan tabel di atas, kode galat, dan alasan `quota` kosong.
