Upload Validated Run Evidence
horizon_upload_evidenceUploads a run's raw input log for developer evidence review when a validated submit requires it, before the 24-hour upload window closes.
Instructions
Uploads the input log of a validated run after horizon_submit_validated answered with evidence.required = true (evidence review). Use when: only when a submit result carries evidence.required: true, before evidence.uploadBefore (24 hours). Not for: runs without an evidence request (the server answers 404 EVIDENCE_NOT_REQUESTED) and sending the log with the submit (the submit takes only its hash). Requires: userId and the player's session: sign in with horizon_signin_email or horizon_signin_anonymous and pass its accessToken as sessionToken. The runId from the submit result and the raw input log as exactly one of inputLogBase64 (raw bytes as base64) or inputLog (UTF-8 text). Its SHA-256 must equal the inputLogHash sent with the run, so pass the same bytes or text that were hashed at submit; at most evidence.maxBytes (32,768 bytes by default). Side effects: stores the log for the developer's review; one upload per run (a second one gets 409). Returns: {runId, status: "UPLOADED", bytes} plus inputLogHash (the SHA-256 of the uploaded bytes, for comparison with the submit). Errors: Errors carry a stable code in the body and the error result names it: 400 EVIDENCE_INVALID_ENCODING (not standard base64), 401 SESSION_REQUIRED, 403 SESSION_FORBIDDEN, 404 EVIDENCE_NOT_REQUESTED (no request for this run and player; also for a run of another player), 409 EVIDENCE_ALREADY_UPLOADED, 410 EVIDENCE_EXPIRED (window passed, slot freed), 413 EVIDENCE_TOO_LARGE (decoded log above maxBytes), 422 EVIDENCE_HASH_MISMATCH (SHA-256 of the log differs from the run's inputLogHash; the request stays open, retry with the correct bytes until uploadBefore), 429 without code (account request limit). Only 422 and network errors are worth a retry; the others are final. Local error (no request sent): INVALID_INPUT_LOG when the log input was missing, doubled, empty or not base64. 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
| Name | Required | Description | Default |
|---|---|---|---|
| runId | Yes | runId (UUID) from the horizon_submit_validated result (evidence.runId) | |
| userId | Yes | Player user ID (UUID) from horizon_signup_* or horizon_signin_* | |
| inputLog | No | Input log as UTF-8 text; its UTF-8 bytes are uploaded. Use this or inputLogBase64. | |
| sessionToken | Yes | accessToken from horizon_signin_email or horizon_signin_anonymous for this userId; sent as a Bearer session | |
| inputLogBase64 | No | Raw input log bytes as standard base64. Use this or inputLog. |