Skip to content
You're previewing the new Puzzel.org Back to the current site
Developer API

Build activities from your own system

One POST per activity type. Send your content as JSON, get back an activity in your Puzzel.org account and a URL you can hand to players or drop into an iframe.

Base URL
https://puzzel.org/api/public/v1
Auth
Key + email in the body
Endpoints
20 activity types
Quota
10 activities a day

Your first request

Nothing to install and no handshake: post a JSON body with your key, your email and your content. The response carries the new activity's key and the URL it plays at.

POST crossword
curl -X POST https://puzzel.org/api/public/v1/crossword \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Crossword",
  "language": "en",
  "items": [
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    },
    {
      "answer": "CHERRY",
      "description": "A small red stone fruit",
      "type": "text"
    },
    {
      "answer": "MELON",
      "description": "Big, green outside, sweet inside",
      "type": "text"
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/crossword/embed?p=-Nq8sample_activity_key",
  "message": "Crossword created successfully"
}

Every example on this page is a complete, runnable request. Swap in your own key and content and it works as-is.

Authentication

There are no headers and no bearer token. Both credentials travel in the JSON body of every request, and the key is only accepted for the account that email belongs to.

FieldTypeWhat it does
account_api_key
required
string
stringYour account's API key. It goes in the body, not in a header.
email
required
string
stringThe address your Puzzel.org account signs in with. The key is only valid together with it.

Your key sits on the account section of your dashboard, behind Show.

Sign in

API keys are handed out when a subscription starts, so a free account does not have one yet.

See the plans

Treat the key like a password. It creates and overwrites activities in your account, so keep it server-side and out of anything a browser can read.

The request body

Every endpoint takes the same five fields. What differs is the content field underneath them: most take an array of items, a few take one sentence or one image, and sudoku takes nothing at all.

FieldTypeWhat it does
account_api_key
required
string
stringYour account's API key. It goes in the body, not in a header.
email
required
string
stringThe address your Puzzel.org account signs in with. The key is only valid together with it.
title
optional
string
stringThe name the activity gets in your dashboard. Leave it out and the endpoint uses its own fallback name.
language
optional
string
stringOnly decides the locale in the URL you get back — it does not translate anything you send. Word search also reads it to switch its filler letters to Arabic when it is "ar".
Default: "en"
activity_key
optional
string
stringLeave it out to create a new activity. Pass the key of one you already own and that activity is rebuilt instead.

settings is an object of per-endpoint options. Which ones an endpoint reads is listed with it below; anything else you put there is ignored.

What comes back

A successful call answers 200 with the new activity's key and the URL it plays at. Anything else answers with success set to false and a single error string.

Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/crossword/embed?p=-Nq8sample_activity_key",
  "message": "Crossword created successfully"
}
Failure
{
  "success": false,
  "error": "Invalid Email or API Key"
}

The url you get back is the embed view. Swap embed for play to open it full-page, or for build to open it in the builder — the key after p= stays the same.

Creating vs. updating

Send activity_key and the activity behind it is rebuilt in place: its content is replaced, its name and version stamp are refreshed, and the key itself stays the same — so links and embeds you already shared keep working. Results, folder placement and every setting the endpoint does not write itself are left as they were.

activity_key
{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "activity_key": "-Nq8sample_activity_key",
  "title": "Fruit crossword, week 2",
  "items": [
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    },
    {
      "answer": "CHERRY",
      "description": "A small red stone fruit",
      "type": "text"
    },
    {
      "answer": "MELON",
      "description": "Big, green outside, sweet inside",
      "type": "text"
    }
  ]
}
  • title is applied on every update, its default included — leave it out and the activity is renamed to that endpoint's fallback name.
  • The setting blocks an endpoint writes itself are rewritten from scratch, so an update also resets those to the values you send, or to the endpoint's defaults.
  • You can only update activities your own account owns. Someone else's key answers 403.
  • An update costs the same as a create: one call off today's quota.

Rate limit

10
10 activities per account per day

Every successful call counts, creates and updates alike. Go over and the next request answers 429 until the counter is cleared.

The counter is wiped once a day by a scheduled job, not on a rolling 24-hour window.

Errors

Errors always arrive as JSON with the same two fields, never as an HTML page. The error string is written to be read by a person — it names the field or the limit that failed.

StatusWhat it means
400
Bad Request
Something in the body is missing, malformed or out of range. The message names the field.
401
Unauthorized
The email is unknown, or the key does not belong to that account.
403
Forbidden
The activity_key you sent belongs to a different account.
429
Too Many Requests
Today's quota is used up. It clears once a day.
500
Server Error
The generator could not build a puzzle from what you sent — usually too few words, or words that cannot be fitted together.

