# Fetch the highest version of an agent

GET

/v1/agents/{agentId}

```sh
curl --request GET \
  --url https://example.com/v1/agents/example \
  --header 'Authorization: Bearer <token>'
```

An item more than one project serves (an environment order carries it to later environments) answers its newest active version that can run in a project the caller reads, and `404` when there is none. `projectId` narrows that to one project. An item with one project answers its latest active version. For an agent, that is its highest version, which numbers the next one. It is not always what a project runs: `agents.projects` says what runs in each project.

## Authorizations

- **[bearerAuth](https://docs.kindgi.com/v0.4.0/reference/api.md#bearerauth)**

## Parameters

### Path Parameters

**agentId**

required

string

AgentId — dotted namespace (`acme.drafting`).

### Query Parameters

**projectId**

string format: uuid

The newest active version that can run in this project, a project the caller reads; `404` when there’s none, or when the caller doesn’t read the project. An item with one project answers its latest version for its own project and `404` for any other; one that names no project (under `kindgi dev`, a pack’s agents, flows and tools) answers it for any. With authorization off, the caller reads every project. An older runtime ignores it and answers the latest version.

## Responses

### 200

Agent.

application/json

object

**id**

required

AgentId — dotted namespace (e.g. `acme.drafting`).

string

**version**

required

Semver.

string

**projectId**

The agent’s project: every version of an agent is in the one project. Absent when the runtime doesn’t record it: a pack `kindgi dev` serves from disk, or a runtime before Kindgi 0.1.6.

string format: uuid

**name**

required

string

**description**

string

**instructions**

required

One of:

- **string**

  string

  \>= 1 characters

- **object**

  A prompt block an agent’s instructions come from, by id and semver range.

  object

  **prompt**

  required

  The prompt block id.

  string

  **version**

  required

  A semver range (`^1.0.0`, `1.2.0`).

  string

**parameters**

Array\<object>

object

**name**

required

string

**description**

string

**type**

required

string

Allowed values: string number boolean date

**required**

boolean

**default**

Default value used when the caller omits this parameter.

**settings**

Settings blocks the agent reads, by range: tools read them as `ToolContext.settings['<id>']`, templates as `settings["<id>"]`. Pinned at publish (`pins.settings`).

Array\<object>

A settings block an agent reads, by id and semver range.

object

**id**

required

The settings block id.

string

**version**

required

A semver range (`^1.0.0`, `1.2.0`).

string

**modelSettings**

A model-settings block by range: its `temperature`, `maxOutputTokens` and `thinking` go into the turn’s model calls. Pinned at publish.

object

**id**

required

The settings block id.

string

**version**

required

A semver range (`^1.0.0`, `1.2.0`).

string

**capabilities**

required

Array\<object>

Capability declaration — see `@kindgi/capabilities`. Additional properties are permitted so new capability kinds do not require a wire change.

object

**_key_**

additional properties

any

**tools**

required

Array\<object>

Typed tool reference. `version` is a semver **range** (npm-style: `1.2.3` exact pin, `^1.2.3` compatible-updates, `~1.2.3` patch-updates-only, `>=1.0.0 <2.0.0` explicit range). Dispatch resolves the range to a concrete active version via `semver.maxSatisfying` at run start. No implicit “latest” — every tool ref names both id and range.

object

**id**

required

string

\>= 1 characters

**version**

required

string

\>= 1 characters

**retrieval**

required

Array\<object>

object

**source**

What it reads: facts (the default), or messages of this agent’s earlier conversations, quoted in the turn’s `<memory>` block as earlier conversation, never as turns.

string

Allowed values: facts conversations

**types**

The fact types it retrieves: required for facts; not used for conversations.

Array\<string>

\>= 1 items

**roles**

For conversations: whose messages it recalls. Default `['user']`, the people’s own words. Adding `agent` recalls the agent’s earlier answers too, which can carry its mistakes: they are quoted as unverified earlier answers, and publishing warns `recall-agent-answers`.

Array\<string>

\>= 1 items unique items

Allowed values: user agent

**scope**

required

What the intent selects within what the run may see. Facts: this conversation’s; the run’s end user’s only (`same-user`: none when the run names no `participantId`); the run’s project’s (none without a project); or every fact of the type it may see (`tenant`). Conversations: this end user’s other conversations with the agent (`same-user`: none when the run names no `participantId`); this conversation’s messages older than the history window (`same-conversation`); conversations in the run’s segment path (`same-segment`) or its project (`same-project`), whoever had them: those two quote other people’s conversations, so publishing warns and their messages are marked as another person’s. `same-segment` is for conversations only, `tenant` for facts only.

string

Allowed values: same-conversation same-user same-segment same-project tenant

**limit**

integer

\>= 1

**mode**

With the user’s message as the query: full-text, by meaning (fails the turn with `semantic-unavailable` on a runtime without embeddings), or both fused by rank (without embeddings, the keyword half). Absent: the newest facts.

string

Allowed values: keyword semantic both

**memory**

How the agent uses what it retrieves.

object

**instructionTypes**

Fact types that are instructions for this agent: a retrieved, verified fact of one of these types goes into the system message under ‘Policies (verified)’. Default: none.

Array\<string>

**remember**

Lets the agent remember: its turns offer the built-in tool `kindgi_remember` (built-in tools are `kindgi_<verb>`; an agent cannot list one in `tools`, and a published tool cannot use the prefix). The model picks the type, the text (up to 2,000 characters), an optional slot `key` and when it stops being true; the scope comes from here and the run. Every remembered fact is `unverified`, attributed to the agent version and the call that wrote it, and expires after `keepDays` unless a person verifies it. A person approves it before any read sees it when the scope is wider than one person (`same-project`, `tenant`) or the text reads like an instruction.

object

**types**

required

The fact types it may write.

Array\<string>

\>= 1 items

**scope**

required

Where its facts go: the conversation’s end user (else the user the run acts for), the conversation, the run’s project, or the tenant. Each but `tenant` includes the run’s project.

string

Allowed values: same-user same-conversation same-project tenant

**keepDays**

Days an unverified fact is kept. Default 30.

integer

\>= 1 <= 3650

**guardrails**

required

Array\<string>

**preferredProvider**

Soft hint — the router prefers this provider by id (e.g. `anthropic`) when at least one of its models satisfies `capabilities.needs` + tenant policy. Combine with `preferredModel` to pin the exact (provider, model) tuple. Falls back to capability-based ranking when the pinned provider is unregistered or filtered out.

string

\>= 1 characters

**preferredModel**

Soft hint at the model level (`ModelInfo.name`, e.g. `claude-sonnet-5-5`). Combined with `preferredProvider`: both set → promote the exact tuple; only `preferredModel` → promote any provider exposing that model; only `preferredProvider` → promote every model of that provider.

string

\>= 1 characters

**conversationPolicy**

object

**historyLimit**

integer

\>= 1

**hitlAfterTurns**

integer

\>= 1

**budget**

object

**maxSteps**

integer

\>= 1

**maxCostUsd**

number

**maxWallMs**

integer

\>= 1

**tags**

Array\<string>

**output**

object

**schema**

required

JSON Schema (draft 2020-12) the final answer must match.

object

**name**

A name for the output, shown to the model and in errors. Default `output`.

string

\>= 1 characters

**maxRepairs**

How many times the model is asked to repair an invalid answer. Default 1.

integer

**toolErrors**

object

**maxRetries**

Failed calls sent back to the model per turn. Default 1.

integer

<= 10

**retryOn**

Which failures are sent back: arguments that don’t fit the input schema (`invalid-arguments`), a tool the agent doesn’t have (`unknown-tool`), a tool that ran and failed (`tool-error`). Default `invalid-arguments`, `unknown-tool`.

Array\<string>

unique items

Allowed values: invalid-arguments unknown-tool tool-error

**parallelToolCalls**

Whether calls to read-only tools (`mutating: false`, no changing effect) that a model step asks for one after another run at the same time, up to 8 at once. A call to a read-only tool that pauses or declares connections runs on its own, since it may wait. Default `true`. `false`: every call runs on its own, in the order the model asked for them. Either way, the step’s results reach the conversation and the model in that order, and once a call needs a review, the step’s calls that haven’t started run one at a time. It doesn’t change what the model may ask for.

boolean

**pins**

The exact block versions an agent version runs: its lockfile. Set by the runtime when the version is published, never in the publish body: each tool range resolves once to the version every run of that agent version uses, so a new tool version reaches the agent only through a new agent version. Absent on a version published before pins existed (its ranges resolve per run).

object

**tools**

required

Tool id → exact version.

object

**_key_**

additional properties

string

**prompts**

required

Prompt block id → exact version.

object

**_key_**

additional properties

string

**settings**

required

Settings block id → exact version.

object

**_key_**

additional properties

string

**derivedFrom**

Set by the runtime on an agent or flow version a deploy registered in place of the definition’s version, which was registered already with other pins or content (versions never change). Never in the publish body.

object

**version**

required

The version the definition names.

string

**reason**

required

`pins-changed`: a block it uses has a new version; `unpinned`: the definition’s version was published before pins existed; `version-taken`: the definition’s version holds another definition; `edited`: derived from `version` with some data-block pins swapped: a suggested change’s version (`suggestedChangeId`), or an earlier hand edit’s (`label`, `by`).

string

Allowed values: pins-changed unpinned version-taken edited

**label**

For `edited`: a short label for the version.

string

**by**

For `edited`: who derived it (`user:<id>`).

string

**suggestedChangeId**

For `edited`: the suggested change it was derived for. Such a version serves no scope until a pin makes it serve.

string

**unregisteredAt**

Present only on an unregistered version (`GET …/versions/{version}` reads those too). Unregister stops a version being chosen, not the pins that hold it: a new run naming it is refused, while a resumed run and a published version that pins it still run it.

string format: date-time

**pinsDigest**

Set by the runtime with `pins`: `sha256:<hex>` of the pins’ canonical JSON (sorted keys, no whitespace). Two agent versions with the same digest run the same blocks.

string

/^sha256:\[0-9a-f]{64}$/

**owner**

`GET /v1/agents/{agentId}` only: the agent’s owner, absent until one is set (`PUT /v1/agents/{agentId}/owner`).

object

**userId**

required

string

\>= 1 characters

**name**

The person’s display name, when the runtime’s directory has one.

string

##### Example

```json
{
  "parameters": [
    {
      "type": "string"
    }
  ],
  "retrieval": [
    {
      "source": "facts",
      "roles": [
        "user"
      ],
      "scope": "same-conversation",
      "mode": "keyword"
    }
  ],
  "memory": {
    "remember": {
      "scope": "same-user"
    }
  },
  "toolErrors": {
    "retryOn": [
      "invalid-arguments"
    ]
  },
  "derivedFrom": {
    "reason": "pins-changed"
  }
}
```

### 400

`projectId` is not a project id (a UUID).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 401

Missing / malformed / expired / revoked bearer token.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 404

No agent with that id under this tenant.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 503

The database was too busy to answer in time (`database-busy`); `Retry-After` (whole seconds) says when to try again.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

## See also

- [`GET /v1/agents/{agentId}/projects`: List the projects an agent runs in, and what runs in each](https://docs.kindgi.com/v0.4.0/reference/api/operations/agentsprojects.md)
- [`GET /v1/agents/{agentId}/versions`: List versions of an agent](https://docs.kindgi.com/v0.4.0/reference/api/operations/agentslistversions.md)
- [`GET /v1/agents/{agentId}/versions/{version}`: Fetch a specific agent version](https://docs.kindgi.com/v0.4.0/reference/api/operations/agentsgetversion.md)
- [`PUT /v1/agents/{agentId}/owner`: Set an agent's owner](https://docs.kindgi.com/v0.4.0/reference/api/operations/agentssetowner.md)
- [Kindgi 0.4.0](https://docs.kindgi.com/v0.4.0/releases/0.4.0.md)
- [Error code `database-busy`](https://docs.kindgi.com/v0.4.0/reference/errors.md#database-busy)
- [Every error code](https://docs.kindgi.com/v0.4.0/reference/errors.md)
