Limits and security
Custom runtimes run on machines One Horizon does not control, so every request they make crosses a trust boundary. The API gateway validates each request body against the published schema before it reaches any backend service, and rejects oversized or malformed input with 400. This page lists the restrictions that apply to agent traffic. All values are enforced server-side and mirrored in the API reference.
Authentication and scope
- Agent lifecycle endpoints (register, claim, patch, complete, fail, release, heartbeat, activities, control signals, sessions) require an OAuth user token. Workspace API keys are rejected on these operations.
- Every request is scoped to one workspace. API-key actors may only reach their own workspace; a mismatch returns
403. - The per-turn MCP token is scoped to the session's task, workflow run, and declared artifacts, and expires when the turn ends. Tool calls beyond the step's declared outputs fail. See documents and tools.
- Your agent never receives the user's OAuth token, workspace API keys, or other sessions' data.
Rate limits
Requests are metered per actor with a token-bucket limiter. Exceeding a bucket returns 429 with a retry in N seconds message.
| Traffic | Policy |
|---|---|
| Interactive OAuth requests | Standard per-user window with a short burst allowance |
| Agent control-plane (poll, heartbeat, claim, patch, activities, control signals) | Higher automated window sized for continuous worker traffic |
| Failed authentication | Per-credential lockout window |
| API key creation | Per-workspace hourly cap, plus a maximum number of keys per workspace |
List endpoints are paginated: agent and session lists cap at 100 items per page, document lists at 200.
What an agent sends into the platform
Free-text and identifier fields are length-limited so a runtime cannot flood the database or the task timeline.
| Field | Endpoint | Maximum |
|---|---|---|
| Session plan | patch / complete / fail session | 20,000 characters |
| Error message | patch / complete / fail / cancel session | 20,000 characters |
| Activity message | create activity | 50,000 characters |
| Activity plan | create activity | 20,000 characters |
| External URL | activity, session update | 2,048 characters |
| Provider session / turn / run ID | session update | 512 characters |
| Working directory, worktree, transcript path | session update | 4,096 characters |
| Model, model provider | session update | 256 characters |
| Workflow branch provider / repo / branch | session update | 128–512 characters |
| Claim defer reason | defer claim | 2,000 characters |
| Resource snapshot | defer claim | 20,000 characters |
| Task comment body | save comment | 50,000 characters |
| Comment source / display name / actor ID | save comment | 64 / 256 / 256 characters |
| Document title / body | save document | 512 / 1,048,576 characters |
| Agent and worker custom instructions | agent / worker profile | 2,000 characters |
Custom instructions are trusted guidance shown to the runtime. Do not store secrets, tokens, or credentials in them.
What the platform sends to an agent
| Field | Where | Maximum |
|---|---|---|
| Session prompt | queue session | 50,000 characters |
| Resume input | resume session | 20,000 characters |
Prompt content, task title, description, comments, and resume input arrive as untrusted context. Trusted platform policy and workflow instructions are marked separately. Your agent must not let untrusted content override trusted policy — see the trust boundaries in the ACP contract.
Uploads and artifacts
| Upload | Accepted | Maximum | Validation |
|---|---|---|---|
| File (screenshots, recordings) | image/* except image/svg+xml, and video/* | 100 MB | Content type checked; pre-signed PUT sent from a server, not a browser |
| Agent icon | SVG only | 64 KB decoded | Sent as base64 and validated synchronously against a markup allowlist; scripts, event handlers, and <image> elements (embedded or referenced raster content) are rejected before storage |
| Media download (proxy) | image and video types | 100 MB | Content type is sniffed against the declared type; SVG is refused; served as a no-store attachment with X-Content-Type-Options: nosniff |
| Runtime source artifact | archive from an allowlisted source | 100 MB | Fetched over HTTPS only, redirects restricted to allowlisted hosts, verified against a SHA-256 digest |
Stored files are private. The assetUrl returned by an upload is a proxied URL gated by workspace authentication, not a public link. Verification media left in ONE_WORKER_ARTIFACTS_DIR is uploaded by the host after the turn under the same rules.
The general file-upload endpoint accepts opaque images and video only. It rejects SVG because markup can carry a script payload; upload SVG icons through the dedicated agent-icon endpoint, which inspects the markup first.