Endpoints

One path per activity type, all POST, all under the same base URL. Each one lists the content it needs, the settings it reads and a request you can run.

Words & letters

Crossword puzzle

Interlocks your answers into a grid and numbers the clues for you.

#
POST /api/public/v1/crossword At least 2 in items
Content

An array of words. Each entry pairs the answer with the clue that points at it.

Falls back to the name “Crossword API”

Worth knowing
  • Answers shorter than two characters are dropped before the grid is built, and at least two have to survive that.
  • Answers are upper-cased and the generator gets twenty attempts to fit them. If it cannot place a single word the call answers 500.
Example request
POST crossword
curl -X POST https://puzzel.org/api/public/v1/crossword \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Crossword",
  "language": "en",
  "items": [
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    },
    {
      "answer": "CHERRY",
      "description": "A small red stone fruit",
      "type": "text"
    },
    {
      "answer": "MELON",
      "description": "Big, green outside, sweet inside",
      "type": "text"
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/crossword/embed?p=-Nq8sample_activity_key",
  "message": "Crossword created successfully"
}

Word search

Hides your words in a letter grid, in the directions and the shape you choose.

#
POST /api/public/v1/wordseeker At least 2 in items
Content

An array of words. The clue text becomes the word list players work from.

Falls back to the name “Wordseeker API”

Worth knowing
  • Answers under two characters are dropped, and every answer is upper-cased before it goes into the grid.
  • The grid is padded with Latin letters unless language is "ar", which switches the filler to Arabic.
Settings it reads
FieldTypeWhat it does
hidden_solution
optional in settings
string
stringThe leftover letters spell this out. Setting it also tells the generator to fit the solution first rather than pack in as many words as it can.
directions
optional in settings
string[]
string[]Which ways a word may run. Leave it out and words run east, south-east and south only.
One of westeastnorthsouthnorthwestnortheastsouthwestsoutheast
Default: ["east", "southeast", "south"]
template
optional in settings
string
stringCuts the grid into a shape instead of leaving it square.
One of squarecirclecrossdiamondpyramidsmileystarcross_plus
Example request
POST wordseeker
curl -X POST https://puzzel.org/api/public/v1/wordseeker \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Wordseeker",
  "language": "en",
  "items": [
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    },
    {
      "answer": "CHERRY",
      "description": "A small red stone fruit",
      "type": "text"
    },
    {
      "answer": "MELON",
      "description": "Big, green outside, sweet inside",
      "type": "text"
    }
  ],
  "settings": {
    "hidden_solution": "FRUIT",
    "directions": [
      "east",
      "south",
      "southeast"
    ],
    "template": "square"
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/wordseeker/embed?p=-Nq8sample_activity_key",
  "message": "Wordseeker created successfully"
}

Acrostic

Stacks your answers so one column spells a hidden word.

#
POST /api/public/v1/acrostic At least 1 in items
Content

An array of words. Between them they have to supply every letter of the hidden word.

Falls back to the name “Acrostic API”

Worth knowing
  • If the answers cannot supply the letters the solution needs, the call answers 500 rather than saving a half-built grid.
  • The generator reorders your answers to make the column work, so the order you send is not the order players see.
Settings it reads
FieldTypeWhat it does
hidden_solution
required in settings
string
stringThe word the highlighted column spells out. This endpoint will not run without it.
Example request
POST acrostic
curl -X POST https://puzzel.org/api/public/v1/acrostic \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Acrostic",
  "language": "en",
  "items": [
    {
      "answer": "PEACH",
      "description": "Fuzzy skin, sweet flesh",
      "type": "text"
    },
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    },
    {
      "answer": "CHERRY",
      "description": "A small red stone fruit",
      "type": "text"
    },
    {
      "answer": "MELON",
      "description": "Big, green outside, sweet inside",
      "type": "text"
    }
  ],
  "settings": {
    "hidden_solution": "PLUM"
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/acrostic/embed?p=-Nq8sample_activity_key",
  "message": "Acrostic created successfully"
}

Word scramble

api_e_word_scramble

#
POST /api/public/v1/word-scramble At least 1 in items
Content

api_c_word_scramble

Falls back to the name “Word Scramble API”

Worth knowing
  • Activities made through the API always have the shuffle-the-order setting on, so the order you send is not the order players get.
