Skip to content

API Reference

The API listens on :8080. Request and response bodies are JSON, except agent specs, which may also be YAML.

CredentialHeaderWho uses itReaches
JWTAuthorization: Bearer <access token>People (console, Cortex)The user’s tenants, picked with X-Tenant-ID: <id>. Required for tenant and key management.
API keyX-API-Key: <key>Programs, HeraldIts own tenant only.
Run tokenAuthorization: Bearer <token>An agent mid-runPOST /api/v1/runs/messages/send only.
OperatorJWT of a user with the operator role, or X-Operator-TokenOperators/api/v1/admin/*. An operator’s JWT may also name any tenant in X-Tenant-ID.

Access tokens last 15 minutes; refresh tokens 7 days. /healthz, /readyz and /auth/* are public.

MethodPathBodyReturns
POST/auth/registeremail, password (≥ 8), displayName201 accessToken, refreshToken, user
POST/auth/loginemail, passwordaccessToken, refreshToken, user
POST/auth/refreshrefreshTokenA new pair; the old refresh token is revoked
GET/api/v1/me—The current user: id, email, displayName

JWT only.

MethodPathBodyReturns
POST/api/v1/tenantsdisplayName201 id, crName, displayName
GET/api/v1/tenants—The user’s tenants
DELETE/api/v1/tenants/:id—Soft-deletes the tenant: its keys stop validating, its agents are retired and its active subscriptions are cancelled
POST/api/v1/tenants/:id/keyslabel201 rawKey (shown once), label
GET/api/v1/tenants/:id/keys—Keys by hash and label, never the raw key
DELETE/api/v1/tenants/:id/keys/:hash—Revokes the key (soft delete; versions it authored keep the attribution)

JWT or API key. The tenant comes from the credential.

MethodPathNotes
POST/api/v1/agents[?subscription_id=]Body: the astromesh/v1 spec (YAML or JSON). Creates the agent and version 1. 201.
GET/api/v1/agentsThe tenant’s live agents.
GET/api/v1/agents/:nameThe agent and its current spec.
PUT/api/v1/agents/:name[?subscription_id=]Appends a new version and makes it current. Without subscription_id the agent keeps the one it had.
DELETE/api/v1/agents/:nameSoft-deletes; history stays readable.
GET/api/v1/agents/:name/versionsVersion summaries: number, date, author, checksum.
GET/api/v1/agents/:name/versions/:numberOne version with its spec. :number must be canonical (1, not 01).
GET/api/v1/agents/by-id/:id/versions[/:number]The same, addressed by agent id: unambiguous even after a name is reused.

A spec that fails validation returns 400 with problems: [...]. A body over the size limit is 413, and a number that cannot be stored without changing its value is 400. With subscription_id, a foreign or unknown subscription is 404 and a cancelled one 422.

FieldType
querystringRequired.
session_idstringConversation key. Reuse it to continue a conversation.
contextobjectPassed to the agent: prompt variables and caller data. Keys starting with _ are reserved for the runtime.

Optional header Idempotency-Key: replaying a key returns the existing invocation without running it again.

{
"invocation_id": "…",
"status": "ok",
"answer": "…",
"usage": { "tokens_in": 0, "tokens_out": 0, "by_model": [] },
"credits_charged_micros": 0,
"pricing_status": "priced",
"data": {},
"chain": {},
"propuestas": []
}
  • by_model[] holds provider, model, role and tokens per model, including tokens_cached.
  • data is present when the agent declares spec.output_schema (null if the answer did not validate). chain is present when spec.chain fired. propuestas lists the writes that mode: propose tools recorded without executing. Each key is omitted, not null, when the runtime sent nothing.
  • At 80 % or more of the period’s credit cap, the response carries X-Nexus-Credit-Usage: <percent>.

GET /api/v1/agents/:name/run/stream (WebSocket)

Section titled “GET /api/v1/agents/:name/run/stream (WebSocket)”

The handshake is a GET, so query and session_id travel as URL parameters. Every HTTP-level check (auth, 404, 422, admission) happens before the upgrade. The socket relays the runtime’s execution events and ends with one terminal event:

  • {"type": "done", "invocation_id", "status": "ok", "answer", "usage", …}, which carries the same fields as the synchronous response.
  • {"type": "error", "invocation_id", "status", "error_code", "message"}

Closing the socket cancels the run on the server and records it cancelled, charged zero credits.

StatusWhen
400Missing query or a malformed body.
402credit_budget_exhausted or subscription_credit_budget_exhausted.
404No such agent in this tenant.
409The Idempotency-Key belongs to another tenant’s invocation.
422The agent has no live version, or subscription_inactive.
429concurrency_exceeded or rate_limited.
502The runtime failed, or the agent could not be loaded.
503Nexus could not resolve the tenant’s limits or record the invocation, and refuses to run unrecorded.
504The run exceeded the run timeout.

Admission rejections are recorded as invocations with status rejected and the reason in error_code.

JWT or API key, scoped to the tenant. Provider and infrastructure costs are not included; they are on the operator plane only.

MethodPathReturns
GET/api/v1/agents/:name/statusRecent invocations with status, session_id and errors.
GET/api/v1/agents/:name/logsThe same recent invocations (a dedicated log stream does not exist yet).
GET/api/v1/agents/:name/metrics[?period=YYYY-MM]Consumption for the month (current by default) and all-time, by model.
GET/api/v1/agents/:name/invocations/:idOne invocation: status, timing, error, usage by model.
GET/api/v1/usage[?period=YYYY-MM]Tenant totals (current month and all-time) and a per-agent ranking by credits, including deleted agents.

GET /api/v1/catalog lists the tools an agent can declare (builtins and integrations), read live from the runtime pool.

A connection stores a credential for the tenant, such as an ERP key, an api_<slug> or an mcp_<slug>. Every run carries the tenant’s connections to the runtime, where an integration tool resolves its credential. The tenant comes from the credential, never the path.

MethodPathBody / returns
PUT/api/v1/connections/:namebase_url (optional), material (object, required). Sealed with AES-256-GCM.
GET/api/v1/connectionsNames, base_url and updated_at. Never the material.
DELETE/api/v1/connections/:nameRemoves it.

Without NEXUS_CONNECTIONS_KEY the routes answer 503 and runs go without credentials.

Present only when Herald is configured.

MethodPathCredential
POST/api/v1/messages/sendJWT or API key.
POST/api/v1/runs/messages/sendThe per-run token Nexus minted for the invocation.

Body: channel, recipient (both required), text, conversation_ref. Returns 202 with message_id and status. The tenant always comes from the credential. The run token is how an agent’s send_message tool posts back without the shared pool holding any tenant secret.

With the tenant’s credential. Creating and changing subscriptions is operator-only (below).

MethodPath
GET/api/v1/subscriptions?argo=<code>The tenant’s active subscription for that vertical, with its plan.
POST/api/v1/usage/eventsevent_id, subscription_id, unidad, cantidad, ocurrido_en. Idempotent per subscription and event_id.

A usage event is rejected when its unit is not in the plan, when it falls outside the subscription’s window or more than five minutes in the future, and with 409 period_closed when its period is already closed. See Plans & Billing.

Everything under /api/v1/admin requires the operator role or X-Operator-Token; without either the answer is 401. Every mutation is audited.

MethodPath
POST / GET/admin/tariffs[?at=RFC3339]File a tariff (append-only) / tariffs in force at an instant.
POST / GET/admin/plansCreate a plan (immutable once created) / list plans.
PUT/admin/tenants/:id/planplan_id: assign a tenant’s base plan.
POST / GET/admin/subscriptions[?tenant_id=&period=]Create (tenant_id, argo_code, plan_id, desde) / list with period counters.
PUT/admin/subscriptions/:id/planSchedule a plan change for the next period.
POST/admin/subscriptions/:id/cancelCancel.
GET/admin/usage[?period=]Platform totals and consumption by model.
GET/admin/tenants, /admin/tenants/:idConsumption per tenant with its plan, caps and margin.
GET/admin/agents[?period=]Agent health, with error rate = errors ÷ (errors + ok).
GET/admin/invocationsFilters tenant_id, agent_id, status, pricing_status, period; paged with cursor and limit.
GET/admin/invocations/:idFull detail, including provider and infrastructure cost.
GET/admin/tenants/:id/statement[?period=]The tenant’s statement for a period; .csv for one line per charge.
POST/admin/billing-periods/:id/facturadoMark a closed period invoiced (once; 409 if already).
GET/admin/billing-periods/overduePeriods past their grace that are not closed.

All paths in this table are under /api/v1.

Path
GET /healthzLiveness.
GET /readyzReadiness.

Any other path that is not under /api/ or /auth/ serves the operator console.