Skip to main content
Glama

Start Validated Run

horizon_start_run

Starts a server-validated run for leaderboards requiring server-checked scores, issuing a single-use ticket and seed.

Instructions

Starts a server-checked run (Validated Actions): issues a single-use ticket with a server seed and starts the server's run timer. Use when: before a round whose score or earned currency must be checked by the server, and always for boards marked validatedOnly in horizon_list_leaderboards. Not for: normal boards where the client may write its own score (use horizon_submit_score) and reading balances (use horizon_get_state). Requires: userId and the player's session: sign in with horizon_signin_email or horizon_signin_anonymous and pass its accessToken as sessionToken. Pass leaderboardKey to bind the ticket to a board (it must exist; 'default' is created on first use). Optionally declare the start context (gameVersion, contentVersion, simulationVersion, replayFormatVersion, contentDigest, initialStateBase64); the server binds it with its own start values (rule version, cloud save, balances, seed) into the run, and a sus run keeps it in its review package. Side effects: issues a new ticket per call and counts against the run limits per player and per account; unused tickets simply expire. Returns: {runId, ticket, seed, leaderboardKey, issuedAt, expiresAt, expiresInSeconds}. Seed the game's deterministic randomness with seed, record the input log, then send the result with horizon_submit_validated and the unchanged ticket before expiresAt. Errors: Errors carry a stable code in the body and the error result names it: 400 for a bad context field, 400 INITIAL_STATE_INVALID_ENCODING (initialState not standard base64), 413 INITIAL_STATE_TOO_LARGE (decoded initialState above the plan's evidenceMaxBytes), 401 SESSION_REQUIRED, 403 SESSION_FORBIDDEN, 404 PLAYER_NOT_FOUND or LEADERBOARD_NOT_FOUND, 429 RUN_RATE_LIMITED (per player and hour) or RUN_CAPACITY_REACHED (account per UTC hour; do not retry automatically, the wait can be an hour), 503 VALIDATED_ACTIONS_UNAVAILABLE (server has no ticket key). After 401 sign in again; after 403 SESSION_FORBIDDEN pass the userId that signed in. Needs HORIZON_API_KEY. Every failure returns an error result (isError) with the HTTP status and body: a 401 that horizon_test_connection also returns means HORIZON_API_KEY is wrong, 429 means the account's per-minute rate limit was reached (wait a minute, then retry).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
userIdYesPlayer user ID (UUID) from horizon_signup_* or horizon_signin_*
gameVersionNoGame build version, for example "1.4.2" (1 to 64 printable ASCII characters), stored in the run's start context. Optional
sessionTokenYesaccessToken from horizon_signin_email or horizon_signin_anonymous for this userId; sent as a Bearer session
contentDigestNoSHA-256 of the game content the run uses, 64 hex characters (sent in lower case). Optional
contentVersionNoVersion of the game content (levels, balancing data) the run uses (1 to 64 printable ASCII characters), stored in the run's start context. Optional
leaderboardKeyNoBoard key to bind the ticket to, from horizon_list_leaderboards (1 to 64 characters: a-z, 0-9, _ and -). Omit for an unbound ticket (currency only runs, or choose the board at submit).
simulationVersionNoVersion of the deterministic simulation that replays the input log (1 to 64 printable ASCII characters), stored in the run's start context. Optional
initialStateBase64NoBytes the simulation starts from as standard base64 (sent as context.initialState); decoded at most the plan's evidenceMaxBytes (32,768 bytes by default). Optional
replayFormatVersionNoFormat version of the recorded input log (1 to 64 printable ASCII characters), stored in the run's start context. Optional

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv1.7.0
    • addedInput schema / properties / contentDigest
      Added value: +{
      +  "description": "SHA-256 of the game content the run uses, 64 hex characters (sent in lower case). Optional",
      +  "pattern": "^[0-9a-fA-F]{64}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / contentVersion
      Added value: +{
      +  "description": "Version of the game content (levels, balancing data) the run uses (1 to 64 printable ASCII characters), stored in the run's start context. Optional",
      +  "pattern": "^[\\x20-\\x7E]{1,64}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / gameVersion
      Added value: +{
      +  "description": "Game build version, for example \"1.4.2\" (1 to 64 printable ASCII characters), stored in the run's start context. Optional",
      +  "pattern": "^[\\x20-\\x7E]{1,64}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / initialStateBase64
      Added value: +{
      +  "description": "Bytes the simulation starts from as standard base64 (sent as context.initialState); decoded at most the plan's evidenceMaxBytes (32,768 bytes by default). Optional",
      +  "maxLength": 2000000,
      +  "type": "string"
      +}
    • addedInput schema / properties / replayFormatVersion
      Added value: +{
      +  "description": "Format version of the recorded input log (1 to 64 printable ASCII characters), stored in the run's start context. Optional",
      +  "pattern": "^[\\x20-\\x7E]{1,64}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / simulationVersion
      Added value: +{
      +  "description": "Version of the deterministic simulation that replays the input log (1 to 64 printable ASCII characters), stored in the run's start context. Optional",
      +  "pattern": "^[\\x20-\\x7E]{1,64}$",
      +  "type": "string"
      +}
  2. Addedv1.6.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations (non-read-only, non-idempotent, open-world) cover only the safety profile; the description adds the real behavior: a new single-use ticket per call, run limits per player and per account, ticket expiry, server-owned start values bound into the run, and a full error taxonomy with stable codes and remediation for each (401/403/404/429/503). This is well beyond what the annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Roughly 350 words, but front-loaded with the core action and then segmented into Use when / Not for / Requires / Side effects / Returns / Errors labels, which makes it scannable. It loses a point for mild redundancy, e.g. 429 handling appearing both in the Errors list and again in the closing rate-limit note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the return object is enumerated and the follow-through workflow is spelled out (seed deterministic randomness with seed, record the input log, submit with horizon_submit_validated using the unchanged ticket before expiresAt). Nothing needed to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3 and the schema already documents all nine parameters. The description nonetheless adds semantics not in the schema, notably that leaderboardKey binds the ticket to a board that must already exist and that 'default' is created on first use, plus how the optional context fields are consumed server-side.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource and mechanism: 'Starts a server-checked run (Validated Actions): issues a single-use ticket with a server seed and starts the server's run timer.' It distinguishes itself from siblings by explicitly naming horizon_submit_score and horizon_get_state as the wrong tools for adjacent needs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' (before a round whose score or currency must be server-checked; always for boards marked validatedOnly in horizon_list_leaderboards) and explicit 'Not for' with the correct alternatives named. Prerequisites and auth chain are stated, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.