Start Here
API Quickstart
Create an inference credential and make your first request to api.actual.inc
Use the public inference API after a model is loaded on an online computer with Private Relay connected. Model installation and loading happen through the CLI or website.
Prepare the computer and credential#
Follow Getting Started, then verify actual status, actual models list, and actual relay status on the serving computer. Use actual relay on if relay is disabled, and wait for connection and model readiness.
Create an ac_ inference credential in User > Keys; see API Credentials if that flow is unavailable. Set ACTUAL_API_KEY in your shell environment without committing it to a file or sharing it in logs.
The shell examples use Bash, curl, and jq. Set the API base:
export ACTUAL_API_BASE="https://api.actual.inc"
1. Discover models and cluster IDs#
curl --fail-with-body --silent --show-error "$ACTUAL_API_BASE/v1/models" \
-H "Authorization: Bearer $ACTUAL_API_KEY"
Without a cluster header, inventory spans your account's online clusters. The following response is illustrative; use the IDs actually returned to you:
{
"object": "list",
"data": [
{
"id": "Gemma 4 12B IT",
"object": "model",
"created": 1700000000,
"owned_by": "actual",
"selector": "mdl_a81e2d366803a648",
"display_name": "Gemma 4 12B IT",
"loaded": true,
"clusters": [
{ "cluster_id": "cl_example", "loaded": true }
]
}
]
}
Choose a returned id or selector, and a clusters[].cluster_id where that model has loaded: true. Replace both example values below:
export ACTUAL_MODEL="mdl_a81e2d366803a648"
export ACTUAL_CLUSTER_ID="cl_example"
For a cluster roster, use actual clusters --format json on an authenticated computer. The public inference API does not provide cluster-management or model-loading routes.
If the inventory is empty, restore the computer's connection and install a model. If a model is available but not loaded, load it with actual models load or the Chat model picker, then query inventory again.
2. Check the chosen cluster#
curl --fail-with-body --silent --show-error "$ACTUAL_API_BASE/v1/models" \
-H "Authorization: Bearer $ACTUAL_API_KEY" \
-H "X-Cluster-ID: $ACTUAL_CLUSTER_ID"
The X-Cluster-ID header pins inventory and inference to that cluster. Without it, inference selects an eligible online node with the requested model loaded and the required capabilities; it does not simply choose the first online cluster.
3. Send a response request#
jq -n --arg model "$ACTUAL_MODEL" \
'{model: $model, input: "Say hello.", max_output_tokens: 128}' |
curl --fail-with-body --silent --show-error "$ACTUAL_API_BASE/v1/responses" \
-H "Authorization: Bearer $ACTUAL_API_KEY" \
-H "X-Cluster-ID: $ACTUAL_CLUSTER_ID" \
-H "Content-Type: application/json" \
--data-binary @-
Using jq ensures the model selector is encoded as JSON rather than interpolated unsafely into a request string.
4. Or use Chat Completions#
jq -n --arg model "$ACTUAL_MODEL" \
'{model: $model, messages: [{role: "user", content: "Say hello."}], max_tokens: 128}' |
curl --fail-with-body --silent --show-error "$ACTUAL_API_BASE/v1/chat/completions" \
-H "Authorization: Bearer $ACTUAL_API_KEY" \
-H "X-Cluster-ID: $ACTUAL_CLUSTER_ID" \
-H "Content-Type: application/json" \
--data-binary @-
For streaming, add stream: true to the JSON and --no-buffer to curl. See API Reference for response shapes, SSE, and tool use.
Connect an application#
For applications that accept an OpenAI-compatible provider, configure the base URL as https://api.actual.inc/v1, provide the inference credential, and select the model ID returned by inventory. Set X-Cluster-ID if the application supports custom headers and you want a specific cluster.
For local access, read api.url from actual status --format json on the serving computer. The default port is not guaranteed. See Private Relay.
Troubleshooting#
| Result | Next check |
|---|---|
| 401 | Missing, invalid, expired, or revoked credential. Inspect the response body and replace or recreate the credential. |
| Empty model list | Computer connection, model installation, account, and selected cluster. |
| Model listed but not loaded | Load it through the CLI or website and wait for readiness. |
| 503 or no eligible node | Relay connection, loaded model, selected cluster, and requested capabilities. |
| 404 | Base URL and supported route; the inference API does not manage model loading. |
| Request fails after a device disconnects | Refresh inventory and wait for a suitable node to return. |
Error bodies can be plain text or JSON. Inspect the HTTP status and content type before parsing. Authenticated end-to-end success means a response came from the intended loaded model, not merely that inventory returned 200.