Preview API

AccessAPI Private Preview

One client for the whole platform.

One Python package and one key reach every product on the platform. The same objects answer over REST, a CLI and an MCP server for your agents.

fx = fantasti.Client()

Opens with the first cohort. No account is open yet.

Preview API · subject to change
import fantasti

# one key, one client
fx = fantasti.Client()

node = fx.instances.create(
    gpu="H100:8",
    capacity=fantasti.Reserved("rsv_7d2k"))
sb = fx.sandboxes.create(
    image="python:3.12", ttl="15m")
run = fx.batch.create(
    image="ghcr.io/acme/scorer:2026.10",
    input="s3://acme/in/*.jsonl",
    output="s3://acme/out/")

for o in (node, sb, run):
    print(o.id, o.status, o.placement)

Output · illustrative

ins_8f2a…  ready   us-east · fabric a · reserved
sb_7q2m…   ready   us-east · on-demand
bat_2kq8…  queued  None
$ fantasti instance create ft-01 --gpu H100:1 --on-demand
$ fantasti instance list

$ fantasti cluster create sft-01 --gpu H200:8 \
    --nodes 2 --spot --max-price 3.10

Output · illustrative

request   H200:8 × 2 · one InfiniBand fabric · spot ≤ 3.10
pools     4 considered
placed    cl_8f2k… · us-east · fabric a
state     running · kubeconfig saved
{
  "mcpServers": {
    "fantasti": {
      "type": "http",
      "url": "https://mcp.fantasti.ai/mcp"
    }
  }
}

Tools · early access

catalog     gpus_list
sandboxes   sandboxes_create · sandboxes_exec · sandboxes_read_file
            sandboxes_write_file · sandboxes_delete
workspaces  workspaces_list · workspaces_start · workspaces_stop
jobs        jobs_create · jobs_logs
usage       usage_get
curl -X POST https://api.fantasti.ai/v1/instances \
  -H "Authorization: Bearer $FANTASTI_API_KEY" \
  -H "Idempotency-Key: ft-01-create" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "ft-01",
        "gpu": "H100:1",
        "capacity": { "mode": "on_demand" }
      }'
# 202 → { "id": "ins_8f2a…", "status": "placing" }
# policy.yaml · applies to every request from team "research"
team: research
placement:
  gpus: [H100, H200, B200]
  fabric: infiniband            # multi-node jobs stay on one fabric
  regions: ["us-*"]
capacity:
  allow: [on_demand, spot, reserved]
  spot:
    max_price: { H100: 2.40, H200: 3.10 }   # your ceilings
limits:
  gpus: { H200: 32 }
  sandboxes: { concurrent: 200, max_ttl: 60m }
  spend: { monthly_usd: 40000 }
cost_center: research-llm
Base URL
api.fantasti.ai/v1answers with the first cohort
Authentication
Bearer $FANTASTI_API_KEY
Interfaces
Python · CLI · REST · MCP
Stage
Preview API · subject to change
§01 One client 17 products · one key

Install, authenticate, place.

One Python package and one API key reach every product on the platform. Three lines take you from an empty environment to a placed instance.

  1. 01 Install The SDK and the CLI are published when the first cohort opens.
  2. 02 Authenticate The client reads FANTASTI_API_KEY.
  3. 03 Place The call returns an id while the request is placed.
Quick start Python
Three lines to a placed instance. Illustrative.

Three steps. One: a terminal sets FANTASTI_API_KEY, and one package serves every product. Two: Python imports fantasti and makes one client, which reads that key. Three: the client asks for one H100 and gets an id back at once, while the Fantasti Orchestrator places the request. The instance that comes back reports its status, region, capacity mode and rate. Connections: Install to Authenticate; Authenticate to Place; Place to ins_8f2a…: placed.

  • 01TerminalInstall
    $ export FANTASTI_API_KEY=…
    package
    one, for every product
    published
    with the first cohort
  • 02PythonAuthenticate
    import fantastifx = fantasti.Client()
    reads
    FANTASTI_API_KEY
  • 03PythonPlace
    ins = fx.instances.create(gpu="H100:1")
    returns
    ins_8f2a… placing
    ins.wait("ready")
  • Instanceins_8f2a… (highlighted)
    status
    ready
    region
    us-east
    capacity
    on_demand
    rate
    catalog rate
  • 01TerminalInstall
    $ export FANTASTI_API_KEY=…
    package
    one, for every product
    published
    with the first cohort
  • 02PythonAuthenticate
    import fantastifx = fantasti.Client()
    reads
    FANTASTI_API_KEY
  • 03PythonPlace
    ins = fx.instances.create(gpu="H100:1")
    returns
    ins_8f2a… placing
    ins.wait("ready")
  • Instanceins_8f2a… (highlighted)
    status
    ready
    region
    us-east
    capacity
    on_demand
    rate
    catalog rate
  • What the call returns
  • In order
