zeroruntime.serve(...), it opens an outbound connection to the
runtime and registers your agent under the id in ZERORUNTIME_AGENT_ID. The runtime then
dispatches sessions for that id to every registered worker and load-balances across them.
The CLI commands under Operate (
up, version, secrets,
logs, down) manage workers on Zero Runtime Cloud. They don’t apply here; use your own
platform for rollouts, secrets, scaling, and logs.Prerequisites
- An agent project whose
main.pycallszeroruntime.serve(...). Every quickstart example does. - Docker on the machine that builds the image (and on the host that runs it, for Docker).
- For Kubernetes: a cluster,
kubectlconfigured for it, and a container registry the cluster can pull from. - Your auth token from the Zero Runtime dashboard.
Choose an agent ID
On Zero Runtime Cloud, the platform assigns the agent ID for you. When you self-host, you choose it and set it asZERORUNTIME_AGENT_ID. The worker registers under this ID,
and everything that reaches your agent targets it: zeroruntime invoke --agent-id, the
dispatch API, and telephony routing rules.
Pick an ID that is:
- Unique: don’t reuse it for a different agent. Workers that share an ID receive each other’s sessions.
- Stable: a fixed name like
support-agent, not a random value generated per run or per container. Every replica of the same agent uses the same ID; that’s how the runtime load-balances across them.
Configure the environment
The worker reads its agent ID, connection details, and provider keys from environment variables. Create a.env file in your project folder. See
Authentication for the full list.
.env
.env to .dockerignore.
.dockerignore
Remove the local test invoke
For local testing, use theon_ready callback in serve() to start a playground session when the worker is ready. Remove it in production to avoid automatically creating a new room for every worker. In production, start sessions via zeroruntime invoke CLI, the dispatch API, or telephony routing rules.
Build the image
Use theDockerfile that zeroruntime init generates, or write your own. It should install
requirements.txt and run python main.py:
Dockerfile
Run the worker
- Docker
- Kubernetes
1
Start the container
Run the worker in the background, load your The worker only dials out to the runtime.
.env, and restart it if it exits:-p 8081:8081 is optional and only exposes
the health endpoint.2
Confirm it registered
Check the logs for a successful connection and registration under your agent ID:Then check the health endpoint:
3
Add more workers (optional)
To handle more concurrent sessions, start more containers with the same
Both workers register under the same agent ID, and the runtime balances sessions
across them.
.env. Use a unique container name and host port for each:4
Ship an update
Build a new tag, then replace the running container:
docker stop sends SIGTERM and waits 10 seconds by default. Raise it with
docker stop -t <seconds> if your sessions need longer to wrap up.Start a session
Self-hosted workers receive sessions the same way cloud workers do. Start one with the CLI, passing yourZERORUNTIME_AGENT_ID:
Connect telephony
To take or place phone calls, configure gateways and a routing rule that point at your agent. Use yourZERORUNTIME_AGENT_ID wherever an agent ID is required; it must match
exactly, or calls never reach your workers.
Set up inbound calls
Set up inbound calls
1. Create an inbound gateway: the entry point for incoming calls.2. Create a routing rule: connects the inbound gateway to your self-hosted agent.3. Test it: with your workers running, dial your provider’s phone number from any phone. The agent greets you as soon as the call connects.
- Dashboard
- API
- Copy the Inbound URL from the Zero Runtime dashboard.
- Go to Twilio and create a new SIP Trunk.
- Go to the Origination section, paste the Inbound URL there, and save it.
- Dashboard
- API
- From your inbound gateway, click Configure rule, then Create new routing rule.
- Enter a Routing Rule Name and select API Key authentication.
- Choose the Call Direction (Inbound).
- Enter the Phone Number and select a Room Type.
- Enter your
ZERORUNTIME_AGENT_IDas the Agent ID and click Save.
Set up outbound calls
Set up outbound calls
1. Create an outbound gateway: lets the agent dial out to the PSTN.2. Place a call: with your workers running, trigger a call from the agent. Replace
- Dashboard
- API
- In Twilio, open your SIP Trunk and go to the Termination section. Create a Termination URI and add username/password credentials.
- Back in the Zero Runtime Dashboard, open the outbound gateway configuration.
- Paste the Twilio Termination URI as the address, add the same username/password credentials, and save.
YOUR_ZERORUNTIME_AUTH_TOKEN and routingRuleId with your own.Operating self-hosted workers
- Capacity: each worker accepts up to
capacityconcurrent sessions (default10, set inzeroruntime.serve(...)or withZERORUNTIME_MAX_CONCURRENT_SESSIONS). Add workers or replicas when you need more. - Health: each worker serves
GET /healthon port8081for liveness probes. - Rolling updates: build a new image tag and roll it out with your platform’s usual deploy process.
- Credentials: rotate tokens and provider keys in your secret manager, then restart the workers so they pick up the new values.
- Logs: workers log to stdout and stderr. Collect them with your existing logging stack.
Troubleshooting
- Sessions or calls never arrive: the
agentIdininvoke, dispatch, or your routing rule doesn’t exactly matchZERORUNTIME_AGENT_ID, or the variable is unset and the worker registered aszeroruntime_agent. Check the worker logs for the ID it registered under. - Worker can’t connect: check
ZERORUNTIME_TARGETandZERORUNTIME_AUTH_TOKEN, and that outbound traffic to the runtime on port443is allowed. - Pods restart in a loop: check
kubectl logsfor a startup error, and raise the probe’sinitialDelaySecondsif the worker takes longer to start.