Create and connect to Leaderboard

Leaderboards enable you to create more engaging and interactive content with little to zero maintenance, e.g. a weekly quiz with a ranking, or a Predictor for every match of your sports team.

There are two separate things you can do, and they use two different parts of the build configuration:

What you want to doRiddle type you buildWhere it is configured
Create a new leaderboardLeaderboardthe build object itself - see Create a leaderboard
Make a Quiz/Predictor/Minigame report to an existing leaderboardQuiz, Predictor, Minigamebuild.leaderboard.connections - see Connect a Riddle

Both can be combined: create the leaderboard first, then reference its UUID in the Riddles you build afterwards.

1. Create a leaderboard

A leaderboard is a Riddle type of its own, but a very reduced one: it has no blocks, no logic, no publish settings and no result page. The properties below are everything a leaderboard build config can express.

Build properties

PropertyRequiredTypeDescriptionDefault
titlestringThe title of the leaderboard
riddleConnectionsstringUUIDs of the Riddles that should report to this leaderboard right away; maximum: 10
presetobjectPreset settings of the leaderboard; this is where every display setting of the leaderboard lives - see below

Note: A leaderboard's own display settings - the podium colors and the email verification requirement - are keys of the preset object, not build properties of their own. isEmailValidationRequired, color1st, color2nd and color3rd are no longer accepted at the top level of build; send them as preset.isEmailVerificationEnabled and preset.color1st/color2nd/color3rd instead. That is also exactly how a read-back reports them, so a fetched configuration can be sent back unchanged. Sent at the top level they are now an unknown property: silently ignored in a plain create, and rejected with a 400 under strictProperties or when editing a leaderboard.

Note: riddleConnections is not create-only. PUT /riddle-builder/{UUID} accepts it on an existing leaderboard to add or drop connected Riddles at any time - it replaces the whole list, so resend every UUID you want to keep together with any new ones.

Note: Every UUID in riddleConnections must be an existing Quiz, Predictor or Minigame that already has a Name and an Email field - the same requirements as connecting from the other side, described in section 2.

Leaderboard preset settings

On top of the shared preset settings (preset/presetId, palette, language, ads, customStrings, footerText, footerBranding, isRiddleFooterVisible, isShareButtonVisible), a leaderboard's preset accepts:

PropertyRequiredTypeDescriptionDefault
isCompactViewbooleanWhether entries are rendered in the compact, single-line viewfalse
entriesAboveintegerHow many entries are shown above the visitor's own entry1
entriesBelowintegerHow many entries are shown below the visitor's own entry3
isTotalEntriesEnabledbooleanWhether the total number of entries is displayedfalse
isOneVotePerIdentifierEnabledbooleanWhether every identifier (e.g. email address) may only appear oncefalse
isBadwordFilterEnabledbooleanWhether nicknames are run through the bad-word filterfalse
badwordFilterCustomListstringAdditional comma-separated words to filter
quizTimeMultiplierinteger0-100; how strongly the time a visitor needed influences the ranking0
isEmailVerificationEnabledbooleanWhether visitors have to confirm their email address before their entry appears on the leaderboard. It is never switched on for you, so send it explicitly whenever only confirmed participants should be rankedfalse
color1ststringCSS color of the first-place row on the podium#D38807
color2ndstringCSS color of the second-place row on the podium#A9A9A9
color3rdstringCSS color of the third-place row on the podium#C2691C

The three podium colors are independent of each other: sending one leaves the other two at whatever the leaderboard already shows. A read-back only reports the ones that differ from the defaults above - the rest are listed in omittedDefaults, like every other property still at its default.

Example

The smallest possible leaderboard - a title and nothing else:

{
    "type": "Leaderboard",
    "build": {
        "title": "My leaderboard"
    }
}

A leaderboard that two existing Riddles report to right away, with email verification switched on:

{
    "type": "Leaderboard",
    "build": {
        "title": "My leaderboard",
        "riddleConnections": ["SampleUUID1", "SampleUUID2"],
        "preset": {
            "isEmailVerificationEnabled": true
        }
    }
}

