Skip to content

Agent API Profile ​

Status: live Agent API resource.

The profile is the member plane's bootstrap read: a program asks who it is acting as and what its credential is. It deliberately answers nothing about a delivery address or client. It exposes no email address, no internal database id, and no credential material.

For an Agent it also carries the profile's standing configuration — the tools its model may call and how a turn is assembled — which the profile itself declares through the one writer below and which the kernel reads at each turn's materialization and freezes per turn onto that turn's rows. The ordered fallback_models list is frozen with the execution; live availability gates still apply before a candidate sends. An input may instead capture an inline declaration at admission without changing the standing profile.

Get the current profile ​

Endpoint ​

http
GET /agent_api/v1/profile

Authentication ​

This endpoint accepts a member-plane credential and nothing else. A transport credential is refused with 401 — an executor learns its own identity from Executor, never from here. A revoked, expired, or authority-fenced credential returns 401 on its next request, and the family never explains which of those it was. For an Agent, the authority check requires the Agent to be active and steward_live? to pass: its same-Account steward must be active, and its applied_steward_shutdown_generation must equal that steward's current managed_resource_shutdown_generation. Human removal therefore fences this resource even for a Agent that has no executor. Agent convergence removes the Agent and acknowledges that snapshot. Whenever a Agent becomes removed, its member access and Agent-application credentials are fenced, and its related work is force-stopped asynchronously; an independent Runner is unaffected. Restore keeps the same Agent and does not wait for cleanup, but old credentials stay invalid. Reconnect supplies fresh credentials for the retained address. Agents currently have remove/restore, not a separate suspension command.

There are no query or body parameters.

Response ​

json
{
  "member": {
    "public_id": "01900000-0000-7000-8000-000000000001",
    "handle": "lark",
    "kind": "agent",
    "role": "member",
    "display_name": "Notes assistant"
  },
  "credential": {
    "plane": "member",
    "expires_at": "2026-08-08T00:00:00Z"
  },
  "configuration": {
    "tool_definitions": [
      { "type": "function", "function": { "name": "bash", "description": "…", "parameters": { "type": "object", "properties": { "command": { "type": "string" } }, "required": ["command"] } } }
    ],
    "approval_mode": "bypass",
    "approval_rules": [
      { "tool": "bash|start_process", "path": "command", "match": "*rm -rf /*", "verdict": "deny" },
      { "tool": "memory_*|ask|delegate_task|skill", "verdict": "allow" }
    ],
    "prompt_mechanism": "default",
    "prompt_template": null,
    "compaction_policy": { "mode": "kernel" },
    "lifecycle_hooks": null,
    "memory_context_limit": null,
    "conversation_reach": null,
    "default_model": "openrouter/z-ai/glm-5.3",
    "fallback_models": ["openrouter/moonshotai/kimi-k3"]
  },
  "measured_at": "2026-07-25T00:00:00Z"
}
FieldTypeDescription
member.public_idUUIDv7 stringPublic identifier of the acting member.
member.handlestringThe member's name beside its identity: 2–32 lowercase ASCII letters, digits, _ or -, starting with a letter or digit, unique per account. A peer writes it as @handle on a conversation's access carrier or as agent: on spawn or send. The kernel assigns an agent's from its name table at creation (a numeric suffix past a collision) and its steward may rename it; a Human's defaults from its display name and is the Human's own to change. Never absent, never null; agent_identifier stays the program's registration identity.
member.kindstringagent or human.
member.rolestringCurrent role. An agent member is always member.
member.display_namestringCurrent member name. For an Agent it is program-owned and written by the winning connection; for a Human it is ordinary member data.
credential.planestringAlways member here — the plane this bearer resolved on.
credential.expires_atstring or nullWhen this credential expires; null for a credential with no expiry.
configurationobjectThe Agent's standing declaration, present only when member.kind is agent; a Human declares nothing and the block is absent. Every field is null (the tool list []) until the profile declares.
configuration.tool_definitionsarrayExplicit tool declarations, canonical by name, in the wire families' own {type: "function", function: {name, description, parameters}} shape. Optional top-level defer_loading defers schema exposure without changing authority (see below). Kernel tools use the catalog's exact schema bytes or an alias declaration, {name, canonical, params?, omit?, description?, defer_loading?}. Read-back renders aliases as full function blocks with their resolution facts. Explicit Runner routes remain valid. [] when none are declared. This field retains the authored declaration; it does not read back automatically imported tools.
configuration.kernel_toolsarrayExact canonical kernel names whose plain definitions Nexus imports, such as nexus.conversation.spawn or nexus.runners.list. Omitted, null or [] imports no plain tools. Explicit kernel declarations and aliases in tool_definitions independently enable their tools; this field is not a deny list over those declarations. Duplicate and unknown names, wire aliases and wildcards are invalid.
configuration.runner_executor_public_idsarrayOrdered, unique Runner UUID candidates declared by this Agent. Only the selected Runner contributes automatic tools. Omitted, null or [] declares no candidates. Candidate knowledge survives when no Runner is selected; it is independent of the current tool list.
configuration.runner_tool_namesarray or nullExact served-name allowlist intersected with the selected Runner's model announcements. Omitted or null imports all announcements carrying both a model description and input schema; [] imports none. Names unavailable on the selected Runner contribute no tool. A named definition uses this field to limit its Runner tool subset.
configuration.approval_modestring or nullbypass, ask or rules — how the agent's tool calls cross the approval stage (Run approval). Required for explicit tools, nonempty kernel_tools, lifecycle hooks, or Runner candidates whose runner_tool_names is not []. Candidate knowledge alone need not enable any tools.
configuration.approval_rulesarray or nullThe rule list — [{tool, path?, match?, verdict, reason?, origin?}], the exact grammar in Run approval — frozen with the mode onto every turn the profile declares for. null when none.
configuration.prompt_mechanismstring or nullraw, assembly or default. default (the kernel's word when none is declared) is the built-in order — the three prompt-document slots, memory, the skills catalog, history, the inline lead, the inline tail, the input (Prompt assembly); raw sends the input's own entries; assembly compiles the same blocks in the ORDER prompt_template states (Prompt assembly).
configuration.prompt_templateobject or nullThe assembly template — REQUIRED when prompt_mechanism is assembly, stored unread under any other word: { "blocks": [ … ], "variables"?: { name: default } }, the block grammar in Prompt assembly, at most 64 KiB. A template outside the grammar is 422 validation_failed naming the JSON-pointer path of the fault (/blocks/3/role).
configuration.compaction_policyobject or null{mode: kernel | delegate | off, tool_name?, model?, reasoning_enabled?, reasoning_effort?} — the shape a round's compaction takes; delegate names its tool_name. The independent reasoning controls follow Models. The mid-turn arm prunes while the results outside the keep-recent tail cover the overshoot net of the placeholders each cleared call leaves, and summarizes once they cannot — nothing to configure.
configuration.lifecycle_hooksobject or nullOptional event-to-tool declarations for turn_start, pre_compact, post_compact, and stop, frozen onto each execution. See Lifecycle hooks and the declaration grammar below. null or {} enables none.
configuration.memory_context_limitobject or nullOptional ceiling over selected memory roots and access; configuration limits owns its grammar.
configuration.conversation_reachstring or nullworkspace or subtree; null uses ordinary workspace reach. See configuration limits.
configuration.default_modelstring or nullThe Agent's declared provider/model reference (Models). It is first in the model-selection order for a turn addressed away from the Conversation's default answerer or sent by a peer (spawn, send), using the selected model's default reasoning setting. When null, Nexus uses the addressee's last reply model in this Conversation, then the Conversation's last reply model, then the submitted initiator model. The default answerer's own ordinary inputs keep their submitted model. Recovery uses the execution’s captured ordered candidates and selection intent.
configuration.fallback_modelsarray or nullOrdered complete provider/model recovery candidates. Null or [] declares none. The initial model is independent. Captured with the execution; later declarations do not rewrite accepted work. See Agent configuration.
measured_atstringWhen the blocks were measured.

Renames and the cooldown ​

A handle is a NAME beside the identity: every persisted reference is by row, so a rename — the Human's own in settings, the steward's for an agent — breaks nothing and the rendered history follows the row. The name a rename leaves enters a 14-day cooldown in which no other member of the account may take it (a refusal names the cooldown; the releaser may take its own name back at once; only the latest released name is reserved, so a second rename frees the first); a swap of two handles therefore waits out the cooldown by design. The kernel never redirects an old handle: an unknown @old on an access carrier is principal_not_eligible; an input's to: returns principal_unknown, like any other unknown address — a name meaning two people over time is worse for a model than a loud refusal — and no surface carries the previous handle or a hint toward the new one (member keeps the five fields above). Every rename narrates handle_changed {user_public_id, old, new} on the member's own event rows; no Agent API route reads a member's rows yet.

This resource reports no delivery address ​

An Agent has at most one current logical delivery address. A successful connection with a non-revoked address has one; a never-connected or terminally revoked Agent validly has none and is un-askable. Its member credential is unbound and does not name an address even when one exists. Asking the member plane for it would be asking one plane to answer another's question, so this resource simply does not carry it. An Agent connection returns a sibling executor-transport credential; present that sibling token to Executor to read the address. The member token presented here cannot call Executor, and a Human member token may likewise have no delivery address at all.

That is also why there is nothing here to poll for a different address: a profile cannot have a second current one. This is a logical-address guarantee, not physical-device attestation; several processes holding a copied current credential are indistinguishable and unsupported. To reach this same Agent from several client locations, expose that access through your application. Separate installations may instead pair under distinct installation identifiers, creating distinct Agents and addresses; reconnecting the same identifier re-pairs its existing logical address.

An Agent also need not receive Tasks at all. A pure conversation or role-play product may use its member/data authority while leaving the delivery queue empty; neither this resource nor the existence of an executor address implies pending Task work.

HTTP response status codes ​

StatusCodeDescription
200 OK—Agent returned.
401 UnauthorizedunauthorizedThe credential is missing, unusable, or not a member-plane credential.
429 Too Many Requestsrate_limitedThe ordinary caller budget or broad source-IP backstop is spent. Retry-After is a whole number of seconds.

The rest of this resource ​

PageWhat it owns
Agent configurationThe standing declaration: tools, imports, Runner candidates, models, aliases, approval, lifecycle hooks, memory limits and conversation reach
Named agent definitionsThe sub-agents a profile mints by name
Profile memoryThe Human's own user/ or Agent's own agent/ scope and the shared conditional-write contract
Profile prompt documentsThe system_prompt, summarizer and persona slots

Store entries ​

Endpoints ​

http
GET    /agent_api/v1/profile/store_entries
POST   /agent_api/v1/profile/store_entries
GET    /agent_api/v1/profile/store_entries/{store_entry_id}
PATCH  /agent_api/v1/profile/store_entries/{store_entry_id}
DELETE /agent_api/v1/profile/store_entries/{store_entry_id}?lock_version=...

The principal's own door to the bounded namespaced JSON current-value store — client state that no prompt ever reads. Whose: the ACTING user's own row. An agent's entries here are the agent's, not its steward's, and the steward's are the steward's: a store is client-owned state per principal. Profile memory likewise selects only the caller's own Human or Agent anchor. There is no workspace fence on a person's own row and another principal's store is unreachable.

No receipt is kept for the profile store — Idempotency-Key is still required, but a repeat with the same key is 409 key_taken, never a replay: the unique index and lock_version are the whole convergence contract. The body, projections, pagination and the full status table are Store entries; the bounds are the store's: 64 entries per principal, 1 MiB per value.

Nexus is licensed O’Saasy. The rest of the repository defaults to MIT.