API access is in private beta on Team plans and above; the dashboard requires no API access at all. Request access to get a workspace key, or see pricing for plan details. Breaking changes during the beta are announced in the changelog with a migration window.

Overview

FuturOne agents complete workflows, not chat turns — so the API is built around runs, not messages. You submit a task in natural language, the platform plans, executes, and verifies it, and you get back a finished deliverable with confidence scores and a content-free audit trail. How that pipeline works is covered in How It Works; this page covers how to drive it programmatically.

All endpoints live under a single base URL and speak JSON over TLS 1.3:

Base URL
https://api.futurmix.one/v1

The whole surface is three endpoints plus webhooks:

EndpointWhat it does
POST /v1/runsCreate an agent run from a natural-language task brief
GET /v1/runs/{id}Retrieve a run's status, confidence, and metadata
GET /v1/runs/{id}/eventsStream the run's event log in real time over SSE
WebhooksSigned HTTP callbacks on run completion, escalation, or failure

To see exactly what comes over the events stream before writing a line of code, the live demo replays recorded event streams from four production runs in your browser.

Quickstart

Install an SDK, export your API key, and submit a task. Both SDKs are deliberately thin wrappers — everything they do is expressible against the raw API.

Shell
pip install futurone        # Python
npm i @futurone/sdk         # Node

export FUTURONE_API_KEY="fo_live_..."
Python
from futurone import FuturOne

client = FuturOne()  # reads FUTURONE_API_KEY

run = client.runs.create(
    agent="research",
    task="Source-verified market sizing for warehouse robotics in the EU, 2024-2028. Cite every claim.",
)

for event in client.runs.events(run.id):
    print(event.type, event.data)
Node
import FuturOne from "@futurone/sdk";

const client = new FuturOne(); // reads FUTURONE_API_KEY

const run = await client.runs.create({
  agent: "coding",
  task: "Review the open PR in acme/payments-api: conventions, security, performance, coverage.",
});

for await (const event of client.runs.events(run.id)) {
  console.log(event.type, event.data);
}

The events iterator wraps the SSE stream, reconnects automatically, and resumes from the last processed event — see Stream run events for the underlying protocol.

Authentication

Every request carries a Bearer API key:

HTTP header
Authorization: Bearer fo_live_...

Keys are created and rotated in the dashboard under Workspace → API keys. Keys can be scoped per project and per capability — create runs, read runs, manage webhooks — instead of granting workspace-wide access. We recommend one scoped key per integration: a CI key that can only create and read runs cannot reconfigure your webhooks. Older unscoped keys keep working but are flagged in the dashboard with a one-click migration path.

  • Keys are workspace credentials. Keep them server-side; never embed them in client-side code or mobile apps.
  • Requests with a missing or invalid key return 401; requests outside a key's scope return 403 with the missing capability named in the error body.
  • Key usage is recorded in the audit event log — actor, action, timestamp, resource ID, never payload content.

Create a run

POST/v1/runs

Creates an agent run. The task brief is natural language — the same brief you would give in the dashboard. The planner extracts context, constraints, and success criteria from it; you do not configure a pipeline.

FieldTypeDescription
agentstring, requiredAgent domain: coding, strategy, content, or research
taskstring, requiredNatural-language task brief, including any constraints and the quality bar you expect
connectionsarray, optionalIDs of workspace connections the run may use (e.g. a GitHub App installation). Omit to run without external systems
webhook_urlstring, optionalHTTPS endpoint to notify on completion, escalation, or failure; overrides the workspace default for this run
metadataobject, optionalUp to 16 key-value pairs echoed back on the run object and in webhook payloads — useful for correlating with your own systems
Request
curl https://api.futurmix.one/v1/runs \
  -H "Authorization: Bearer fo_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "research",
    "task": "Source-verified market sizing for warehouse robotics in the EU, 2024-2028. Cite every claim.",
    "webhook_url": "https://example.com/hooks/futurone",
    "metadata": { "ticket": "RES-1042" }
  }'
Response · 201 Created
{
  "id": "fo_run_7c2d91",
  "object": "run",
  "agent": "research",
  "status": "queued",
  "confidence": null,
  "created_at": "2026-06-09T14:22:31Z",
  "completed_at": null,
  "metadata": { "ticket": "RES-1042" }
}

Run lifecycle

A run moves through queuedplanningrunning and terminates in exactly one of three states:

Terminal statusMeaning
completedVerification passed at or above the workspace confidence threshold; the deliverable is final
escalatedVerification scored below threshold; the run is in the human review queue with the verifier's reasoning attached — never delivered as final
failedThe run could not finish after retries and failover; the error event explains why, and failed runs are not billed

Retrieve a run

GET/v1/runs/{id}

Returns the current run object. Plain polling works fine for short runs and for networks that drop long-lived connections; for live progress, prefer the events stream.

Response · 200 OK
{
  "id": "fo_run_7c2d91",
  "object": "run",
  "agent": "research",
  "status": "completed",
  "confidence": 0.94,
  "steps_completed": 6,
  "artifacts": [
    { "type": "report", "label": "Market sizing report", "citations": 12 }
  ],
  "created_at": "2026-06-09T14:22:31Z",
  "completed_at": "2026-06-09T14:26:08Z",
  "metadata": { "ticket": "RES-1042" }
}

confidence is the verifier's 0–1 score, populated when verification finishes. Artifact content is delivered on the events stream and in the run's delivery channel during the run lifecycle — see Data handling for what we do and do not keep afterward.

Stream run events

GET/v1/runs/{id}/events

