Companions API¶
The Companions API orchestrates multi-persona LLM modes — a single answer, several answers in parallel, an expert panel, or a moderated discussion — behind one simple REST interface. You send a prompt and a mode; the platform runs the personas, bills the exact provider cost, and returns a typed result.
How it works¶
Every run is asynchronous. A run-producing request (like POST /v1/completion) returns immediately with a job envelope — an id of the form job-<uuid> and a pending status. You then read the result from the unified /v1/jobs/{id} surface, either by polling or by subscribing to a live event stream.
POST /v1/completion ──► { "id": "job-abc…", "status": "pending" }
│
GET /v1/jobs/job-abc… ◄────────────┘ poll until status is terminal
or
GET /v1/jobs/job-abc…/stream subscribe (Server-Sent Events)
This one envelope (JobStatus) is returned by every run-producing endpoint, so a client learns the shape once and reuses it everywhere.
Quickstart¶
# 1. Enqueue a single-persona answer.
curl https://api.humx.ai/v1/completion \
-H "Authorization: ApiKey $COMPANIONS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "Explain rate limiting to a new engineer.", "mode": "answer" }'
# → { "id": "job-1a2b...", "status": "pending" }
# 2. Poll the job until it is complete.
curl https://api.humx.ai/v1/jobs/job-1a2b... \
-H "Authorization: ApiKey $COMPANIONS_API_KEY"
# → { "status": "complete", "content": { "shape": "answer", "response": "..." } }
import os, time, requests
headers = {"Authorization": f"ApiKey {os.environ['COMPANIONS_API_KEY']}"}
# 1. Enqueue a run.
job = requests.post(
"https://api.humx.ai/v1/completion",
headers=headers,
json={"prompt": "Explain rate limiting to a new engineer.", "mode": "answer"},
).json()
# 2. Poll until it finishes.
while job["status"] not in ("complete", "failed"):
time.sleep(1.0)
job = requests.get(f"https://api.humx.ai/v1/jobs/{job['id']}", headers=headers).json()
print(job["content"]["response"])
const headers = {
Authorization: `ApiKey ${process.env.COMPANIONS_API_KEY}`,
"Content-Type": "application/json",
};
// 1. Enqueue a run.
let job = await (await fetch("https://api.humx.ai/v1/completion", {
method: "POST",
headers,
body: JSON.stringify({ prompt: "Explain rate limiting to a new engineer.", mode: "answer" }),
})).json();
// 2. Poll until it finishes.
while (!["complete", "failed"].includes(job.status)) {
await new Promise((r) => setTimeout(r, 1000));
job = await (await fetch(`https://api.humx.ai/v1/jobs/${job.id}`, { headers })).json();
}
console.log(job.content.response);
const headers = {
Authorization: `ApiKey ${process.env.COMPANIONS_API_KEY!}`,
"Content-Type": "application/json",
};
// 1. Enqueue a run.
let job = await (await fetch("https://api.humx.ai/v1/completion", {
method: "POST",
headers,
body: JSON.stringify({ prompt: "Explain rate limiting to a new engineer.", mode: "answer" }),
})).json();
// 2. Poll until it finishes.
while (!["complete", "failed"].includes(job.status)) {
await new Promise((r) => setTimeout(r, 1000));
job = await (await fetch(`https://api.humx.ai/v1/jobs/${job.id}`, { headers })).json();
}
console.log(job.content.response);
See Authentication to mint a key, then Completion for the full request shape.
Reference¶
| Resource | What it does |
|---|---|
| Completion | Enqueue an engine run — one answer, parallel answers, a panel, or a discussion. |
| Jobs | Poll or stream any run, and return client-side tool outputs. |
| Models | List the model slugs you may select, with their parameter ranges. |
| Discover | One read of every team and companion you can use. |
| Billing | Read your balance and the transaction ledger. |
| Account | Manage your profile, usage history, API keys, and integrations. |
Errors¶
The API uses conventional HTTP status codes.
| Status | Meaning |
|---|---|
200 | Success. |
204 | Success, no body (e.g. a delete). |
401 | Missing or invalid credentials. |
402 | Insufficient balance to run. |
403 | Authenticated, but not allowed. |
404 | No such resource (or not yours). |
409 | Conflict (e.g. a resource limit reached). |
422 | The request body failed validation — the response lists each offending field. |
A 422 body follows FastAPI's detail convention: a list of entries, each naming the field (loc), a machine-readable type, and a human msg.