Skip to content

Caesar Cipher API

Free JSON endpoints for the Caesar cipher, ROT13 and Vigenère, with no key or sign-up. Pick one and send a real request from here.

advertisement

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
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}'
JavaScript
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!
Python
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
<?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.

FieldMeaning
text
required
The text, up to 10,000 characters.
shift
required
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.
Request
{    "text": "Hello World!",    "shift": 3}
Response
{    "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.

FieldMeaning
text
required
The text, up to 10,000 characters.
shift
required
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.
Request
{    "text": "Khoor Zruog!",    "shift": 3}
Response
{    "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.

FieldMeaning
text
required
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.
Request
{    "text": "Wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj",    "language": "en"}
Response
{    "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.

FieldMeaning
method
required
encrypt, decrypt or solve.
items
required
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.
Request
{    "method": "encrypt",    "items": [        {            "text": "Hello",            "shift": 3        },        {            "text": "World",            "shift": 5        }    ]}
Response
{    "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:

Request
{    "text": "Room 101",    "shift": 3,    "alphabet": "custom",    "custom_alphabet": "abcdefghijklmnopqrstuvwxyz0123456789"}
Response
{    "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.

FieldMeaning
text
required
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.
Request
{    "text": "Hello World!"}
Response
{    "success": true,    "result": "Uryyb Jbeyq!",    "method": "rot13",    "text_length": 12}

POST /rot13/bulk

Applies ROT13 to up to 100 texts in one request.

FieldMeaning
items
required
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.
Request
{    "items": [        "Hello",        "World"    ]}
Response
{    "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.

FieldMeaning
text
required
The text, up to 10,000 characters.
key
required
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.
Request
{    "text": "Hello World!",    "key": "KEY"}
Response
{    "success": true,    "result": "Rijvs Uyvjn!",    "method": "encrypt",    "key_length": 3,    "text_length": 12}

POST /vigenere/decrypt

Reverses the encryption with the same key.

FieldMeaning
text
required
The text, up to 10,000 characters.
key
required
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.
Request
{    "text": "Rijvs Uyvjn!",    "key": "KEY"}
Response
{    "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.

FieldMeaning
text
required
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.
Request
{    "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"}
Response
{    "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.

FieldMeaning
method
required
encrypt or decrypt.
items
required
Up to 100 objects, each with text (up to 1,000 characters) and key.
Request
{    "method": "encrypt",    "items": [        {            "text": "Hello",            "key": "KEY"        },        {            "text": "World",            "key": "LEMON"        }    ]}
Response
{    "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.

StatusMeaning
200The request worked.
400The 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.
422A field is missing or invalid.
429Too many requests. Wait the number of seconds given in Retry-After.
422
{    "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.