Inference API — models, no agent
Fireworks-style access to our catalog (and your BYO endpoints). Mint a nxi_… key under Dashboard → APIs, then call chat completions.
- 01Generate an inference key on Dashboard → APIs. Shown once — store it safely.
- 02Optionally list models to pick a catalog id (or omit
modelfor the default). - 03POST to
/v1/chat/completionswith the key as a bearer token.
POST /v1/chat/completions
Authorization: Bearer nxi_…
Content-Type: application/jsonmodelstring
Catalog model id from
GET /v1/models, or the id of one of your BYO custom models. Omit to use the platform default.messagesarray
{ role, content }with rolessystem,user, orassistant. Exactly one ofmessages/messageis required.messagestring
Single user message shortcut (also accepts
input).streamboolean
When
true, respond with Server-Sent Events.temperaturenumber
Sampling temperature for this call.
max_tokensnumber
Cap on completion length for this call.
cURL
curl https://api.nexpher.ai/v1/chat/completions \
-H "Authorization: Bearer nxi_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "deepinfra/meta-llama-3.1-8b-instruct",
"messages": [{"role": "user", "content": "Give me a one-line pitch for my app."}]
}'OpenAI Python SDK
from openai import OpenAI
client = OpenAI(
base_url="https://api.nexpher.ai/v1",
api_key="nxi_your_key_here",
)
reply = client.chat.completions.create(
model="deepinfra/meta-llama-3.1-8b-instruct",
messages=[{"role": "user", "content": "Hello!"}],
)
print(reply.choices[0].message.content)Responses follow OpenAI's chat.completion schema — LangChain, Vercel AI SDK, and similar tools work unmodified.
List models
GET /v1/models
Authorization: Bearer nxi_…Returns the platform catalog plus your registered BYO custom models (owned by the key's account). Use a catalog id or a custom model id as model in completions. BYO runs use your endpoint and do not burn Nexpher inference tokens.
{
"object": "list",
"default": "deepinfra/meta-llama-3.1-8b-instruct",
"data": [
{
"id": "deepinfra/meta-llama-3.1-8b-instruct",
"object": "model",
"owned_by": "deepinfra",
"label": "Llama 3.1 8B Instruct"
}
]
}Agent API — trained assistants
When you need a fixed system prompt, marketplace listing, or fine-tuned behavior, bind a nxa_… key to an agent.
- 01Create an agent in the builder. Copy its Agent ID from My Agents.
- 02Generate a per-agent key under Dashboard → APIs.
- 03Call
/v1/agents/:agentId/chat.
POST /v1/agents/:agentId/chat
Authorization: Bearer nxa_…
Content-Type: application/jsonmessagestring
Single user message. Exactly one of
message/messagesis required (inputis accepted as an alias).messagesarray
{ role, content }objects. The agent's system prompt is always applied first.streamboolean
When
true, respond with Server-Sent Events.temperaturenumber
Defaults to the temperature saved on the agent.
max_tokensnumber
Cap on completion length for this call.
from openai import OpenAI
client = OpenAI(
base_url="https://api.nexpher.ai/v1/agents/<AGENT_ID>",
api_key="nxa_your_key_here",
)
reply = client.chat.completions.create(
model="nexpher-agent", # ignored – the key selects the agent
messages=[{"role": "user", "content": "Hello!"}],
)
print(reply.choices[0].message.content)Streaming
Set "stream": true on either endpoint. The response is text/event-stream with OpenAI-style chat.completion.chunk payloads, ending with data: [DONE].
const res = await fetch("https://api.nexpher.ai/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer nxi_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "deepinfra/meta-llama-3.1-8b-instruct",
messages: [{ role: "user", content: "Hello" }],
stream: true,
}),
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() ?? "";
for (const line of lines) {
if (!line.startsWith("data: ") || line === "data: [DONE]") continue;
const delta = JSON.parse(line.slice(6)).choices[0].delta;
if (delta.content) appendToUI(delta.content);
}
}Errors
Errors return the matching HTTP status with an OpenAI-style body:
{ "error": { "message": "Invalid or disabled API key", "type": "invalid_request_error", "code": 401 } }| Status | Type | When it happens |
|---|---|---|
| 400 | invalid_request_error | Malformed body, empty message, or missing model configuration. |
| 401 | invalid_request_error | Missing/malformed key, or the key was disabled or deleted. |
| 402 | insufficient_quota | Your plan (or the agent's billing target) is out of tokens. Upgrade or buy a pack. |
| 404 | invalid_request_error | Agent doesn't exist or an agent key isn't bound to that agent. |
| 429 | rate_limit_error | Too many requests for this key in a rolling minute. Back off and retry. |
| 502 | api_error | The upstream model provider failed. Safe to retry with backoff. |
Managing keys
Key management uses your logged-in session (Dashboard → APIs). Two key types:
nxi_…— Inference API (account-scoped, any catalog / BYO model)nxa_…— Agent API (bound to one agent)
Inference keys
GET /inference-api-keys
POST /inference-api-keys { "name": "Production" }
# → returns { …, "apiKey": "nxi_…" } once
GET /inference-api-keys/:id/usage
PATCH /inference-api-keys/:id { "name": "…", "enabled": false }
DELETE /inference-api-keys/:idAgent keys
GET /agent-api-keys
POST /agent-api-keys { "agentId": "…", "name": "Production" }
# → returns { …, "apiKey": "nxa_…" } once
GET /agent-api-keys/:id/usage
PATCH /agent-api-keys/:id { "name": "…", "enabled": false }
DELETE /agent-api-keys/:id- Raw keys are stored only as SHA-256 hashes — we can't recover a lost key, only issue a new one.
- Disabling a key takes effect immediately; requests fail with 401 until re-enabled.
- Inference plan limits: Free 1 · Starter 3 · Pro/Scale unlimited.
- Agent plan limits: Free 1 · Starter 2 · Pro/Scale unlimited (keyed to that agent's billing plan).
Rate limits: each API key allows up to 30 requests per minute by default. Responses include X-RateLimit-Limit and X-RateLimit-Remaining.
Webhooks
Register an HTTPS endpoint and we'll POST signed JSON when things happen. Manage endpoints from Dashboard → APIs → Webhooks.
{
"id": "evt_9f31c0a2b7d4e5f6a7b8",
"event": "finetune.succeeded",
"created": "2026-08-24T09:41:07.000Z",
"data": {
"jobId": "…",
"agentId": "…",
"displayName": "math-tutor-ft",
"baseModel": "…",
"outputModelId": "nexpher/ft/math-tutor"
}
}| Event | Fires when |
|---|---|
| finetune.succeeded | A training job finishes successfully; outputModelId is ready to use. |
| finetune.failed | A training job fails; data.error explains why. |
| wallet.topup | A wallet top-up completes. |
| wallet.payout | A creator payout is sent. |
Verifying signatures
Every delivery carries a Nexpher-Signature header of the form t=<unix>,v1=<hex> where hex is HMAC-SHA256 over "<t>.<raw body>" using your endpoint's signing secret.
Quotas & billing
- Inference API calls draw from your personal monthly token allowance — same pool as Chat in the app.
- Agent API calls follow that agent's billing target (you, the team owner, or a shared team plan).
- When the allowance runs out the endpoint answers 402 insufficient_quota.
- BYO / custom models route through your registered endpoint and don't consume Nexpher inference budget.
Building something cool?
Start with the Inference API for raw models, then wrap a trained agent when you need a fixed personality or marketplace listing.
Start freeWas this page helpful?
