Getting started
You don’t need a key or an account. Every operation is a POST request with a JSON body, sent to an address that starts with:
https://caesar-cipher.com/api/v1 Send both Content-Type: application/json and Accept: application/json. Without the second header, a validation error redirects you and doesn’t return JSON. The Python example needs the requests package.
curl -X POST https://caesar-cipher.com/api/v1/caesar/encrypt \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"text": "Hello World!", "shift": 3}'const response = await fetch("https://caesar-cipher.com/api/v1/caesar/encrypt", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ text: "Hello World!", shift: 3 }),}); const data = await response.json();console.log(data.result);// Khoor Zruog!import requests response = requests.post( "https://caesar-cipher.com/api/v1/caesar/encrypt", json={"text": "Hello World!", "shift": 3}, headers={"Accept": "application/json"},)print(response.json()["result"])# Khoor Zruog!<?php $context = stream_context_create(['http' => [ 'method' => 'POST', 'header' => "Content-Type: application/json\r\nAccept: application/json\r\n", 'content' => json_encode(['text' => 'Hello World!', 'shift' => 3]),]]); $response = file_get_contents('https://caesar-cipher.com/api/v1/caesar/encrypt', false, $context);echo json_decode($response, true)['result'], "\n";// Khoor Zruog!Caesar cipher
Encrypt, decrypt or solve a Caesar cipher. To see how the cipher itself works, try the Caesar cipher tool.
POST /caesar/encrypt
Shifts each letter forward.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
shiftrequired | A whole number from -25 to 25. |
alphabet | basic (default), polish, german, spanish, french or custom. |
custom_alphabet | Your own characters, up to 100. Required when alphabet is custom. |
preserve_case | Keep lower case. Default true; with false the result is in capitals. |
preserve_non_alpha | Keep characters outside the alphabet. Default true; with false they are removed. |
{ "text": "Hello World!", "shift": 3}{ "success": true, "result": "Khoor Zruog!", "method": "encrypt", "shift": 3, "alphabet": "basic", "text_length": 12}POST /caesar/decrypt
Shifts each letter back. Pass the same shift that was used to encrypt.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
shiftrequired | A whole number from -25 to 25. |
alphabet | basic (default), polish, german, spanish, french or custom. |
custom_alphabet | Your own characters, up to 100. Required when alphabet is custom. |
preserve_case | Keep lower case. Default true; with false the result is in capitals. |
preserve_non_alpha | Keep characters outside the alphabet. Default true; with false they are removed. |
{ "text": "Khoor Zruog!", "shift": 3}{ "success": true, "result": "Hello World!", "method": "decrypt", "shift": 3, "alphabet": "basic", "text_length": 12}POST /caesar/solve
Tries every shift and scores the results by letter frequency, with no key needed. The text comes back in capitals. confidence is a score and not a probability, and short texts can fool it, so also look at all_solutions, which holds the five best results.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
alphabet | As above, but without custom. |
language | Whose letter frequencies to score with: en (default), pl, de, es or fr. |
{ "text": "Wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj", "language": "en"}{ "success": true, "best_solution": { "shift": 3, "text": "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG", "confidence": 96 }, "all_solutions": [ { "shift": 3, "text": "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG", "score": 95.84 }, { "shift": 13, "text": "JXU GKYSA RHEMD VEN ZKCFI ELUH JXU BQPO TEW", "score": 95.69 }, { "shift": 14, "text": "IWT FJXRZ QGDLC UDM YJBEH DKTG IWT APON SDV", "score": 95.69 }, { "shift": 19, "text": "DRO AESMU LBYGX PYH TEWZC YFOB DRO VKJI NYQ", "score": 95.26 }, { "shift": 6, "text": "QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD", "score": 95.12 } ], "alphabet": "basic", "language": "en"}POST /caesar/bulk
Processes up to 100 texts in one request. With solve, the scoring always uses English letter frequencies.
| Field | Meaning |
|---|---|
methodrequired | encrypt, decrypt or solve. |
itemsrequired | Up to 100 objects, each with text (up to 1,000 characters) and shift (default 3). |
alphabet | basic (default), polish, german, spanish, french or custom. |
custom_alphabet | Your own characters, up to 100. Required when alphabet is custom. |
{ "method": "encrypt", "items": [ { "text": "Hello", "shift": 3 }, { "text": "World", "shift": 5 } ]}{ "success": true, "method": "encrypt", "alphabet": "basic", "count": 2, "results": [ { "index": 0, "original": "Hello", "result": "Khoor", "shift": 3 }, { "index": 1, "original": "World", "result": "Btwqi", "shift": 5 } ]}Other alphabets
The named alphabets match our Caesar cipher tool, so results agree with it. french has the 26 basic letters, and accented letters stay unchanged. For anything else, use custom. This example shifts digits too:
{ "text": "Room 101", "shift": 3, "alphabet": "custom", "custom_alphabet": "abcdefghijklmnopqrstuvwxyz0123456789"}{ "success": true, "result": "Urrp 434", "method": "encrypt", "shift": 3, "alphabet": "custom", "text_length": 8}ROT13
ROT13 needs no key, and the same call both encrypts and decrypts. Only the letters A to Z change.
POST /rot13/transform
Applies ROT13 to one text.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
preserve_case | Keep lower case. Default true; with false the result is in capitals. |
preserve_non_alpha | Keep characters outside the alphabet. Default true; with false they are removed. |
{ "text": "Hello World!"}{ "success": true, "result": "Uryyb Jbeyq!", "method": "rot13", "text_length": 12}POST /rot13/bulk
Applies ROT13 to up to 100 texts in one request.
| Field | Meaning |
|---|---|
itemsrequired | Up to 100 texts of up to 1,000 characters. |
preserve_case | Keep lower case. Default true; with false the result is in capitals. |
preserve_non_alpha | Keep characters outside the alphabet. Default true; with false they are removed. |
{ "items": [ "Hello", "World" ]}{ "success": true, "method": "rot13", "count": 2, "results": [ { "index": 0, "original": "Hello", "result": "Uryyb" }, { "index": 1, "original": "World", "result": "Jbeyq" } ]}Vigenère cipher
The key may contain only the letters A to Z. Letters from other alphabets stay as they are and don’t use up a key letter. You can also watch the cipher work in the Vigenère tool.
POST /vigenere/encrypt
Shifts each letter by the next letter of the key.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
keyrequired | The keyword, up to 100 letters from A to Z. |
preserve_case | Keep lower case. Default true; with false the result is in capitals. |
preserve_non_alpha | Keep characters outside the alphabet. Default true; with false they are removed. |
{ "text": "Hello World!", "key": "KEY"}{ "success": true, "result": "Rijvs Uyvjn!", "method": "encrypt", "key_length": 3, "text_length": 12}POST /vigenere/decrypt
Reverses the encryption with the same key.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
keyrequired | The keyword, up to 100 letters from A to Z. |
preserve_case | Keep lower case. Default true; with false the result is in capitals. |
preserve_non_alpha | Keep characters outside the alphabet. Default true; with false they are removed. |
{ "text": "Rijvs Uyvjn!", "key": "KEY"}{ "success": true, "result": "Hello World!", "method": "decrypt", "key_length": 3, "text_length": 12}POST /vigenere/analyze
Finds the key from the letter statistics of the text, which needs at least 20 letters. Long texts work best: in our tests on English, Polish, German, Spanish and French, the key came back correct in 96 to 100 percent of attempts at 400 characters, and in only 8 to 58 percent at 80. So choose the right language, and check decrypted_preview to see whether the result reads as real text.
| Field | Meaning |
|---|---|
textrequired | The text, up to 10,000 characters. |
max_key_length | The longest key to look for, from 1 to 20. Default 10. |
language | Whose letter frequencies to score with: en (default), pl, de, es or fr. |
{ "text": "Tx iof l fdwtsx ocyo qafatrs kupr fvr zpp hrlgtse hexyro mzhb elq qylwefbzq mbq hvahr l wubtwi xwap sz hup faoeo. Rapboc wbrh atog tx ysnyx, nsplyes rgidm ypxfse sep prpr yciph mzbyk fvr lpbvnmif pl l rgaopv ts epjggro xa hrwp fvrx. Lq ofvip hup wfiqprfg gz pacx qsd dnexqfad, xa qbfrf hup pqhgpve, oao xa hutrw oozyf kutgt kbche ocaimf zzwf cseiz wa zvpwalvk ketxubt.", "language": "en"}{ "success": true, "analysis": { "probable_key_lengths": [ 5, 2, 10 ], "best_key_length": 5, "ioc_scores": { "10": 0.0739, "5": 0.0724, "6": 0.0464, "7": 0.0462, "9": 0.0447 }, "probable_key": "LEMON", "decrypted_preview": "It was a bright cold morning when the old teacher walked into the classroom and wrote a single line " }, "language": "en", "text_length": 295}POST /vigenere/bulk
Encrypts or decrypts up to 100 texts in one request, each with its own key.
| Field | Meaning |
|---|---|
methodrequired | encrypt or decrypt. |
itemsrequired | Up to 100 objects, each with text (up to 1,000 characters) and key. |
{ "method": "encrypt", "items": [ { "text": "Hello", "key": "KEY" }, { "text": "World", "key": "LEMON" } ]}{ "success": true, "method": "encrypt", "count": 2, "results": [ { "index": 0, "original": "Hello", "result": "Rijvs", "key": "KEY" }, { "index": 1, "original": "World", "result": "Hsdzq", "key": "LEMON" } ]}Errors
The HTTP status tells you what happened. A validation error also lists each field that failed.
| Status | Meaning |
|---|---|
200 | The request worked. |
400 | The input passed validation but can’t be used, such as a custom alphabet with fewer than 2 characters or a text too short to analyze. |
422 | A field is missing or invalid. |
429 | Too many requests. Wait the number of seconds given in Retry-After. |
{ "message": "The text field is required.", "errors": { "text": [ "The text field is required." ] }}Rate limits
Each IP address can make 60 requests per minute, and requests sent from this page count too. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. Once you pass the limit, you get status 429 with Retry-After and X-RateLimit-Reset.
The API accepts requests from any website, so you can call it directly from browser code. If you need a higher limit, write to us.
Frequently asked questions
Do I need an API key?
No. The API is free and needs no key or account. Only the limit of 60 requests per minute applies.
Can I use this to protect real data?
No. These ciphers are for learning and puzzles, and they break in seconds. Your text is also sent to our server to be processed, so don’t send anything private.
Should I use the API or the library?
The API works from any language and covers ROT13 and Vigenère as well. In JavaScript and TypeScript, the caesar-cipher-js library runs the Caesar cipher locally, with no requests or limits. To write the code yourself, follow the Python or JavaScript tutorial.