Private puzzle library API
Store up to 1,000 puzzles per personal or team workspace. These operations create no public links; publication remains an explicit separate action.
On this page
Manage your library
Your private library
The key selects the personal or team library. It stays in memory while these docs are open. Reading needs library:read; saving and deleting need library:write.
Requests and responses
All four endpoints use POST JSON with an API key in the Authorization header. MCP exposes the equivalent library_list, library_get, library_save and library_delete tools. Calls share the usual account quota.
curl https://sudokumax.com/api/v1/library/list \
-H "Authorization: Bearer $SUDOKUMAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"limit":20}'POST /api/v1/library/list — full input and output fields
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"limit": {
"default": 20,
"type": "integer",
"minimum": 1,
"maximum": 50
},
"after": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"created": {
"type": "number"
},
"updated": {
"type": "number"
}
},
"required": [
"id",
"name",
"tags",
"revision",
"created",
"updated"
],
"additionalProperties": false
}
},
"nextCursor": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"attribution": {
"type": "object",
"properties": {
"text": {
"type": "string",
"const": "Created with Sudokumax"
},
"url": {
"type": "string",
"const": "https://sudokumax.com"
},
"required": {
"type": "boolean",
"const": true
}
},
"required": [
"text",
"url",
"required"
],
"additionalProperties": {}
}
},
"required": [
"entries",
"nextCursor",
"attribution"
],
"additionalProperties": false
}POST /api/v1/library/get — full input and output fields
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"id"
],
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"entry": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"puzzle": {
"type": "string"
},
"solution": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"created": {
"type": "number"
},
"updated": {
"type": "number"
}
},
"required": [
"id",
"name",
"puzzle",
"solution",
"tags",
"revision",
"created",
"updated"
],
"additionalProperties": false
},
"attribution": {
"type": "object",
"properties": {
"text": {
"type": "string",
"const": "Created with Sudokumax"
},
"url": {
"type": "string",
"const": "https://sudokumax.com"
},
"required": {
"type": "boolean",
"const": true
}
},
"required": [
"text",
"url",
"required"
],
"additionalProperties": {}
}
},
"required": [
"entry",
"attribution"
],
"additionalProperties": false
}POST /api/v1/library/save — full input and output fields
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"puzzle": {
"type": "string",
"pattern": "^[1-9.0-]{81}$"
},
"tags": {
"default": [],
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 30
}
}
},
"required": [
"name",
"puzzle"
],
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"entry": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"puzzle": {
"type": "string"
},
"solution": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"created": {
"type": "number"
},
"updated": {
"type": "number"
}
},
"required": [
"id",
"name",
"puzzle",
"solution",
"tags",
"revision",
"created",
"updated"
],
"additionalProperties": false
},
"attribution": {
"type": "object",
"properties": {
"text": {
"type": "string",
"const": "Created with Sudokumax"
},
"url": {
"type": "string",
"const": "https://sudokumax.com"
},
"required": {
"type": "boolean",
"const": true
}
},
"required": [
"text",
"url",
"required"
],
"additionalProperties": {}
}
},
"required": [
"entry",
"attribution"
],
"additionalProperties": false
}POST /api/v1/library/delete — full input and output fields
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
}
},
"required": [
"id",
"revision"
],
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"deleted": {
"type": "boolean",
"const": true
},
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"attribution": {
"type": "object",
"properties": {
"text": {
"type": "string",
"const": "Created with Sudokumax"
},
"url": {
"type": "string",
"const": "https://sudokumax.com"
},
"required": {
"type": "boolean",
"const": true
}
},
"required": [
"text",
"url",
"required"
],
"additionalProperties": {}
}
},
"required": [
"deleted",
"id",
"attribution"
],
"additionalProperties": false
}Save: supply name, puzzle and optional tags. The server verifies a unique solution and stores the normalized puzzle and answer. For updates, send both id and revision; a stale revision returns 409 REVISION_CONFLICT. Delete also requires the current revision.
List: returns metadata and nextCursor. Pass it as after to fetch the next page; null means the end. Entries are ordered by ID. This is live pagination, not a snapshot: concurrent inserts may require a fresh listing. Get returns the complete entry, including the solution for your backend.
400 means invalid fields, 401 missing/invalid key, 403 revoked access or insufficient scope, 404 unavailable entry, 409 stale revision or capacity, and 422 an unsuitable puzzle. OpenAPI schemas.
Access and privacy
A personal key accesses only its owner’s personal library. A team key accesses only that team’s library. Viewers cannot write, even with an old key. Removing a member revokes their team keys immediately; suspending the owner disables the team’s API access.
Records remain until deleted or the owning account is deleted. Private entries have no public URL. If you explicitly publish their grids, those public copies are separate and are not removed by deleting the library entry. Puzzle data and titles should not contain personal or confidential information.
Manage teams and key scopes →