Puzzle API, files not a serverBratislavaVersion 1
Six thousand logic puzzles, as files.
Ten kinds, three difficulties, two hundred puzzles each. Every one of them generated by the engine that runs our daily games, and checked by our own solver for exactly one solution before it was written to disk.
There is no server behind this. Every endpoint is a file, and fetching one is the same as fetching an image. That is also why there is no key, no sign-up and no rate limit to talk about.
- Kinds10
- Puzzles per kind and difficulty200
- Files in the treeJSON + puzzle SVG + solution SVG
- Checked for exactly one solutionevery one
- Cost to younothing
This is not a picture. It is the embeddable widget, running the same rules as the daily game.
Free to use, with one line of credit.
Use any puzzle from this API on your own site, in your classroom, in your club newsletter or in your app, as long as it is not something you sell and as long as the credit line is next to the puzzle:
Puzzle by ARLing, arling.sk
A link on those words is welcome and not required. The embeddable widget carries the credit line itself, so if you use the widget there is nothing else to do.
Selling is the line. A book, a paid app, a paid newsletter, a printed magazine, an ad-funded puzzle site: those need the commercial licence, which comes with a Puzzle Post Bulletin Pro subscription. Every JSON file repeats both licences in its own licence field, so the terms travel with the file.
What we do not allow under either licence: passing the puzzles off as your own, or republishing the tree itself as a competing download.
Four addresses, and that is all of it.
| Address | What is in it |
|---|---|
/api/puzzles/v1/index.json | The kinds, the difficulties, the counts, the full rules of each kind and the schema notes. |
/api/puzzles/v1/<kind>/<difficulty>/<index>.json | One puzzle. Index runs from 001 to 200. |
/api/puzzles/v1/<kind>/<difficulty>/index.json | The list of ids in that difficulty, with a sha256 for every file. |
/api/puzzles/v1/today/<kind>.json | The puzzle the daily game shows today. Rewritten every night, with an extra date field. |
Next to every <index>.json there are two drawings: <index>.svg is the puzzle and <index>-solution.svg is the answer. They have no width and no height, only a viewBox, so they take the size you give them and print sharply at any of them.
The ten kinds are badgers (Killer Sudoku), hares (Anti-knight Sudoku), squirrels (Kakuro), magpies (Nonograms), hedgehogs (Star Battle), otters (Slitherlink), cranes (Hashi), swans (Masyu), voles (Nurikabe) and herons (Numberlink). The three difficulties are easy, medium and hard.
This is the whole of otters-easy-001.
Nothing is cut out of the example below except line breaks inside the arrays. Open the file itself and compare.
{
"v": 1,
"kind": "otters",
"difficulty": "easy",
"id": "otters-easy-001",
"seed": "api-v1:otters:easy:1:5",
"size": 5,
"rules": "Slitherlink. Full rules: https://arling.sk/games/otters/guide/",
"givens": [0,null,3,null,null,null,null,0,null,3,null,null,null,null,null,0,0,null,null,1,null,null,null,1,0],
"solution": {
"h": [0,0,1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0],
"v": [0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0]
},
"verified": { "uniqueSolution": true, "solverMs": 2 },
"licence": {
"free": "personal and non-commercial use with the credit line Puzzle by ARLing, arling.sk",
"commercial": "Puzzle Post Bulletin Pro subscription",
"url": "https://arling.sk/puzzle-post/bulletin/"
},
"svg": { "puzzle": "001.svg", "solution": "001-solution.svg" }
}
- v
- The schema version. It is 1 and it will stay 1: a change that would break a reader gets a new folder,
v2, andv1stays where it is. - seed
- The exact string the puzzle was generated from. It is there so that the file can be reproduced, not so that you have to use it.
- size
n, the side of the grid. Sizes differ by kind and by difficulty; the index file lists which sizes occur where.- givens
- The clues as one flat array in reading order, for the kinds that have such a field:
hares,squirrels,hedgehogs,otters,swans,volesandherons. - grid
- The clues that are not a flat array:
cagesfor badgers,clueswith row and column runs for magpies,islandsfor cranes,starsfor hedgehogs,rulesfor hares,pairsfor herons. - solution
{ cells }for the grid kinds,{ h, v }for the two loop kinds (otters and swans),{ bridges }for cranes.- verified
uniqueSolutionis true in every file, because a puzzle that failed the check was never written.solverMsis how long that check took on the machine that built the file.- svg
- The names of the two drawings that sit next to the JSON.
curl, fetch, and a picture without any code at all.
curl -s https://arling.sk/api/puzzles/v1/otters/easy/001.json | jq .size curl -s https://arling.sk/api/puzzles/v1/today/badgers.json | jq .date curl -sO https://arling.sk/api/puzzles/v1/otters/easy/001.svg
const r = await fetch('https://arling.sk/api/puzzles/v1/badgers/medium/017.json');
const puzzle = await r.json();
console.log(puzzle.size); // 9
console.log(puzzle.grid.cages.length); // how many dotted cages
console.log(puzzle.solution.cells); // 81 digits, reading order
// the drawing lives next to the JSON
const svg = 'https://arling.sk/api/puzzles/v1/badgers/medium/' + puzzle.svg.puzzle;
If all you want is the picture, you do not need any code:
<img src="https://arling.sk/api/puzzles/v1/swans/hard/042.svg" alt="A Masyu puzzle">
- Read
/api/puzzles/v1/index.jsononce to learn the kinds, the sizes and the counts. - Pick a kind, a difficulty and a number from 1 to 200, padded to three digits.
- Fetch the JSON for the answer and the clues, or the SVG if you only want to print it.
- Put the credit line next to the puzzle.
Build the snippet, watch it run.
The widget draws the board, checks the marks and shows the answer. It sets no cookies, stores nothing in the browser and sends no analytics.
An iframe
Or one line of script, which puts the same iframe in its own place
Both take the same parameters: kind, difficulty and id, or date=today for the daily puzzle, or seed= for one generated in the visitor's own browser.
What the widget tells your page.
When the puzzle appears, and again when somebody finishes it, the iframe posts a message to the page around it. Nothing else ever leaves the frame.
window.addEventListener('message', (e) => {
if (!e.data || e.data.type !== 'arling-puzzle') return;
// e.data.event is 'loaded' or 'solved'
console.log(e.data.event, e.data.id);
});
Last message from the frame above: nothing yet
No limits to quote, and one thing to be sensible about.
These are static files behind a CDN, so there is no quota to run out of and no header that counts your requests. We do not log who you are, because there is nothing here that could.
The one sensible thing: if you need many puzzles, fetch the index once and cache what you take. Files never change once published, so a cache never goes stale. Hot-looping the same file a thousand times a second helps nobody, and it will not get you a different puzzle.
What is not here yet, and how it will arrive. Keyed access, per-key counts and a commercial tier are the next step, and they will come as a separate host so that these files stay exactly as they are. Nothing on this page will start asking for a key later; a key will unlock more, not gate this.
The API is built by ops/puzzle-api/postav.mjs in our repository and checked by the same script with --kontrola, which opens every file, compares it with the sha256 in the index and runs five puzzles per kind through the solver again.
What people ask first.
Do I need an API key?
No. Every endpoint is a static file on this website. There is no key, no account and no rate limit. Keyed access is planned for the commercial tier, and it will not change these addresses.
What does "exactly one solution" mean here?
Our own solver, the one that runs the daily game, found exactly one answer for the puzzle, and that answer matches every clue. The build refuses to write a file that fails either half of that check. It is a program check, not a claim that the puzzle has never appeared anywhere in the world.
Could I get the same puzzle twice, or the same one as in a book?
No puzzle in this API is the same as a puzzle in our daily archive, in one of our books, in a Puzzle Planner pack or in a Puzzle Post issue, and no two records here are the same puzzle. The check is on the puzzle, not on the answer: two different sets of clues can lead to the same finished grid, and for a solver those are two different puzzles.
May I use the puzzles in something I sell?
Not under the free licence. Commercial use comes with a Puzzle Post Bulletin Pro subscription, which also gets you fresh sets every month rather than a fixed two hundred.
Does the embedded puzzle set cookies or count visitors?
No. The widget stores nothing in the browser, sets no cookies and loads no analytics. It fetches its own static files from arling.sk and posts two messages to your page. That is the whole of its behaviour.
Can I generate a puzzle instead of picking one?
Yes, in the browser. /embed/puzzle/?kind=voles&difficulty=hard&seed=anything runs our generator on the visitor's own machine and gives everyone with that seed the same puzzle. It is not pre-checked the way the files are, so the files are the better source when you need the guarantee.
Will the files ever change?
A published file keeps its content. The build is deterministic and idempotent: running it again writes the same bytes, and the index carries a sha256 for every file so you can prove it. Only today/ changes, once a night.
Something missing or wrong? Write to andrej@arling.sk.
Colophon
- Publisher
- ARLing s. r. o., Ivanská cesta 32E, 821 04 Bratislava, Slovakia. Company ID 56583486, VAT ID SK2122352100.
- Who makes it
- Andrej in Bratislava looks after the products and the support and answers at andrej@arling.sk. Our own program typesets every page; the covers are commissioned and disclosed.
- What it costs
- Nothing. The endpoints are static files on the same host as this page, so there is no key, no sign-up and no rate limit to talk about.