Skip to content
Tracon

Agents

19 operations. {prefix} is the route prefix passed to MapTracon; the template uses /tracon.

Operation ID: TraconListAgentExtensions

Lists the agent extensions a definition can name.

Extensions are defined only in code, with AddAgentExtension. This endpoint does not offer a write path; the UI lets users pick from this list when defining an agent. Listing the extensions runs none of them. The list is the same for every tenant, ordered by name, and an empty list is not an error.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Response Body Headers
200 OK application/json → array of AgentExtensionResponse —

Operation ID: TraconListAgents

Lists all agents defined in code and in the database.

The list merges every registered agent source into a single view, ordered by name. When two sources hold the same name, the source with the higher priority wins and the other one is dropped from the list — code definitions win over database definitions. The response is not paged; the number of agents is bounded by the control plane, not by traffic. Each entry carries the origin, so a client can tell an editable definition from a code-defined one.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Response Body Headers
200 OK application/json → array of AgentDescriptor —

Operation ID: TraconCreateAgent

Creates a new agent definition.

The definition is fully validated before it is stored: the model binding, every tool, skill, and callable agent must already exist, and the call graph must be free of cycles. A failed check returns 400 and nothing is written. A name that another definition already uses returns 409; a name that a code-defined agent already uses also returns 409, because code wins name conflicts and the stored definition would never resolve. On success the response is 201 with the saved definition at version 1 and a Location header pointing at it.

Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.

Request body (required):

Response Body Headers
201 Created application/json → AgentDefinition —
400 Bad Request application/problem+json → ProblemDetails —

Operation ID: TraconGetAgent

Returns an agent’s catalog summary and its persisted definition, if any.

A code-defined agent has no STORED definition, so ‘isEditable’ is always false for it — code is changed by changing the application, not through this API. A code agent declared declaratively (AddAgent(AgentDefinition)) still returns its full in-memory definition in ‘definition’, including ‘instructions’; only a code agent built from a factory (AddAgent(name, factory)) has ‘definition’ as null, since there is no AgentDefinition to return for one. For a factory agent whose concrete type exposes instructions (currently only Microsoft.Agents.AI.ChatClientAgent), ‘factoryInstructions’ carries a best-effort read of them instead; it is null when the type does not expose them or reading them failed. ‘isEditable’ is the single field a client checks before offering an edit form — it is true only when the agent’s origin is the database.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Parameter In Required Type Description and rules
name path yes string —
Response Body Headers
200 OK application/json → AgentDetailResponse —

Operation ID: TraconUpdateAgent

Updates an agent definition and produces a new version.

An agent’s name is immutable: when the path name and the body name differ the response is 400. A code-defined name returns 409 — code definitions are validated at compile time and are changed by changing the application. The same existence and call-graph checks as create apply, and a failed check writes nothing. Every successful save appends a version rather than overwriting; the previous content stays readable through the version history.

Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.

Parameter In Required Type Description and rules
name path yes string —

Request body (required):

Response Body Headers
200 OK application/json → AgentDefinition —
400 Bad Request application/problem+json → ProblemDetails —

Operation ID: TraconDeleteAgent

Deletes an agent definition and its version history.

The delete removes the current definition together with every stored version; it is not a soft delete and there is no rollback afterwards. A code-defined name returns 409. A name with no stored definition returns 404, so the call is not idempotent across repeats. Runs already recorded for the agent are kept — the run history does not depend on the definition still existing. The version numbering is kept too: an agent created again under the name starts one above the highest version the name ever had, so a pin to a deleted version finds no version.

Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.

Parameter In Required Type Description and rules
name path yes string —
Response Body Headers
204 No Content — —

Operation ID: TraconEstimateContextWindow

Estimates a prompt’s token count against the agent’s model, without calling the provider.

The diagnostic surface of the pre-flight context-window check: it returns the same numbers the check on ‘POST /api/agents/{name}/run’ would use, regardless of whether that check is enabled. No model provider is ever contacted. The estimate is approximate — it uses a fixed reference tokenizer, not the bound provider’s own count. ‘contextWindowTokens’ and ‘allowedPromptTokens’ are null when the agent’s model is not found in the catalog; in that case ‘wouldBeRejected’ is always false, since an unknown window can never be exceeded.

Authorization: bearer authentication; Reader role policy when that policy is registered; RunsRead API-key scope.

Parameter In Required Type Description and rules
name path yes string —

Request body (required):

Response Body Headers
200 OK application/json → ContextWindowEstimate —
400 Bad Request application/problem+json → ProblemDetails —
404 Not Found application/problem+json → ProblemDetails —

Operation ID: TraconRollbackAgent

Writes a definition as a new version with the content of a previous version.

A rollback moves forward, not backward: the old content is appended as a NEW version and the history is never rewritten, so the rollback itself stays auditable and can be rolled back in turn. An unknown version number returns 404; a code-defined name returns 409.

Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.

Parameter In Required Type Description and rules
name path yes string —

Request body (required):

Response Body Headers
200 OK application/json → AgentDefinition —

Operation ID: TraconRunAgent

Runs an agent for trial purposes and streams the response via SSE.

If the quota is exceeded, the run does not start and a 429 is returned; the ProblemDetails carries which quota was exceeded and when the counter resets. When the pre-flight context-window check is enabled (disabled by default) and the prompt is estimated to exceed the model’s window, the run does not start and a 400 is returned with the estimated and allowed token counts; no call reaches the provider. A request carrying the ‘Idempotency-Key’ header runs with a single JSON response (non-streaming) instead of SSE, because a replayed response cannot be reconstructed from a stream. A request carrying the ‘Prefer: respond-async’ header queues the run and returns ‘202 Accepted’ with a ‘Location’ header. If a registered IContentGuard blocks the content, the non-streaming response returns ‘422’ and the run’s error type becomes ‘content_blocked’; in the STREAMING response the status code has already been sent, so the block arrives as an SSE ‘error’ event instead. If a registered IRunAuthorizationHandler denies the caller, the run does not start and a 403 is returned; this check runs before the quota check, so a denied run never consumes the tenant’s quota. When session ownership is turned on, naming another user’s session in ‘sessionId’ is also refused with 403, and opening a NEW session is refused the same way when no authenticated identity can be resolved to own it (‘errorType’: ‘session_owner_required’). A run without a ‘sessionId’ that stops at a tool approval can never be answered: it closes as Failed, the non-streaming response is 409 (‘errorType’: ‘approval_unanswerable’), and the stream ends with an ‘error’ event of that type instead of ‘done’. Right before ‘done’, the stream sends a ‘custom’ event for each notice the run recorded from a fixed list, with the same data GET /api/runs/{id}/events serves: ‘tracon.output.truncated’ (a plain-text answer the model cut off at its output token limit or its context window) always, and ‘tracon.quota.threshold’ when the quota options publish it to the run stream. An agent with a harness loop streams every iteration, so the ‘update’ events carry the drafts and the feedback as well as the answer. After each iteration the loop evaluated, the stream sends a ‘loop.iteration-completed’ event, between that iteration’s last ‘update’ and the first ‘update’ of the next. Its data is the event GET /api/runs/{id}/events serves; its ‘payload’ holds ‘iteration’, ‘continued’, ‘continuedBy’, ‘failedCriterion’ and ‘ceilingReached’, and is null when ‘RunRecording:RecordToolPayloads’ is off. The answer is the iteration the last event closes, when that event has ‘continued’ false. When the last event has ‘ceilingReached’ true, the answer is the iteration after it, because the turn at the ceiling is not evaluated and has no event of its own. After an event with ‘continued’ true, the next ‘update’ carries the feedback the loop gives the model (role ‘user’), not the model’s answer. A run that does not record its events, or whose store could not take the event, sends no ‘loop.iteration-completed’ event. When an MCP server asks the user for input in the middle of a tool call (elicitation), the run ends as ‘AwaitingInput’ and the stream sends an ‘inputs’ event right before ‘done’ (the non-streaming response carries the same list as ‘inputs’): one entry per request with ‘requestId’, ‘toolName’, ‘serverName’, ‘message’ and ‘requestedSchema’ (a flat JSON schema of the fields to fill in). The answer is the input of the next run of the same session (‘inputResponses’); the tool call then runs again from its start with the answer. Only this endpoint and the AG-UI endpoint (‘Tracon.AGUI’, where the answer is a ‘resume’ entry of the thread) can carry the answer, and only in a run with a ‘sessionId’: on every other surface and in an agent called by another agent, the server’s request is answered with ‘decline’. An answer for an unknown request or with values that do not fit the requested fields is refused with 400, one for a request already answered with 409.