§02 Placement Illustrative

Every object reports where it was placed.

Region, fabric and rate. The Fantasti Orchestrator checks each request against your policy and places it on one fabric. The record lists every pool it considered and the constraint each one failed.

Request path 64 × H100 SXM5 · on-demand
How one request is placed. Illustrative.

A request (64 × H100 SXM5, InfiniBand · us-*, On-demand) enters the Fantasti Orchestrator and passes five policy gates: GPU, interconnect, region, capacity and price ceiling. Four pools are considered. us-east, fabric a: placed, 96 GPUs free. us-east, fabric b: passed over, only 32 free < 64. us-west: passed over, no infiniband. eu-west, fabric a: passed over, region not allowed. The request runs as a node. Connections: Orchestrator to us-east · fabric b; Orchestrator to us-west; Orchestrator to eu-west · fabric a; us-east · fabric a to Sandbox; us-east · fabric a to Batch worker; fx.clusters.create to Orchestrator; Orchestrator to us-east · fabric a; us-east · fabric a to Node.

  • Requestfx.clusters.create
    64 × H100 SXM5InfiniBand · us-*On-demand
  • OrchestratorPolicy gates
    GPU
    H100 SXM5 × 64
    interconnect
    infiniband
    region
    us-*
    capacity
    on_demand
    price ceiling
    catalog rate
  • us-east · fabric a (highlighted)
    free 96asked 64
    Placed
  • us-east · fabric b
    free 32asked 64
    32 free < 64
  • us-west
    free 64asked 64
    No InfiniBand
  • eu-west · fabric a
    free 128asked 64
    Region not allowed
  • Node (done)

    A virtual machine

  • Sandbox
  • Batch worker
Consideredand passed over
  • Requestfx.clusters.create
    64 × H100 SXM5InfiniBand · us-*On-demand
  • OrchestratorPolicy gates
    GPU
    H100 SXM5 × 64
    interconnect
    infiniband
    region
    us-*
    capacity
    on_demand
    price ceiling
    catalog rate
  • us-east · fabric a (highlighted)
    free 96asked 64
    Placed
  • us-east · fabric b
    free 32asked 64
    32 free < 64
  • us-west
    free 64asked 64
    No InfiniBand
  • eu-west · fabric a
    free 128asked 64
    Region not allowed
  • Node (done)

    A virtual machine

  • Sandbox
  • Batch worker
Considered and passed over
  • Requestfx.clusters.create
    64 × H100 SXM5InfiniBand · us-*On-demand
  • OrchestratorPolicy gates
    GPU
    H100 SXM5 × 64
    interconnect
    infiniband
    region
    us-*
    capacity
    on_demand
    price ceiling
    catalog rate
  • us-east · fabric a (highlighted)
    free 96asked 64
    Placed
  • us-east · fabric b
    free 32asked 64
    32 free < 64
  • us-west
    free 64asked 64
    No InfiniBand
  • eu-west · fabric a
    free 128asked 64
    Region not allowed
  • Node (done)

    A virtual machine

  • Sandbox
  • Batch worker
  • This request
  • Passed over
CLI
Output · illustrative
$ fantasti explain cl_3m7q

Output · illustrative

request   64 × H100 SXM5 · InfiniBand · us-* · on-demand
pool-a    us-east · InfiniBand · 96 free     placed
pool-b    us-east · InfiniBand · 32 free     ✕ 32 free < 64
pool-c    us-west · no InfiniBand            ✕ no InfiniBand
pool-d    eu-west · InfiniBand · 128 free    ✕ region not allowed
price     on-demand · catalog rate

The same decision, as a record.

fantasti explain prints why a request landed where it did. An object's placement field carries the result.

  • Regioninside the regions your policy allows
  • Fabricone InfiniBand fabric for a multi-node job
  • Ratethe catalog rate, the spot price or the rate in your order form
  • Capacity modeon-demand, spot or reserved
How capacity is placed
§03 Objects and states 15 objects · 4 lifecycles

Objects and their states.

TAB 01Objects Source · Fantasti Reviewed 2026-10-10
Objects of the Fantasti API: id prefix, the call that makes each one, its REST line and the page that explains it
Object Id Made with REST Explained on
Placed by the Orchestrator08
Instance Compute ins_ fx.instances.create() POST /v1/instances POST /v1/instances Compute
Cluster GPU Clusters cl_ fx.clusters.create() POST /v1/clusters POST /v1/clusters GPU Clusters
Workspace Early access Workspaces ws_ fx.workspaces.create() POST /v1/workspaces POST /v1/workspaces Workspaces
Sandbox Early access Sandboxes sb_ fx.sandboxes.create() POST /v1/sandboxes POST /v1/sandboxes Sandboxes
Job Early access Serverless job_ fx.jobs.create() POST /v1/jobs POST /v1/jobs Serverless
Endpoint Early access Serverless ep_ fx.endpoints.create() POST /v1/endpoints POST /v1/endpoints Serverless
Batch run Batch Inference bat_ fx.batch.create() POST /v1/batch POST /v1/batch Batch Inference
Flow run Planned Flows run_ python flow.py run POST /v1/flows/{flow}/runs POST /v1/flows/{flow}/runs Flows
Storage and network03
Filesystem Storage fs_ fx.storage.filesystems.create() POST /v1/storage/filesystems POST /v1/storage/filesystems Storage
Bucket Storage name fx.storage.buckets.create() POST /v1/storage/buckets POST /v1/storage/buckets Storage
Network Networking name fx.networks.create() POST /v1/networks POST /v1/networks Networking
Account and records04
Reservation By request Reservations rsv_ A signed order form GET /v1/reservations/{id} GET /v1/reservations/{id} Reservations
Decision Agents dec_ Written for every decision GET /v1/decisions GET /v1/decisions Agents
Case Early access Support case_ fx.support.cases.create() POST /v1/support/cases POST /v1/support/cases Support
Preview Planned Previews slug fx.previews.join() POST /v1/previews/{slug}/join POST /v1/previews/{slug}/join Previews
TAB 02States Source · Fantasti Reviewed 2026-10-10
States of an instance, a sandbox, a batch run and a reservation, in order, and what ends each one
Object States, in order Ends when
Instance
  1. placing
  2. booting
  3. ready (in service)
  4. released (end)

Ends whenYou release it, or its reservation ends.

You release it, or its reservation ends.
Sandbox
  1. placing
  2. booting
  3. ready (in service)
  4. expired (end)

or deleted

Ends whenIts TTL or idle timeout passes, or you delete it.

Its TTL or idle timeout passes, or you delete it.
Batch run
  1. queued
  2. placed
  3. running (in service)
  4. done (end)

on spot stopped_priceorstopped_reclaimed then resuming

Ends whenThe last item completes, or retries run out (failed).

The last item completes, or retries run out (failed).
Reservation
  1. pending
  2. accepted
  3. active (in service)
  4. ended (end)

Ends whenThe term ends.

The term ends.

In service End state

TAB 03Spot states Source · Fantasti Reviewed 2026-10-10
The states an object reports on spot capacity, what each means and what compute is charged in it
State Meaning Compute charge
blocked Your max price is below the current spot price. Nothing has started. Compute chargeNone None
placing Capacity at your price is being placed. Compute chargeNone None
running Nodes are up. Compute chargeSpot price for each interval Spot price for each interval
stopping Stop notice sent. 60 seconds to exit. Compute chargeSpot price until the node stops Spot price until the node stops
stopped_price The spot price rose above your max. Disks are kept. Compute chargeNone. Storage continues. None. Storage continues.
stopped_reclaimed The capacity was reclaimed. Disks are kept. Compute chargeNone. Storage continues. None. Storage continues.
resuming Capacity at your price is back. Work restarts from its checkpoint. Compute chargeNone until running None until running

Compute is charged On spot capacity an object reports one of these states. How spot works

Sheet
01 / 02
Title
API objects and states
Objects
15
Reviewed
2026-10-10
EQ One of each Every product

1 client

1 key

1 error model

Shared by every product
EQ 01 Source · Fantasti API, preview Reviewed 2026-10-10
§04 Interfaces 4 interfaces

The same objects, ids and limits.

Python, REST, a CLI and an MCP server sit over one API. Use the one your code, or your agent, already speaks.

One request 1 × L40S · 15 minutes
One call, four interfaces. Illustrative.

Four interfaces send the same request, one sandbox on an L40S for fifteen minutes: the Python SDK calls fx.sandboxes.create, the command line runs fantasti sandbox create, REST posts to /v1/sandboxes and an agent calls the MCP tool sandboxes_create. All four reach the Fantasti API at api.fantasti.ai/v1 with one key and one error model, and the Fantasti Orchestrator places the request. One object comes back, sb_7q2m, with one id whichever interface asked. Connections: Python SDK to Fantasti API; CLI to Fantasti API; REST to Fantasti API; MCP server to Fantasti API; Fantasti API to sb_7q2m…: returns.

  • 01Python SDK
    sb = fx.sandboxes.create( gpu="L40S", ttl="15m")
    sync
    fantasti.Client
    async
    fantasti.AsyncClient
  • 02CLI
    $ fantasti sandbox create \ --gpu L40S --ttl 15m
    binary
    fantasti
    grammar
    <noun> <verb>
  • 03REST
    POST /v1/sandboxes{ "gpu": "L40S", "ttl": "15m" }
    body
    JSON over HTTPS
    auth
    Bearer $FANTASTI_API_KEY
  • 04MCP serverEarly access
    sandboxes_create{ "gpu": "L40S", "ttl": "15m" }
    wire
    Streamable HTTP
    tools
    12 in early access
  • Fantasti APIEvery interface
    host
    api.fantasti.ai/v1
    key
    one, for all four
    errors
    one model
    placed by
    Orchestrator
  • Sandboxsb_7q2m…Same id
    L40S · 1 GPU
    id
    sb_7q2m…
    status
    ready
    placement
    us-east · on_demand
    ttl
    15m
    policy
    team research
    concurrent
    200 sandboxes
    max_ttl
    60m

    One object, whichever interface asked. The idone of them returns is the id the other threeuse, and the same policy limits all four.

  • 01Python SDK
    sb = fx.sandboxes.create( gpu="L40S", ttl="15m")
    sync
    fantasti.Client
    async
    fantasti.AsyncClient
  • 02CLI
    $ fantasti sandbox create \ --gpu L40S --ttl 15m
    binary
    fantasti
    grammar
    <noun> <verb>
  • 03REST
    POST /v1/sandboxes{ "gpu": "L40S", "ttl": "15m" }
    body
    JSON over HTTPS
    auth
    Bearer $FANTASTI_API_KEY
  • 04MCP serverEarly access
    sandboxes_create{ "gpu": "L40S", "ttl": "15m" }
    wire
    Streamable HTTP
    tools
    12 in early access
  • Fantasti APIEvery interface
    host
    api.fantasti.ai/v1
    key
    one, for all four
    errors
    one model
    placed by
    Orchestrator
  • Sandboxsb_7q2m…Same id
    id
    sb_7q2m…
    status
    ready
    placement
    us-east · on_demand
    ttl
    15m
    policy
    team research
    concurrent
    200 sandboxes
    max_ttl
    60m

    One object, whichever interface asked. The id one of them returns is the id the other threeuse, and the same policy limits all four.

  • 01Python SDK
    sb = fx.sandboxes.create( gpu="L40S", ttl="15m")
    sync
    fantasti.Client
    async
    fantasti.AsyncClient
    to
    Fantasti API
  • 02CLI
    $ fantasti sandbox create \ --gpu L40S --ttl 15m
    binary
    fantasti
    grammar
    <noun> <verb>
    to
    Fantasti API
  • 03REST
    POST /v1/sandboxes{ "gpu": "L40S", "ttl": "15m" }
    body
    JSON over HTTPS
    auth
    Bearer $FANTASTI_API_KEY
    to
    Fantasti API
  • 04MCP serverEarly access
    sandboxes_create{ "gpu": "L40S", "ttl": "15m" }
    wire
    Streamable HTTP
    tools
    12 in early access
  • Fantasti APIEvery interface
    host
    api.fantasti.ai/v1
    key
    one, for all four
    errors
    one model
    placed by
    Orchestrator
  • Sandboxsb_7q2m…Same id
    id
    sb_7q2m…
    status
    ready
    placement
    us-east · on_demand
    ttl
    15m
    policy
    team research
    concurrent
    200 sandboxes
    max_ttl
    60m

    One object, whichever interface asked. Theid one of them returns is the id the otherthree use, and the same policy limits allfour.

  • One object, one id
  • What comes back
MCP server
§05 Conventions Preview API
Preview API · subject to change
curl -X POST https://api.fantasti.ai/v1/instances \
  -H "Authorization: Bearer $FANTASTI_API_KEY" \
  -H "Idempotency-Key: sft-0412-node" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "ft-01",
        "gpu": "H100:1",
        "capacity": { "mode": "spot", "max_price": "2.40",
                      "currency": "USD", "unit": "gpu_hour" },
        "labels": { "team": "research", "run": "sft-0412" },
        "placement_timeout": "15m"
      }'

Responses · illustrative

202   { "id": "ins_8f2a…", "status": "placing",
        "labels": { "team": "research", "run": "sft-0412" } }
 
200   { "id": "ins_8f2a…", "status": "ready",
        "placement": { "region": "us-east", "fabric": "a",
                       "capacity": "spot", "rate": "…" } }
import fantasti

fx = fantasti.Client()                          # reads FANTASTI_API_KEY

ins = fx.instances.create(
    name="ft-01",
    gpu="H100:1",
    capacity=fantasti.Spot(max_price=2.40),     # USD per GPU-hour
    labels={"team": "research", "run": "sft-0412"},
    idempotency_key="sft-0412-node",            # a retry returns the same object
    placement_timeout="15m",
)
ins.wait("ready")
print(ins.placement)                            # region, fabric, rate, capacity mode

for obj in fx.instances.list(labels={"run": "sft-0412"}):
    obj.release()                               # tear down the whole run

Conventions.

One request carries all six. The same rules hold for every object and every interface.

  • Authenticationa bearer token from FANTASTI_API_KEY
  • Idempotencyan Idempotency-Key header on every create, so retries are safe
  • Labelskey–value pairs on every object, used to list and tear down whole runs
  • Placementevery placed object reports region, fabric, capacity mode and rate
  • TimeUTC ISO 8601 timestamps; durations as "15m" or seconds
  • MoneyUSD as decimal strings ("2.40")
§06 Errors 5 conditions

Errors that say why.

TAB 04Errors Source · Fantasti Reviewed 2026-10-10
Error conditions of the Fantasti API and the response to each
Condition Status Code The response says
No pool can hold the request on one fabric The object stays placing until placement_timeout. The error then lists the closest pools and the constraint each failed. 409 no_capacity The object stays placing until placement_timeout. The error then lists the closest pools and the constraint each failed.
The request exceeds a quota, cap or price ceiling Names the policy and the limit. 403 policy_denied Names the policy and the limit.
A max price stays below the spot price past placement_timeout Until then the object reports blocked. Nothing has started. 409 spot_price_above_max Until then the object reports blocked. Nothing has started.
The same Idempotency-Key with a different body 422 idempotency_conflict
Missing or invalid key 401 unauthorized
LOG 01A 409 in full Illustrative
Preview API · subject to change
{
  "error": {
    "status": 409,
    "code": "no_capacity",
    "request": { "gpu": "H100:8", "nodes": 16, "fabric": "infiniband" },
    "closest": [
      { "pool": "pool-a", "region": "us-east", "failed": "96 free < 128" },
      { "pool": "pool-b", "region": "us-east", "failed": "32 free < 128" },
      { "pool": "pool-c", "region": "us-west", "failed": "no InfiniBand" },
      { "pool": "pool-d", "region": "eu-west", "failed": "region not allowed" }
    ]
  }
}
$ fantasti cluster create big-run --gpu H100:8 --nodes 16 --on-demand

Output · illustrative

error     409 no_capacity
request   128 × H100 SXM5 · InfiniBand · us-* · on-demand
pool-a    us-east · InfiniBand · 96 free     ✕ 96 free < 128
pool-b    us-east · InfiniBand · 32 free     ✕ 32 free < 128
pool-c    us-west · no InfiniBand            ✕ no InfiniBand
pool-d    eu-west · InfiniBand · 128 free    ✕ region not allowed
Sheet
02 / 02
Title
API errors
Conditions
5
Reviewed
2026-10-10
§07 MCP Early access

The Fantasti API as tools for AI agents.

A remote MCP server that gives AI agents the Fantasti API as tools, inside the limits your admins set.

  • Sign-inOAuth when a person is present, a scoped agent key when the agent runs alone
  • Limitsquotas, spend caps and price ceilings apply to agents as they apply to people
Preview API · subject to change
{
  "mcpServers": {
    "fantasti": {
      "type": "http",
      "url": "https://mcp.fantasti.ai/mcp"
    }
  }
}
{
  "mcpServers": {
    "fantasti": {
      "type": "http",
      "url": "https://mcp.fantasti.ai/mcp?features=sandboxes,jobs&project=evals",
      "headers": { "Authorization": "Bearer ${FANTASTI_AGENT_KEY}" }
    }
  }
}

Tool groups 12 tools in early access · 25 planned

Early access
  • catalog 1 tool
  • sandboxes 5 tools
  • workspaces 3 tools
  • jobs 2 tools
  • usage 1 tool
Planned
  • batch 3 tools
  • flows 6 tools
  • broker 3 tools
  • quota 2 tools
  • clusters 4 tools
  • records 3 tools
  • support 3 tools
  • changelog 1 tool