Settings it reads
FieldTypeWhat it does
hidden_solution
optional in settings
string
stringAn optional bonus word players enter once the rest is solved.
Example request
POST word-scramble
curl -X POST https://puzzel.org/api/public/v1/word-scramble \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Word Scramble",
  "language": "en",
  "items": [
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    },
    {
      "answer": "CHERRY",
      "description": "A small red stone fruit",
      "type": "text"
    },
    {
      "answer": "MELON",
      "description": "Big, green outside, sweet inside",
      "type": "text"
    }
  ],
  "settings": {
    "hidden_solution": "FRUIT"
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/word-scramble/embed?p=-Nq8sample_activity_key",
  "message": "Word Scramble created successfully"
}

Hangman

Turns your words or phrases into guess-the-letter rounds.

#
POST /api/public/v1/hangman At least 1 in items
Content

An array of words or short phrases. The clue is the hint players see.

Falls back to the name “Hangman API”

Example request
POST hangman
curl -X POST https://puzzel.org/api/public/v1/hangman \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Hangman",
  "language": "en",
  "items": [
    {
      "answer": "BANANA",
      "description": "A long yellow fruit",
      "type": "text"
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/hangman/embed?p=-Nq8sample_activity_key",
  "message": "Hangman created successfully"
}

Wordle

Makes a guess-the-word game out of every word you send.

#
POST /api/public/v1/wordle At least 1 in items
Content

An array of words. Players get one round per word.

Falls back to the name “Wordle API”

Worth knowing
  • Made with the check-that-guesses-are-real-words setting on. Switch it off in the builder if your words are names or invented.
Example request
POST wordle
curl -X POST https://puzzel.org/api/public/v1/wordle \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Wordle",
  "language": "en",
  "items": [
    {
      "answer": "MELON",
      "description": "Sweet and green",
      "type": "text"
    },
    {
      "answer": "PEACH",
      "description": "Fuzzy and orange",
      "type": "text"
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/wordle/embed?p=-Nq8sample_activity_key",
  "message": "Wordle created successfully"
}

Typing practice

api_e_typing_practice

#
POST /api/public/v1/typing-practice At least 1 in items
Content

api_c_typing_practice

Falls back to the name “Typing Practice API”

Example request
POST typing-practice
curl -X POST https://puzzel.org/api/public/v1/typing-practice \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Typing Practice",
  "language": "en",
  "items": [
    {
      "answer": "The quick brown fox jumps over the lazy dog",
      "description": "Every letter of the alphabet",
      "type": "text"
    },
    {
      "answer": "Pack my box with five dozen liquor jugs",
      "description": "Another pangram",
      "type": "text"
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/typing-practice/embed?p=-Nq8sample_activity_key",
  "message": "Typing Practice created successfully"
}

Wheel of fortune

api_e_wheel_of_fortune

#
POST /api/public/v1/wheel-of-fortune At least 1 in items
Content

api_c_wheel_of_fortune

Falls back to the name “Wheel of Fortune API”

Worth knowing
  • Made with “show the outcome in the wheel only”, so the result is read off the wheel rather than announced beside it.
Example request
POST wheel-of-fortune
curl -X POST https://puzzel.org/api/public/v1/wheel-of-fortune \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Wheel of Fortune",
  "language": "en",
  "items": [
    {
      "answer": "Read a page aloud",
      "description": "Segment 1",
      "type": "text"
    },
    {
      "answer": "Name three fruits",
      "description": "Segment 2",
      "type": "text"
    },
    {
      "answer": "Spell it backwards",
      "description": "Segment 3",
      "type": "text"
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/wheel-of-fortune/embed?p=-Nq8sample_activity_key",
  "message": "Wheel of Fortune created successfully"
}
Cards & pairs

Memory

Face-down cards to turn over and match in pairs.

#
POST /api/public/v1/memory At least 2 in items
Content

An array of pairs. Each pair holds the two cards that belong together.

Falls back to the name “Memory Game API”

Worth knowing
  • A card is an object with a type and a value. Use "text" for words, or "image", "audio", "youtube" or "link" with a URL in value, and add alt for a description.
Example request
POST memory
curl -X POST https://puzzel.org/api/public/v1/memory \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Memory Game",
  "language": "en",
  "items": [
    {
      "cards": [
        {
          "type": "text",
          "value": "Apple"
        },
        {
          "type": "text",
          "value": "A red fruit"
        }
      ]
    },
    {
      "cards": [
        {
          "type": "text",
          "value": "Banana"
        },
        {
          "type": "text",
          "value": "A yellow fruit"
        }
      ]
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/memory/embed?p=-Nq8sample_activity_key",
  "message": "Memory game created successfully"
}

Matching pairs

api_e_matching_pairs

#
POST /api/public/v1/matching-pairs At least 2 in items
Content

api_c_matching_pairs

Falls back to the name “Matching Game API”

Worth knowing
  • A card is an object with a type and a value. Use "text" for words, or "image", "audio", "youtube" or "link" with a URL in value, and add alt for a description.
Example request
POST matching-pairs
curl -X POST https://puzzel.org/api/public/v1/matching-pairs \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Matching Game",
  "language": "en",
  "items": [
    {
      "cards": [
        {
          "type": "text",
          "value": "Apple"
        },
        {
          "type": "text",
          "value": "A red fruit"
        }
      ]
    },
    {
      "cards": [
        {
          "type": "text",
          "value": "Banana"
        },
        {
          "type": "text",
          "value": "A yellow fruit"
        }
      ]
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/matching-pairs/embed?p=-Nq8sample_activity_key",
  "message": "Matching pairs game created successfully"
}

Flash cards

api_e_flash_cards

#
POST /api/public/v1/flash-cards At least 1 in items
Content

api_c_flash_cards

Falls back to the name “Flash Cards API”

Worth knowing
  • The endpoint stores as many cards as you send, so send exactly two per entry — front, then back.
  • A card is an object with a type and a value. Use "text" for words, or "image", "audio", "youtube" or "link" with a URL in value, and add alt for a description.
Example request
POST flash-cards
curl -X POST https://puzzel.org/api/public/v1/flash-cards \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Flash Cards",
  "language": "en",
  "items": [
    {
      "cards": [
        {
          "type": "text",
          "value": "Apple"
        },
        {
          "type": "text",
          "value": "A red fruit"
        }
      ]
    },
    {
      "cards": [
        {
          "type": "text",
          "value": "Banana"
        },
        {
          "type": "text",
          "value": "A yellow fruit"
        }
      ]
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/flash-cards/embed?p=-Nq8sample_activity_key",
  "message": "Flash Cards created successfully"
}

Categorize

Cards to sort into the bucket they belong in.

#
POST /api/public/v1/categorize At least 2 in items
Content

An array of categories, each with a name and the cards that belong in it.

Falls back to the name “Categorize Game API”

Worth knowing
  • A category sent without a name is saved as “Untitled Category”, so always send one.
  • A card is an object with a type and a value. Use "text" for words, or "image", "audio", "youtube" or "link" with a URL in value, and add alt for a description.
Example request
POST categorize
curl -X POST https://puzzel.org/api/public/v1/categorize \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Categorize Game",
  "language": "en",
  "items": [
    {
      "name": "Red fruits",
      "cards": [
        {
          "type": "text",
          "value": "Strawberry"
        },
        {
          "type": "text",
          "value": "Cherry"
        }
      ]
    },
    {
      "name": "Yellow fruits",
      "cards": [
        {
          "type": "text",
          "value": "Banana"
        },
        {
          "type": "text",
          "value": "Lemon"
        }
      ]
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/categorize/embed?p=-Nq8sample_activity_key",
  "message": "Categorize game created successfully"
}

Reorder

A sequence players have to put back in order.

#
POST /api/public/v1/reorder At least 1 in items
Content

An array of sequences. Each holds its cards in the correct order.

Falls back to the name “Reorder Game API”

Worth knowing
  • The order you send is stored as the correct order — number one first.
  • A card is an object with a type and a value. Use "text" for words, or "image", "audio", "youtube" or "link" with a URL in value, and add alt for a description.
Example request
POST reorder
curl -X POST https://puzzel.org/api/public/v1/reorder \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Reorder Game",
  "language": "en",
  "items": [
    {
      "name": "From seed to fruit",
      "cards": [
        {
          "type": "text",
          "value": "Plant the seed"
        },
        {
          "type": "text",
          "value": "Water it"
        },
        {
          "type": "text",
          "value": "Watch it grow"
        },
        {
          "type": "text",
          "value": "Pick the fruit"
        }
      ]
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/reorder/embed?p=-Nq8sample_activity_key",
  "message": "Reorder game created successfully"
}
Questions & answers

Quiz

Multiple-choice and open questions, scored as players go.

#
POST /api/public/v1/quiz At least 1 in items
Content

An array of questions. Multiple-choice questions carry their answers; open questions carry the answer you accept.

Falls back to the name “Quiz API”

Worth knowing
  • question_type is either "multiple_choice", where the right option carries isCorrect true, or "open_answer", which uses correct_answer instead. Left out, it is treated as multiple choice.
  • The quiz endpoint passes settings straight through as activity setting blocks, so it is not a place for loose options — adjust the quiz in the builder afterwards.
Example request
POST quiz
curl -X POST https://puzzel.org/api/public/v1/quiz \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Quiz",
  "language": "en",
  "items": [
    {
      "question_type": "multiple_choice",
      "description": "Which fruit is yellow?",
      "answers": [
        {
          "type": "text",
          "description": "Banana",
          "isCorrect": true
        },
        {
          "type": "text",
          "description": "Cherry",
          "isCorrect": false
        }
      ]
    },
    {
      "question_type": "open_answer",
      "description": "What colour is a lemon?",
      "correct_answer": "Yellow",
      "explanation": "Lemons ripen from green to yellow."
    }
  ]
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/quiz/embed?p=-Nq8sample_activity_key",
  "message": "Quiz created successfully"
}

Board game

api_e_board_game

#
POST /api/public/v1/board-game At least 1 in items
Content

api_c_board_game

Falls back to the name “Board Game API”

Worth knowing
  • question_type is either "multiple_choice", where the right option carries isCorrect true, or "open_answer", which uses correct_answer instead. Left out, it is treated as multiple choice.
Settings it reads
FieldTypeWhat it does
number_of_tiles
optional in settings
number
numberHow many tiles the board has. Between 10 and 75.
Default: 30
game_mode
optional in settings
string
stringWhether players race to the finish or collect items along the way.
One of race_to_finishcollect_items
Default: "race_to_finish"
Example request
POST board-game
curl -X POST https://puzzel.org/api/public/v1/board-game \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Board Game",
  "language": "en",
  "items": [
    {
      "question_type": "multiple_choice",
      "description": "Which fruit is yellow?",
      "answers": [
        {
          "type": "text",
          "description": "Banana",
          "isCorrect": true
        },
        {
          "type": "text",
          "description": "Cherry",
          "isCorrect": false
        }
      ]
    },
    {
      "question_type": "open_answer",
      "description": "What colour is a lemon?",
      "correct_answer": "Yellow",
      "explanation": "Lemons ripen from green to yellow."
    }
  ],
  "settings": {
    "number_of_tiles": 30,
    "game_mode": "race_to_finish"
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/board-game/embed?p=-Nq8sample_activity_key",
  "message": "Board Game created successfully"
}
Sentences & numbers

Cryptogram

Turns a sentence into a code to crack, one character at a time.

#
POST /api/public/v1/cryptogram Takes no items
Content

One sentence, in the sentence field. This endpoint takes no items.

Falls back to the name “Cryptogram API”

Worth knowing
  • Anything you send in items is ignored — the puzzle is built from the sentence alone.
Settings it reads
FieldTypeWhat it does
sentence
required
string
stringThe sentence to encrypt. Players decode it character by character.
helpers
optional in settings
string
stringWhich characters are given away for free as a way in: none, the most common ones, the vowels, or the ones you list yourself.
One of nonemost_commonvowelscustom
Default: "none"
character_list
optional in settings
string
stringThe alphabet the cipher is built from. Left empty, the encryption picks its own.
extra_letters
optional in settings
string
stringThe characters given away when helpers is "custom". Ignored for the other helper modes.
hide_unused_characters
optional in settings
boolean
booleanLeaves characters the sentence never uses out of the key.
Default: false
Example request
POST cryptogram
curl -X POST https://puzzel.org/api/public/v1/cryptogram \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Cryptogram",
  "language": "en",
  "sentence": "An apple a day keeps the doctor away",
  "settings": {
    "helpers": "vowels",
    "hide_unused_characters": false
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/cryptogram/embed?p=-Nq8sample_activity_key",
  "message": "Cryptogram created successfully"
}

Calculation

Hides a sentence behind sums — solve the sum, reveal the letter.

#
POST /api/public/v1/calculation Takes no items
Content

One sentence, in the sentence field. This endpoint takes no items.

Falls back to the name “Calculation Game API”

Worth knowing
  • If the constraints are too tight to encode the sentence, the call answers 400 asking you to loosen them rather than saving a partial puzzle.
Settings it reads
FieldTypeWhat it does
sentence
required
string
stringThe sentence players uncover by solving the sums.
difficulty_level
optional in settings
number
numberThe highest answer a sum is allowed to have.
One of 20501001000
Default: "100"
operators
optional in settings
string[]
string[]Which operations may appear. x is multiply, : is divide.
One of +-x:
Default: ["+", "-", "x", ":"]
max_operations
optional in settings
number
numberHow many operations one sum may chain together.
One of 123
Default: 1
number_difficulty
optional in settings
number
numberCaps the individual numbers inside a sum. Anywhere from 5 to 1000.
Default: 100
Example request
POST calculation
curl -X POST https://puzzel.org/api/public/v1/calculation \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Calculation Game",
  "language": "en",
  "sentence": "Fruit salad for everyone",
  "settings": {
    "difficulty_level": "100",
    "operators": [
      "+",
      "-",
      "x",
      ":"
    ],
    "max_operations": 1,
    "number_difficulty": 100
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/calculation/embed?p=-Nq8sample_activity_key",
  "message": "Calculation game created successfully"
}

Sudoku

Generates a solved grid, then takes numbers back out.

#
POST /api/public/v1/sudoku Takes no items
Content

Nothing. The whole puzzle comes out of its two settings.

Falls back to the name “Sudoku API”

Worth knowing
  • Send no items and no sentence — size and difficulty are the entire input.
  • The builder only offers the difficulty for 2x3, 3x3 and 3x4. The API applies it to every size, 2x2 and 4x4 included.
Settings it reads
FieldTypeWhat it does
size
optional in settings
string
stringThe size of one block, written as rows by columns — 3x3 gives the classic 9x9 grid. The endpoint only checks that it parses as two numbers, so stay with the sizes the builder offers.
One of 2x22x33x33x44x4
Default: "3x3"
difficulty_level
optional in settings
string
stringHow many numbers are left on the board to start from.
One of easynormalhard
Default: "normal"
Example request
POST sudoku
curl -X POST https://puzzel.org/api/public/v1/sudoku \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Sudoku",
  "language": "en",
  "settings": {
    "size": "3x3",
    "difficulty_level": "normal"
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/sudoku/embed?p=-Nq8sample_activity_key",
  "message": "Sudoku created successfully"
}
Pictures

Jigsaw puzzle

Cuts a picture into pieces to drag back together.

#
POST /api/public/v1/jigsaw Takes no items
Content

One image URL, in the image field. This endpoint takes no items.

Falls back to the name “Jigsaw Game API”

Worth knowing
  • The API always makes a 4 by 4 jigsaw. Piece count, irregular pieces and flat edges are builder settings — sending rows or columns here does nothing.
  • The URL is stored as you sent it and the file is never copied, so it has to stay publicly reachable for as long as the activity is played.
Settings it reads
FieldTypeWhat it does
image
required
string
stringAbsolute URL of the picture to cut up. Sent at the top level, not inside settings.
Example request
POST jigsaw
curl -X POST https://puzzel.org/api/public/v1/jigsaw \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Jigsaw Game",
  "language": "en",
  "image": "https://example.com/orchard.jpg"
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/jigsaw/embed?p=-Nq8sample_activity_key",
  "message": "Jigsaw game created successfully"
}

Sliding puzzle

Scrambles a picture into tiles that slide into place.

#
POST /api/public/v1/slidingpuzzle Takes no items
Content

One image URL, inside settings. This endpoint takes no items.

Falls back to the name “Sliding Puzzle API”

Worth knowing
  • Unlike the jigsaw, this endpoint reads its picture from settings.image. A top-level image field is ignored and the call answers 400.
  • The URL is stored as you sent it and the file is never copied, so it has to stay publicly reachable for as long as the activity is played.
Settings it reads
FieldTypeWhat it does
image
required in settings
string
stringAbsolute URL of the picture to scramble. Unlike the jigsaw's, this one lives inside settings.
Example request
POST slidingpuzzle
curl -X POST https://puzzel.org/api/public/v1/slidingpuzzle \
  -H "Content-Type: application/json" \
  -d '{
  "account_api_key": "YOUR_API_KEY",
  "email": "you@example.com",
  "title": "Sliding Puzzle",
  "language": "en",
  "settings": {
    "image": "https://example.com/orchard.jpg"
  }
}'
Success
{
  "success": true,
  "id": "-Nq8sample_activity_key",
  "url": "https://puzzel.org/en/slidingpuzzle/embed?p=-Nq8sample_activity_key",
  "message": "Sliding puzzle created successfully"
}

Something not behaving?

Send the request you tried and the error you got back and you'll get a real answer, from the person who wrote the endpoint.

Email support