Authorization: bearer authentication; Operator role policy when that policy is registered; RunsWrite API-key scope.

Parameter In Required Type Description and rules
name path yes string —

Request body (required):

Response Body Headers
200 OK text/event-stream → string —
202 Accepted application/json → AcceptedRunResponse —
400 Bad Request application/problem+json → ProblemDetails —
403 Forbidden application/problem+json → ProblemDetails —
404 Not Found application/problem+json → ProblemDetails —
409 Conflict application/problem+json → ProblemDetails —
422 Unprocessable Entity application/problem+json → ProblemDetails —
429 Too Many Requests application/problem+json → ProblemDetails —
501 Not Implemented application/problem+json → ProblemDetails —
503 Service Unavailable application/problem+json → ProblemDetails —

Operation ID: TraconListAgentVersions

Lists a definition’s version history, newest first.

Every entry is a full definition snapshot, not a delta, so a single entry is enough to inspect or restore a past state. The agent must have a current stored definition; a deleted name returns 404. A code-defined or agent-source name also returns 404, with a reason that says so — such a definition is not stored by Tracon and has no version history at all.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Parameter In Required Type Description and rules
name path yes string —
Response Body Headers
200 OK application/json → array of AgentDefinition —

GET {prefix}/api/agents/{name}/versions/{a}/diff/{b}

Section titled “GET {prefix}/api/agents/{name}/versions/{a}/diff/{b}”

Operation ID: TraconGetAgentVersionDiff

Returns two definition versions as raw JSON; the diff is computed in the UI.

