Private Agents & Join Keys
Enroll your own backend agents, manage join keys, and monitor your private fleet.
Overview
Private agents (XIM nodes) are your own hardware enrolled in your Xerotier project using join keys. They give you full control over your inference infrastructure while using Xerotier for routing, monitoring, and management.
For a comparison of private agents vs. shared agents, see the Agent Types overview page.
This page covers the practical steps: creating join keys, enrolling agents, monitoring your fleet, and managing agent lifecycle.
Join Key Management
Join keys are secure tokens that authorize a backend agent to enroll in your project. Each key is tied to a specific project and can be revoked at any time.
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/projects/:projectId/join-keys | Create a new join key. |
| GET | /api/v1/projects/:projectId/join-keys | List all join keys for the project. |
| GET | /api/v1/projects/:projectId/join-keys/:keyId | Get join key details. |
| DELETE | /api/v1/projects/:projectId/join-keys/:keyId | Revoke a join key. Agents already enrolled are not affected. |
Join Key API Examples
Create a Join Key
curl -X POST https://xerotier.ai/api/v1/projects/PROJECT_ID/join-keys \
-H "Authorization: Bearer xero_my-project_abc123" \
-H "Content-Type: application/json" \
-d '{"region": "us-east-1", "expires_in_hours": 24}'
import requests
headers = {
"Authorization": "Bearer xero_my-project_abc123",
"Content-Type": "application/json"
}
response = requests.post(
"https://xerotier.ai/api/v1/projects/PROJECT_ID/join-keys",
headers=headers,
json={"region": "us-east-1", "expires_in_hours": 24}
)
join_key = response.json()
print(f"Join Key: {join_key['key']}")
const response = await fetch(
"https://xerotier.ai/api/v1/projects/PROJECT_ID/join-keys",
{
method: "POST",
headers: {
"Authorization": "Bearer xero_my-project_abc123",
"Content-Type": "application/json"
},
body: JSON.stringify({
region: "us-east-1",
expires_in_hours: 24
})
}
);
const joinKey = await response.json();
console.log(`Join Key: ${joinKey.key}`);
List Join Keys
curl https://xerotier.ai/api/v1/projects/PROJECT_ID/join-keys \
-H "Authorization: Bearer xero_my-project_abc123"
Agent Enrollment
To enroll a private agent:
- Create a join key in the dashboard or via the API.
- Run the agent with the
enrollsubcommand using the join key. - The agent authenticates with the router and establishes a secure encrypted connection.
- The agent begins sending heartbeats and is ready to receive inference requests.
# Enroll a XIM node
xeroctl-agent enroll --join-key "eyJhbGciOiJI..."
# Or using the environment variable
XEROTIER_AGENT_JOIN_KEY="eyJhbGciOiJI..." xeroctl-agent enroll
After enrollment, start the agent in serve mode to begin handling inference requests. See the XIM Deployment guide for detailed setup instructions.
Agent Monitoring
The agent dashboard at /agents provides real-time visibility
into your enrolled agents:
- Heartbeat status -- Whether each agent is actively communicating with the router.
- Current load -- Active request count and capacity.
- Model information -- Which model is loaded and its status.
- Event history -- Per-agent log of significant events.
Real-Time Streaming
The dashboard uses Server-Sent Events (SSE) at /agents/stream
for real-time metric updates. A JSON API at /agents/api
provides the same data as a point-in-time snapshot for programmatic access.
Agent Management
| Method | Endpoint | Description |
|---|---|---|
| PATCH | /api/v1/projects/:projectId/agents/:agentId | Update agent labels or metadata. |
| DELETE | /api/v1/projects/:projectId/agents/:agentId | Remove an agent from the project. |
| GET | /api/v1/projects/:projectId/agents/:agentId/events | Retrieve the event log for a specific agent. |
Agent Lifecycle
Agents transition through these status states:
| Status | Description |
|---|---|
| Online | Agent is sending regular heartbeats and is available for requests. |
| Offline | Agent has not sent a heartbeat recently but may reconnect. |
| Dead | Agent has been offline for an extended period. It will not receive new requests until it reconnects and resumes heartbeats. |
The router considers an agent stale if no heartbeat has been received recently. Stale agents are excluded from routing decisions until they reconnect and resume sending heartbeats.
Single-Agent Queuing
When only one agent is available for an endpoint's tier, the router queues incoming requests instead of immediately returning a 503 error. This is particularly relevant for XIM deployments with a single backend agent.
The queue timeout defaults to 30 seconds. If the agent does not become available within the timeout, the request fails with a timeout error.