Streams the run's event log as server-sent events (text/event-stream). This is the same stream the dashboard renders, and the same recorded streams the live demo replays — plan, tool calls, findings, verification, delivery.

Request
curl -N https://api.futurmix.one/v1/runs/fo_run_7c2d91/events \
  -H "Authorization: Bearer fo_live_..." \
  -H "Accept: text/event-stream"
Stream
id: 14
event: step_start
data: {"step":"s3"}

id: 15
event: tool_call
data: {"step":"s3","tool":"web.search","args":{"query":"EU warehouse robotics installed base 2024"}}

: heartbeat

id: 16
event: step_done
data: {"step":"s3","took":"6.1s"}

Event types

EventPayload
statusAgent narration line — what the run is doing right now
planThe step graph the planner produced: step IDs, labels, dependencies
step_start / step_doneStep lifecycle, with wall-time on completion
tool_call / tool_resultSandboxed tool invocations and their results, with latency
findingA graded finding — severity, title, detail — as the agent surfaces it
artifactA deliverable section or attachment as it is produced
run_doneTerminal summary: final status, confidence, verification results

Reliability behavior

  • Heartbeats. The stream sends a comment-frame heartbeat every 15 seconds and sets X-Accel-Buffering: no, so proxies and corporate middleboxes don't buffer or silently collect idle connections on long runs.
  • Resumption. Every event carries a monotonic id. Reconnect with Last-Event-ID and the stream resumes from the last event you processed — no replays, no gaps. The SDKs do this automatically as of futurone 0.9 and @futurone/sdk 0.11.
  • Fallback. If your network still drops long-lived connections, poll GET /v1/runs/{id} instead; status and confidence are always consistent with the stream.

Webhooks

For fire-and-forget integrations, register a webhook endpoint (workspace-wide in the dashboard, or per run via webhook_url). FuturOne POSTs a JSON notification when a run reaches a terminal state:

EventSent when
run.completedVerification passed; the deliverable is final
run.escalatedThe run entered the human review queue
run.failedThe run terminated after exhausting retries and failover

Payloads are thin by design — run ID, terminal status, confidence, and your metadata, never artifact content. Your handler fetches what it needs with its own credentials, which keeps webhook delivery consistent with zero retention and keeps your endpoint out of your data-security audit scope.

Verifying signatures

Every delivery is signed with HMAC-SHA256 in the X-FuturOne-Signature header, using the signing secret shown when you create the endpoint. Verify before trusting:

Python
import hashlib, hmac

def verify(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Retries and the dead-letter queue

Any non-2xx response (or a timeout) triggers retries: up to 8 attempts over roughly six hours with exponential backoff and jitter. Deliveries that exhaust their retries land in a per-workspace dead-letter queue, inspectable and replayable from the dashboard for 7 days. Respond 200 quickly and process asynchronously — slow handlers are the most common cause of spurious retries.

Errors

Errors use conventional HTTP status codes and a consistent body:

Error body
{
  "error": {
    "type": "permission_error",
    "message": "This key is scoped to read runs; creating runs requires the runs:create capability."
  }
}
StatusTypeMeaning
400invalid_requestMalformed body or missing required field; the message names the field
401authentication_errorMissing, malformed, or revoked API key
403permission_errorValid key, but the request is outside its project or capability scope
404not_foundNo such run in this workspace
429rate_limitedWorkspace rate limit reached; honor the Retry-After header. Beta limits are set per workspace and shown in the dashboard
5xxserver_errorSomething failed on our side; safe to retry with backoff. Current availability is on the status page

The SDKs raise typed exceptions for each error type and retry 429 and 5xx responses with backoff automatically.

Connections & permission scoping

Runs that touch external systems — repositories, document stores, internal tools — do so through workspace connections, configured once in the dashboard and referenced by ID in POST /v1/runs. Connections follow least privilege end to end:

  • GitHub. A first-party GitHub App, installed on selected repositories only. Permissions are read on contents and write on pull requests and checks — nothing else. PR review runs can trigger automatically on ready_for_review, no API call required.
  • Enterprise connectors. Document stores and internal systems connect with credentials scoped to the specific resources you select, never workspace-wide access.
  • Short-lived credentials. Inside a run, the sandboxed tool layer receives scoped, short-lived credentials per step; nothing persists between runs.
  • Audit trail. Every agent action against a connected system lands in the audit log as an event — actor, action, timestamp, resource ID — never content. Audit events export as JSON Lines.

See Use Cases for how teams wire connections into real workflows, and Security for the full trust architecture.

Data handling

FuturOne is zero-retention: task content, documents, and intermediate results exist only for the request lifecycle, in transient encrypted buffers (TLS 1.3 in transit, AES-256 at rest). What persists is operational metadata — step timings, routing decisions, check results, audit events — which is why the event log is safe to keep and the content is not there to leak.

Practically, that means your integration should consume artifacts as they are delivered — on the events stream, or fetched on webhook notification — and store them in your own systems. Once a run's lifecycle ends, its content is gone from ours. The full policy, including subprocessors and compliance posture, is on the security page.

SDKs

SDKInstallCurrent
Pythonpip install futuronefuturone 0.9
Node / TypeScriptnpm i @futurone/sdk@futurone/sdk 0.11

Both provide typed run creation, automatic status polling with backoff, and an events iterator that wraps the SSE stream with automatic reconnection and Last-Event-ID resumption. They are deliberately thin: everything they do is expressible against the public API, so nothing locks you in. Release notes ship in the changelog.

Ready to create your first run?

Request API access on a Team plan, or watch the live demo replay these event streams first — no signup required.

Request API Access Open the Live Demo