Skip to main content
Horizon requires an API key to use. You can get one by signing up at api.mathematicalcompany.com, or programmatically via the SDK.

Setup

Option A: Website (Manual)

1

Get your API key

Sign up at api.mathematicalcompany.com and copy your API key. Keys start with hz_sdk_.
2

Set the environment variable

Add this to your shell profile (~/.zshrc, ~/.bashrc, etc.):
Then reload your shell or run source ~/.zshrc.
3

Run your strategy

That’s it. The SDK validates your key once at startup and caches the result locally. There is zero latency impact on trading.

Option B: Programmatic (Agentic)

Create an account and generate an SDK key entirely from the command line or through an AI agent. No browser required.
1

Install the SDK

2

Run setup

Pass your password via the HORIZON_PASSWORD environment variable to avoid shell history exposure:
This will:
  1. Try to log in (if you already have an account)
  2. Sign up if the account does not exist
  3. Generate a new SDK key
  4. Save the encrypted key to ~/.horizon/credentials.json
On success you will see:
If Supabase email confirmation is enabled, you will see "status": "confirmation_required". Check your email and confirm before running setup again.
3

Run your strategy

The engine auto-loads the key from ~/.horizon/credentials.json:
Or set the env var explicitly:

MCP / AI Agent Setup

AI agents using the MCP server or OpenClaw skill can call the auth tools directly: The agent asks the user for their email, sets HORIZON_PASSWORD, and calls account(action="setup", params="{\"email\": \"...\"}"). The key is saved encrypted to disk and never returned in full in tool responses (only the prefix is shown).

Python API

Security

  • Passwords: Always use the HORIZON_PASSWORD env var instead of passing passwords as CLI arguments. CLI arguments are visible in shell history and process listings.
  • Key storage: Credentials are encrypted at rest using a machine-derived key (hostname + username). The plaintext key is never written to disk.
  • Key exposure: Tool responses only include the key prefix, never the full key.
  • Rate limiting: Client-side rate limiting caps auth attempts to 5 per 60 seconds.

How It Works

  1. Startup only - validation happens once when Engine is created (inside hz.run()). After that, no network calls are made during trading.
  2. Local cache - a successful validation is cached at ~/.horizon/license.json for 72 hours. The raw key is never stored, only a SHA-256 hash.
  3. Offline grace period - if the network is unavailable but a valid cache exists for your key, the SDK allows startup. No internet dependency during cached periods.
  4. Compiled in Rust - the validation logic is in the compiled binary, not in bypassable Python code.

Configuration

There are two ways to provide your API key:
This is the recommended approach. Set it once in your shell profile and forget about it.

Explicit Parameter

You can pass the key directly in code - useful for notebooks, testing, or when you don’t want to set environment variables. With hz.run():
With Engine() directly:
The explicit parameter takes priority over the environment variable.

Resolution Order

Error Messages

If the key is missing:
If the key is invalid or expired:
If there’s a network error and no cached validation:

Cache Location

The license cache is stored at:
To force re-validation (e.g., after upgrading your plan), delete this file:

Using with Docker

Pass the key as an environment variable:
Or at runtime: