API Overview
Understand the current Apothic control plane, authentication model, and the recommended developer surfaces for apps, jobs, services, storage, and shared state.
API Overview
The main programmable Apothic surface today is the runtime control plane served from:
https://run.apothic.ai
Most users should access it through apothic-client, which provides a Python SDK and CLI for:
- deploying apps
- invoking functions
- watching jobs and deployments
- tailing deployment startup logs for services that expose
startup_log_tail - running HTTP services
- using stateful classes and sandboxes
- managing storage and secrets
- coordinating workers with queues and dictionaries
Recommended entry points
Choose the interface that matches your workflow:
- Python SDK for application code and automation
- CLI for deploy, inspect, watch, and cleanup workflows
- Dashboard for account, billing, and managed deployment flows
If you are building on the runtime directly, start with:
- Apothic Client API Reference
- Apothic Client Quickstart
- Apothic Client Functions and Jobs
- Apothic Client Services and Streaming
- Apothic Client Storage, Secrets, and Sandboxes
- Apothic Client Shared State and Coordination
- Apothic Client CLI and Operations
- Cloud Browser API Reference
Runtime architecture
The public runtime is the native Apothic control plane.
The important pieces are:
- Fly hosts the control-plane API
- SurrealDB stores deployments, functions, jobs, schedules, workers, secrets, volumes, and event rows
- on-demand workers execute user workloads and connect back to the runtime over outbound machine sessions
- storage is split across portable mounts and host-local fast paths rather than one universal bucket-only model
That architecture is why the API can expose one coherent resource surface while still supporting stateless jobs, long-lived services, stateful sandboxes, and host-affine vast_local storage.
Authentication
Runtime requests are authenticated with an Apothic account API key.
The most common setup is:
export APOTHIC_API_KEY=your_apothic_api_key
The current client/runtime stack also supports:
APOTHIC_AUTH_TOKENAPOTHIC_AUTH_HEADERAPOTHIC_BASE_URL
By default, apothic-client targets https://run.apothic.ai and automatically sends an Authorization: Bearer ... header when APOTHIC_API_KEY is set.
Account and billing model
Runtime usage is tied to your Apothic account.
That means:
- apps, deployments, and jobs are associated with the caller’s billing account
- runtime charges draw down from your Apothic balance
- you can add funds from the website billing dashboard before running billable workloads
For the current user-facing billing flow, see /dashboard/billing in the website.
Core resource types
The current runtime surface is organized around a few core primitives.
Apps and deployments
An App is the package you deploy. Each deploy creates a deployment record you can inspect, watch, stop, or delete later.
Typical operations include:
app.deploy()RemoteFunction.from_name(...)apothic app listapothic deployment inspect ...apothic deployment watch ... --snapshot
Functions and jobs
Use @app.function(...) for remote compute. You can:
- call it directly with
remote() - create a background job with
spawn() - stream typed execution events with
job.watch()orremote_events(...)
Services
Apothic also supports long-lived service shapes:
@app.endpoint(...)@app.asgi(...)@app.fastapi_endpoint(...)@app.wsgi_app()@app.web_server(...)
Classes and sandboxes
The runtime also supports persistent instance-style resources through:
@app.cls(...)app.sandbox(...)
These are useful when you need a sticky instance id, a persistent workspace, or repeated calls against one initialized resource.
Storage and secrets
The current runtime surface also includes:
- portable named volumes
- host-affine
vast_localvolumes - explicit
CloudBucketMount(...)specs for S3-compatible buckets - account-scoped secrets
Shared coordination
The runtime exposes named shared primitives:
QueueDict
They support:
- blocking reads
- watch streams
- claims, acknowledgements, renewals, and releases
- key leases
- compare-and-set updates
- locks and leader election
Placement and capacity filters
The client and runtime support two ways to describe capacity requirements.
The convenience path uses fields such as:
gpugpu_countmin_vram_gbgeolocationmax_cost_per_hour_usddisk_gbservice_startup_timeout_s
The flexible path uses offer_filters, which accepts structured comparison operators:
eqneqgtltgtelteinnotin
That means you can express ranges and richer capacity filters without waiting for the SDK to grow one-off named parameters for every metadata field.
Apothic Client reference section
The site now also includes a dedicated apothic-client reference section for signatures and method-level lookup:
- Apothic Client API Reference
- App and Decorators Reference
- Functions and Jobs Reference
- Image Reference
- Storage and Secrets Reference
- Classes and Sandboxes Reference
- Queues and Dicts Reference
- Liv Reference
Event streams and watches
The current control plane is stream-oriented in a few important places.
You can watch:
- jobs
- apps
- deployments
- queues
- dictionaries
Snapshot-aware watch flows are available in both the SDK and CLI, which makes it easier to build dashboards, operators, and automation that reacts to live state.
Generated functions
apothic-client also supports generated implementations through @apothic.liv(...) and LivConfig.
The currently supported mode is deploy-time freeze, which means:
- the generated implementation is materialized before deploy
- the generated module is packaged into the app archive
- the remote runtime executes the frozen result as normal Python
CLI example
apothic deploy app.py
apothic run infer --app-name demo --payload '{"args":["hello"],"kwargs":{}}' --watch
apothic logs jobs:123
apothic deployment logs deployments:123
apothic deployment watch deployments:123 --snapshot
apothic queue watch image-jobs --snapshot
Python example
from apothic import App, RemoteFunction
app = App("hello-world")
@app.function(cpu=1, memory_mb=512, timeout_s=60)
def greet(name: str) -> str:
return f"hello, {name}"
deployment_id = app.deploy()
remote = RemoteFunction.from_name("hello-world", "greet")
print(deployment_id)
print(remote.remote("world"))