Example

Every property a leaderboard build config accepts, including the leaderboard-specific preset settings:

{
    "type": "Leaderboard",
    "project": 123,
    "publish": true,
    "build": {
        "title": "Season leaderboard",
        "riddleConnections": ["SampleUUID1", "SampleUUID2"],
        "preset": {
            "language": "en",
            "isEmailVerificationEnabled": true,
            "color1st": "#ffd700",
            "color2nd": "#c0c0c0",
            "color3rd": "#cd7f32",
            "isCompactView": false,
            "entriesAbove": 2,
            "entriesBelow": 5,
            "isTotalEntriesEnabled": true,
            "isOneVotePerIdentifierEnabled": true,
            "isBadwordFilterEnabled": true,
            "badwordFilterCustomList": "spam,troll",
            "quizTimeMultiplier": 20
        }
    }
}

Replace SampleUUID1/SampleUUID2 with UUIDs of Riddles that exist in the same project - or leave riddleConnections out entirely to create an empty leaderboard and connect Riddles to it later, as described next.

2. Connect a Riddle to an existing leaderboard

Connections are configured in build.leaderboard of the Riddle you build, not of the leaderboard.

Requirements

  • Only quizzes, predictors and minigames can be connected - they are the only types that produce a ranking. Polls, personality tests, forms and stories cannot.
  • The Riddle needs a Name and an Email field (see form fields), or an explicit nickname/identifier mapping.
  • A minigame consisting of nothing but a WheelSpinner block cannot be connected - a wheel only produces a win/loss outcome, not a rankable score. Add another minigame block (e.g. a Sudoku).
  • Connecting multiple Riddles to a single leaderboard requires our Enterprise subscription.

Connection properties

PropertyRequiredTypeDescriptionDefault
connectionsstring1-3 UUIDs of the leaderboards this Riddle reports to. Duplicate UUIDs are collapsed into one connection
identifierstringWhich field identifies the visitor; overrides auto-detection. Must be an Email field
nicknamestringWhich field provides the displayed name; overrides auto-detection. Must be a Name field or a data layer variable

Example

With no identifier/nickname given, the first Email field becomes the identifier and the first Name field the nickname:

{
    "type": "Quiz",
    "build": {
        "title": "My quiz",
        "blocks": [
            {
                "title": "What's the capital of Germany?",
                "type": "SingleChoice",
                "items": [
                    { "title": "Berlin", "isCorrect": true },
                    { "title": "Lissabon", "isCorrect": false },
                    { "title": "Leipzig", "isCorrect": false }
                ]
            },
            {
                "title": "My form",
                "type": "FormBuilder",
                "fields": [
                    { "title": "Your email", "type": "Email" },
                    { "title": "Your name", "type": "Name" }
                ]
            }
        ],
        "leaderboard": {
            "connections": ["Fw5uSygx"]
        }
    }
}

Identifier and nickname fields

Auto-detection is only right as long as there is exactly one obvious candidate. Map the fields explicitly whenever your form holds several email or text fields, or when the value should come from the data layer instead of a visible field.

Both properties accept three input forms:

Input formExampleWhen to use it
The field label"Your email"Matched case-insensitively, ignoring surrounding whitespace
The canonical field key"email1", "email2", "name1"The field type in lowercase plus its position among the fields of that type (email2 = second Email field). This is exactly what the API emits when you read the Riddle back, so a fetched build config can be sent back unchanged
A data layer variable"dataLayer:customerId"The value is passed in when the Riddle is opened rather than typed by the visitor

Example with both mapped explicitly - the second email field identifies the visitor, and the second name field provides the displayed name:

