Agent API — trained assistants
When you need a fixed system prompt, community 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.
conversation_idstring
Continue a retained thread. When the agent has product-chat retention on, each reply returns a
conversation_idyou can send back so the ticket stays one thread for review and training.external_user_idstring
Your app's visitor or account id. When set, that person is metered under a separate monthly credit budget (default 10,000 / UTC month). Configure limits from Dashboard → APIs.
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)Website embeds
Give site owners a chat widget without writing backend code. The widget loads a Nexpher-hosted iframe and calls the same agent API documented above. Configure everything from Agent Studio → Website.
<script
src="https://nexpher.ai/embed.js"
data-agent-id="YOUR_AGENT_ID"
data-key="nxa_YOUR_KEY"
data-name="Support"
data-mode="bubble"
data-position="bottom-right"
data-color="#6366f1"
data-external-user-id="user_12345"
async
></script>Set data-external-user-id to your logged-in visitor id so each person has their own monthly credit limit. See End-user limits.
Widget modes
bubble— floating corner button with popup panel (default)sidebar— full-height slide-in panel from left or rightbar— bottom bar that expands into a chat panel
Domain allowlist
Set allowedOrigins when creating or updating an agent API key. When non-empty, requests must include a matching Origin or X-Embed-Origin header. Widget embeds pass the parent site origin automatically.
PATCH /agent-api-keys/:id
{
"allowedOrigins": ["https://example.com", "https://www.example.com"]
}See the Website embeds guide for iframe embeds, JavaScript control (NexpherEmbed), and security best practices.
End-user credit limits
Pass external_user_id on chat (or data-external-user-id on the widget) to give each visitor their own monthly credit budget. Default is 10,000 credits per UTC calendar month; your account plan quota still applies. Manage defaults and individuals from Dashboard → APIs.
POST /v1/agents/:agentId/chat
Authorization: Bearer nxa_…
{ "message": "Hello", "external_user_id": "user_12345" }
# With the same nxa_ key (or session from Dashboard → APIs):
GET /v1/agents/:agentId/end-users/usage
GET /v1/agents/:agentId/end-users/:externalUserId/quota
PATCH /v1/agents/:agentId/end-users/:externalUserId/quota
{ "monthlyCredits": 25000, "bonusCredits": 5000, "disabled": false }
GET /agent-api-keys/:id/end-users
PATCH /agent-api-keys/:id
{ "endUserMonthlyCredits": 10000, "requireExternalUserId": true }
PATCH /agent-api-keys/:id/end-users/:externalUserId
{ "monthlyCredits": 25000, "bonusCredits": 0, "disabled": false }- 402 when an end user exhausts their monthly allowance; 403 if you paused them.
- requireExternalUserId on a key rejects chats that omit external_user_id.
- Bonus credits apply only to the current UTC calendar month.
MCP server — connect Cursor & Claude
Nexpher hosts a Model Context Protocol endpoint so external apps can list your agents, chat with them, and check credit balance. Use the same API keys as the REST APIs (nxa_… or your account key).
Endpoint: POST https://api.nexpher.ai/mcp (Streamable HTTP, stateless). Tools: list_agents, chat_with_agent, get_credit_balance.
Cursor mcp.json
{
"mcpServers": {
"nexpher": {
"url": "https://api.nexpher.ai/mcp",
"headers": {
"Authorization": "Bearer nxa_your_key_here"
}
}
}
}list_agentstool
Returns agents this key can access. An
nxa_key returns only its bound agent.chat_with_agenttool
Args:
agentId,message, optionalhistory. Burns plan credits like the REST agent API.get_credit_balancetool
Remaining credits and plan allowance for the billing target.
Streaming
Set "stream": true on the agent chat 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/agents/<AGENT_ID>/chat", {
method: "POST",
headers: {
Authorization: "Bearer nxa_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
message: "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 credits. 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). Mint an nxa_… key bound to one agent.
Agent keys
GET /agent-api-keys
POST /agent-api-keys { "agentId": "…", "name": "Production" }
# → returns { …, "apiKey": "nxa_…" } once
GET /agent-api-keys/:id/usage
GET /agent-api-keys/:id/end-users
PATCH /agent-api-keys/:id { "name": "…", "enabled": false, "allowedOrigins": ["https://example.com"], "endUserMonthlyCredits": 10000, "requireExternalUserId": true }
PATCH /agent-api-keys/:id/end-users/:externalUserId
{ "monthlyCredits": 25000, "bonusCredits": 5000, "disabled": 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.
- Agent plan limits: Free 1 · Starter 2 · Pro/Scale unlimited (keyed to that agent's billing plan).
- End-user limits: set endUserMonthlyCredits / requireExternalUserId on the key, or override per external_user_id.
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
- Agent API calls follow that agent's billing target (you, the team owner, or a shared team plan).
- Credits scale with model cost: cheaper models burn fewer credits than premium ones.
- 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?
Wrap a trained agent when you need a fixed personality or community listing.
Start freeWas this page helpful?
