Skip to main content
Glama

Start Validated Run

horizon_start_run

Starts a server-checked run by issuing a single-use ticket, server seed, and run timer before submitting a validated score or earned currency.

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, balances, seed) into the run, and a sus run keeps it in its review package. The server never reads the cloud save; send the start state a replay needs as initialStateBase64. 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

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.6/5.0
Behavior4/5

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

Rich disclosure beyond the annotations: a new ticket per call, per-player and per-account run limits, unused tickets expire, the server never reads the cloud save (so start state must be sent as initialStateBase64), and a full error-code table with remediation. One flaw: the final sentence says 429 means the account's per-minute limit and 'wait a minute, then retry', which conflicts with the earlier 'do not retry automatically, the wait can be an hour' for RUN_CAPACITY_REACHED.

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?

Long, but front-loaded and segmented into Use when / Not for / Requires / Side effects / Returns / Errors, with nearly every line carrying operational information. It loses a point for some redundancy and for the internally inconsistent 429 guidance in the closing paragraph.

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?

With 9 parameters, no output schema, and a mutation tool, the description supplies what is otherwise missing: exact return fields, ticket lifetime and the horizon_submit_validated follow-up, typed error codes with per-code recovery, and capacity caveats. An agent has everything needed to call it correctly and handle failures.

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, but the description adds real semantics: leaderboardKey binds the ticket to an existing board ('default' is created on first use) or may be omitted for an unbound ticket, and initialStateBase64 is framed as the channel for start state given the server never reads the cloud save. The optional context fields are otherwise only summarized as 'start context', leaving the schema to carry the detail.

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?

States a specific verb and resource ('starts a server-checked run (Validated Actions)') and immediately names the concrete artifact produced: a single-use ticket with a server seed plus the server run timer. It is clearly separable from horizon_submit_score and horizon_get_state, both of which are named as the wrong tools for adjacent jobs.

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' (server-checked score/currency rounds, always for validatedOnly boards per horizon_list_leaderboards) and 'Not for' (normal boards → horizon_submit_score; balances → horizon_get_state). Prerequisites are spelled out: sign in via horizon_signin_email/horizon_signin_anonymous and pass the accessToken as sessionToken.

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

Deploy Server

Other Tools