{
    "type": "Quiz",
    "build": {
        "title": "My quiz",
        "blocks": [
            {
                "title": "What's the capital of Germany?",
                "type": "SingleChoice",
                "items": [
                    { "title": "Berlin", "isCorrect": true },
                    { "title": "Lissabon", "isCorrect": false },
                    { "title": "Leipzig", "isCorrect": false }
                ]
            },
            {
                "title": "My form",
                "type": "FormBuilder",
                "fields": [
                    { "title": "Your private email", "type": "Email" },
                    { "title": "Your work email", "type": "Email" },
                    { "title": "Your real name", "type": "Name" },
                    { "title": "Your display name", "type": "Name" }
                ]
            }
        ],
        "leaderboard": {
            "connections": ["Fw5uSygx"],
            "identifier": "Your work email",
            "nickname": "Your display name"
        }
    }
}

The exact same mapping by canonical key - and a nickname taken from the data layer instead of a visible field:

{
    "leaderboard": {
        "connections": ["Fw5uSygx"],
        "identifier": "email2",
        "nickname": "dataLayer:customerName"
    }
}

Rules:

  • identifier must point at an Email field, nickname at a Name field (or, for nickname, at a data layer variable). Any other field type - a ShortText, for example - is rejected, naming the allowed types.
  • If a label is shared by more than one eligible field, the request is rejected as ambiguous and lists the candidate keys - use one of those canonical keys instead.
  • identifier and nickname cannot resolve to the same field.
  • If both resolve to form fields (i.e. neither is a dataLayer: variable), they must live on the same FormBuilder block.
  • A nickname is mandatory: without a Name field and without an explicit nickname, the connection is rejected.
  • Connecting to a leaderboard that has email verification enabled (preset.isEmailVerificationEnabled, see section 1) requires an identifier - either an Email field in the Riddle or an explicit identifier.

Tip: To show the leaderboard on the result page and to fully engage the user, add the Leaderboard block to the result page. Click here to learn more.

Fetch leaderboard entries

To read the entries of a leaderboard, e.g. to display them in your own frontend or to determine the winners of a contest, use the /riddle-leaderboard/entries/{UUID} API endpoint.

PropertyRequiredTypeDescriptionDefault
pageintegerThe page you want to return
limitintegerHow many results the page should contain (maximum: 50)50
searchstringSearch term; exact match for an email address, or partial match for a nickname

Example payload:

{
    "page": 1,
    "limit": 50
}

Unpublishing and deleting a leaderboard

A leaderboard with active Riddle connections cannot be unpublished - the connected Riddles depend on it, and you will get an UNPUBLISH_CONFLICTING_INTERDEPENDENCE_LEADERBOARD validation error. For the same reason, a connected Riddle cannot be deleted while the leaderboard still points at it.

To get rid of such a leaderboard, delete it instead: deleting a leaderboard is always allowed and cleans up the connected Riddles automatically. Unpublishing becomes possible once the connections themselves are gone.

Troubleshooting

Make sure that..

  • the leaderboard UUID is correct
  • the leaderboard is in the same project as the Riddle you are creating
  • you have added a FormBuilder with a Name and an Email field to your Riddle
  • when you want to connect multiple Riddles: you are subscribed to our Enterprise plan

Full example

A quiz connected to the published leaderboard Fw5uSygx, with the identifier and nickname fields mapped explicitly because the form holds two email fields.

{
    "type": "Quiz",
    "build": {
        "title": "Season quiz",
        "blocks": [
            {
                "type": "SingleChoice",
                "title": "What's the capital of Germany?",
                "items": [
                    { "title": "Berlin", "isCorrect": true },
                    { "title": "Lissabon", "isCorrect": false },
                    { "title": "Leipzig", "isCorrect": false }
                ]
            },
            {
                "type": "FormBuilder",
                "title": "Enter the ranking",
                "fields": [
                    { "title": "Your email", "type": "Email" },
                    { "title": "Work email", "type": "Email" },
                    { "title": "Your name", "type": "Name" }
                ]
            }
        ],
        "leaderboard": {
            "connections": ["Fw5uSygx"],
            "identifier": "Your email",
            "nickname": "Your name"
        },
        "results": [
            {
                "minPercentage": 0,
                "maxPercentage": 100,
                "title": "Thanks for playing!"
            }
        ]
    }
}