Password hash - bcrypt

Free bcrypt Hash API Endpoint

The free bcrypt hash API endpoint takes a password of at most 72 bytes and hands back a bcrypt string: the $2b$ prefix, the cost, a fresh 16 byte salt and the hash, 60 characters in all. bcrypt has been hashing passwords since 1999 and is in every language's standard toolbox; it is the right choice when a system already stores bcrypt, and this endpoint produces strings those systems verify. Added 3 October 2026, computed in a process of its own.

  • No API key
  • 60 characters, $2b$12$
  • At most 72 bytes
  • 200 calls per IP per day

Hash a test password

POST/bcrypt_hash

https://aisenseapi.com/services/v1/bcrypt_hash

Call the free bcrypt hash API endpoint

curl -X POST https://aisenseapi.com/services/v1/bcrypt_hash \
  -H "Content-Type: application/json" \
  -d '{"password":"correct horse battery staple"}'
{"bcrypt_hash":"$2b$12$gn6ItEhVTwbuboZRi6NOZ.CDyi0awJjCpEvbnwwRP7kwJAJXJ4T5q"}

Call it again with the same password and you get a different string: the salt is fresh every time, and that is the point of a password hash. Both strings verify. The field may also be called data, like the rest of the hash family, and a text/plain body works too. There is no file upload here, because a file is not a password.

Use test data. The string is kept by nobody here, but the password travels to a public service over TLS, and a real password belongs to the application that uses it. These routes exist to test, compare and generate fixtures.

Response fields

FieldTypeDescription
bcrypt_hashstringThe self-describing hash string: algorithm, cost, salt and hash. An empty password is refused with HTTP 400 and a fix; one over 1024 bytes with 413.

The cost is fixed at 12, which means 2^12 = 4096 rounds of the key setup; each step up doubles the work. On the API box one call takes about 190 ms of one core. bcrypt reads at most 72 bytes of the password and stops at a NUL byte, so this endpoint refuses longer input and input containing NUL with 400 rather than silently hashing part of it, which is what many libraries do.

Verify a password

POST /password_verify takes password and the hash string. The algorithm is read from the string, so no field has to name it, and the answer carries the parameters that were read. A mismatch is a result, {"match":false}, not an error.

curl -X POST https://aisenseapi.com/services/v1/password_verify \
  -H "Content-Type: application/json" \
  -d '{"password":"correct horse battery staple","hash":"$2b$12$gn6ItEhVTwbuboZRi6NOZ.CDyi0awJjCpEvbnwwRP7kwJAJXJ4T5q"}'
{"match":true,"algorithm":"bcrypt","params":{"cost":12}}

bcrypt strings with the $2a$, $2b$, $2x$ and $2y$ prefixes and cost 4 to 12 are verified, so a $2y$ string made by PHP works; a cost above 12 is refused with 400 and a fix, so nobody can make a verification cost more than a hash does. A hex digest sent here is refused with a pointer to /hash_verify, which is where digests are checked.

Cost, budget and the 503 you may see

One call is 100 to 230 ms of CPU on the server, 250 to 580 times a SHA-256. That is by design, and it is why these routes have a budget of their own beside the 5000 calls per day every address has: 200 password operations per IP address per day, hashing and verifying together, answered with 429 past that, and 20 000 per day for everyone, answered with 503. Both carry a Retry-After until midnight Oslo time.

The hashing runs in a process of its own, one computation at a time. While that process is busy with another caller the answer is 503 with Retry-After: 1 and "reason":"busy"; if it is down for any reason, 503 with Retry-After: 5 and "reason":"unavailable". Retry after the given seconds. Nothing else in the API is affected either way.

Why bcrypt, and when

bcrypt is not memory-hard: its 4 KiB working set fits in any cache, so graphics cards attack it well enough. OWASP lists it after Argon2id and scrypt for that reason. It is still a sound password hash at cost 12, and it has one thing the newer two lack: three decades of deployments. If your users' passwords are already stored as bcrypt, keep bcrypt and raise the cost when hardware allows; if you are starting fresh, start with Argon2id.

Common uses

Callers reach for the free bcrypt hash API endpoint in a handful of recurring situations.

Verifying old hashes

A $2y$ string from a PHP application or a $2b$ string from Python or Node verifies here with its cost reported, which is a quick way to confirm what a legacy table holds.

Testing a login flow

Generate test strings at cost 12 for a fixture file without installing a library first, and check that your application accepts them.

The 72 byte rule

Send a 73 byte password and get a refusal instead of a truncated hash. Use it to find out whether your own library truncates silently.

Teaching

Show the structure of a bcrypt string, prefix, cost, salt and hash, and that two calls with the same password give two different strings.

Privacy and limits

The password travels in the POST body over TLS, never in a URL, and no part of it is logged or stored: the request log keeps the status and how long the answer took. It still reaches this service in the clear inside that connection, which is why the word above is test data.

The free bcrypt hash API endpoint shares the service-wide ceiling of 5000 requests per IP per day and has the password budget described above. No key, no account and no signup step stand in the way. Every route sits under the base URL https://aisenseapi.com/services/v1, and the whole catalogue is listed on Free public REST APIs.