The server does no diffing and takes no position on how a change should be displayed; it returns both snapshots verbatim as ‘left’ and ‘right’ so the client chooses the presentation. The two version numbers may be given in any order. When either version is missing the response is 404 and names the one that was not found; a code-defined or agent-source name returns 404 saying it has no version history.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Parameter In Required Type Description and rules
name path yes string —
a path yes integer (int32) pattern `^-?(?:0\
b path yes integer (int32) pattern `^-?(?:0\
Response Body Headers
200 OK application/json → AgentVersionDiffResponse —

Operation ID: TraconValidateAgent

Compiles a definition without saving it and without calling any model.

A validation failure is NOT an HTTP error. When the body is well-formed the response is always 200 and the outcome is carried in the report’s ‘valid’ field, with one message per finding. 400 is returned only when the body itself cannot be read or the required name/model fields are missing — that is the single case a pipeline needs in order to tell a transport error from a rejected definition. No model provider is contacted and nothing is written.

Authorization: bearer authentication; Operator role policy when that policy is registered; AgentsAdmin API-key scope.

Request body (required):

Response Body Headers
200 OK application/json → AgentValidationReport —
400 Bad Request application/problem+json → ProblemDetails —

Operation ID: TraconListLoopCriteria

Lists the loop criterion kinds a definition can name, and the loop judge model.

The built-in kinds come first, then the kinds registered in code with AddLoopEvaluator. A kind registered in code reads no field of the criterion except its kind. Listing the kinds runs no registered criterion factory. judgeModel is the model an aiJudge criterion calls, or null when the host bound none: such a criterion then does not compile, and it never falls back to the agent’s own model. The list is the same for every tenant; whether the caller’s egress policy allows the judge is reported by POST /api/agents/validate.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Response Body Headers
200 OK application/json → LoopCriterionCatalogResponse —

Operation ID: TraconListModels

Lists registered model providers and their models.

The model catalog comes from configuration; Tracon does not ship a built-in model list. An empty list is not an error. The catalog is also not a validation list: a model name that is not listed here can still be used. The status field comes FROM THE CACHE, and this endpoint makes no network call to the provider; use /api/models/health for an up-to-date check.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Response Body Headers
200 OK application/json → array of ModelProviderDescriptor —

Operation ID: TraconStats

Returns run counts, token totals, and the error rate.

The summary is computed in the store itself. Cost is populated only when pricing is configured (model catalog or Tracon:Pricing); the count of models with undefined pricing is counted separately in the RunsWithUnknownPricing field — it is not written as zero. Every breakdown (byAgent, byModel, byVersion, byUser, byLabel) is ALWAYS returned; there is no groupBy switch. ‘userId’ and ‘label’ (‘key:value’) narrow the whole summary rather than choosing a breakdown. byLabel rows do NOT sum to totalRuns: a run carrying three labels appears in three of them. cachedInputTokens and reasoningTokens are counted INSIDE inputTokens/outputTokens, so adding them double counts.

Authorization: bearer authentication; Reader role policy when that policy is registered; RunsRead API-key scope.

Parameter In Required Type Description and rules
agentName query no string —
userId query no string —
label query no string —
startedAfter query no string (date-time) —
maxAgents query no integer (int32) pattern `^-?(?:0\
Response Body Headers
200 OK application/json → RunStatistics —

Operation ID: TraconStatsErrors

Returns the breakdown by error class and each class’s top three clusters.

This is a narrow slice of /api/stats: it returns only the ByErrorClass field (that field is also present in the /api/stats response). The default range is the last 24 hours, changed with ?hours=. Rows written before error classification existed appear in the Unknown bucket; a high Unknown share means the taxonomy is incomplete.

Authorization: bearer authentication; Reader role policy when that policy is registered; RunsRead API-key scope.

Parameter In Required Type Description and rules
agentName query no string —
hours query no number (double) pattern `^-?(?:0\
Response Body Headers
200 OK application/json → array of RunErrorStatistics —

Operation ID: TraconRecalculateCosts

Fills in the cost of runs whose price is still unknown.

This is a maintenance endpoint. It fills in the cost of runs whose price is still unknown (unpriced when they completed, typically because the model was not configured yet); a run’s cost is a price snapshot and this endpoint never rewrites one that already has a known price, even if the price list changed since. A run written before the provider column existed resolves by model name alone; if the same model name is defined for more than one provider, the first alphabetical match wins. Requires Admin; the call is written to the audit trail.

Authorization: bearer authentication; Admin role policy when that policy is registered; RunsWrite API-key scope.

Response Body Headers
200 OK application/json → RunCostRecalculationResult —

Operation ID: TraconStatsTimeSeries

Per-bucket time series of runs, errors, tokens, and cost.

Empty buckets are returned too. The default range is the last 24 hours, the default bucket is an hour. At most 500 buckets; exceeding that returns 400. Unlike /api/stats, this endpoint does NOT exclude Eval/Workflow runs by default; it can be filtered with ?kind=.

Authorization: bearer authentication; Reader role policy when that policy is registered; RunsRead API-key scope.

Parameter In Required Type Description and rules
from query no string (date-time) —
to query no string (date-time) —
bucket query no TimeSeriesBucket —
agentName query no string —
modelId query no string —
kind query no RunKind —
Response Body Headers
200 OK application/json → array of TimeSeriesPoint —

Operation ID: TraconListTools

Lists registered tools and their JSON schemas.

Tools are defined only in code. This endpoint does not offer a write path; the UI lets users pick from this list when defining an agent. A hosted tool (a web search, a code interpreter or a file search the model provider runs) carries hostedKind and no JSON schema; whether the provider of an agent’s model runs it is reported by POST /api/agents/validate. Listing runs no factory of the host.

Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.

Response Body Headers
200 OK application/json → array of ToolDescriptor —