Reading a Riddle back

GET /riddle-builder/{UUID} returns any Riddle - also ones that were never built via the API - as the same build configuration a build request accepts as build. Three things it is for:

  • preparing an edit, which addresses blocks by the id they are stored with
  • checking what a Riddle currently holds, including which features are switched on
  • learning the defaults of a block type

Response

PropertyTypeDescriptionDefault
uuidstringThe UUID of the Riddle
typestringThe Riddle type
modifiedAtstringWhen the Riddle was last modified, e.g. 2024-01-01 12:00:00
buildobjectThe Riddle as a build configuration; every block, item and result carries the id it is stored with
nextBlockIdintegerThe ID a newly added block may claim, and the only reliable source for one - see block IDs
warningsarrayEverything that could not be expressed in build, each with a path (e.g. blocks[7].items), a reason (UNKNOWN_BLOCK_TYPE, PROPERTY_NOT_SERIALIZABLE, RIDDLE_DATA_NOT_EXPRESSIBLE) and a message

Example

{
    "uuid": "abcdef12",
    "type": "Poll",
    "modifiedAt": "2026-01-01 12:00:00",
    "nextBlockId": 9,
    "build": {
        "title": "Favorite color poll",
        "blocks": [
            {
                "id": 1,
                "type": "SingleChoice",
                "title": "What's your favorite color?",
                "items": [ ... ]
            },
            {
                "id": 3,
                "type": "NPS",
                "title": "How likely are you to recommend us?"
            }
        ],
        "result": { "id": 2, "title": "Thank you" }
    },
    "warnings": []
}

Content the build configuration cannot express

The endpoint never fails on content it does not understand. Unsupported blocks are returned as {"id": ..., "type": ..., "isSupported": false, "rawContent": {...}} - for reference only, never send them back. Everything else that could not be expressed comes with an entry in warnings.

Properties left out because they are still at their default

A property that still holds its block type's own default value is not written into build. The omission is never silent, though: every block carries an omittedDefaults object naming each of those properties together with the value it is at.

{
    "id": 1,
    "type": "SingleChoice",
    "title": "Capital of France?",
    "items": [
        {
            "id": 1,
            "title": "Paris",
            "isCorrect": true,
            "omittedDefaults": { "description": "", "media": null, "score": 1 }
        }
    ],
    "omittedDefaults": {
        "description": "",
        "media": null,
        "mediaOrientation": "Settings",
        "score": 1,
        "itemsShuffled": false,
        "isRequired": true,
        "layoutType": "Rows"
    }
}

Items, form fields and result pages carry their own omittedDefaults the same way their block does - the map always belongs to the object it sits in. (The block map above is shortened; a real one covers every default that block type has.)

Read it as "these properties are still X", not as "these properties can be set to X here":

Do not send a value from omittedDefaults back. It is informational. A good number of builder properties switch a feature on by being present at all, whatever value they carry - the preset timer, double opt-in and email automation, the scoring level. Copying a pair out of this map into the block is therefore not a no-op; leave the property out, exactly as the read-back did.

  • id and type are never omitted. They are written on every block, always - as is every required property of that block type, even when it happens to equal the default.
  • A property this block cannot accept at all is not listed either. Where a property is only valid for a certain configuration - the showInfo-only properties of an interactive-graphic hotspot, the area-only properties of a dot hotspot - it is rejected rather than defaulted, so it is deliberately not advertised as an omitted default.
  • The key is absent from a block that omitted nothing.
  • A property in neither build nor omittedDefaults is either one of those conditionally invalid ones, or genuinely could not be expressed - and the second kind comes with an entry in warnings.

This is also why diffing a fetched config against the config you originally sent shows fewer properties than you sent: compare against a fresh minimal build of the same block type instead.

Need the defaults of a block type you have not built yet? Build a minimal block of that type and read it back - its omittedDefaults is the complete list. The same catalogue is also published per Riddle type and block type as a reference document for MCP clients.

Next steps