---
title: "Create Agent"
method: POST
path: "/v1/agents"
tags: ["agents"]
---

# Create Agent

`POST /v1/agents`

## Request

- Base URL: `https://api.sonenta.dev`
- URL: `https://api.sonenta.dev/v1/agents`
- Auth: none declared

Platform staff only. Publishes a NEW agent to the catalogue.

Until now a new agent was provisioned by a one-off script run on the box
with the app's Mongo connection (`scripts/seed_agent_code_analysis.py`).
This is that script as a route, with the guards the script could not have:
the caller is identified, the write is audited, and a second create on the
same `id` is refused instead of silently upserting over the first.

The moment this returns 201 the agent is DISTRIBUTABLE: the public catalogue
lists it on the next read (edge cache: 300 s) and every paid client can
fetch and install it. So the content is validated as an installable file —
a frontmatter with the `version:` the update loop keys on and a `name:`
equal to the served id — but it is stored VERBATIM, never re-serialised.

## Request body

- AgentCreateIn: A NEW catalogue agent. Every field is required — there is nothing to be left unchanged on a document that does not exist yet. `name` is not accepted: it is `id`, and `install_path` derives from it (§5). Accepting a second identifier would create the "renamed = new agent" trap the contract closes by making `id` immutable. `content_version` is not accepted either: it is DERIVED from the frontmatter `version:` line so the two can never disagree (`entitlement.version_from_content`).
  - `id` string, required
  - `agent_type` string, required
  - `label` string, required
  - `description` string, required
  - `content` string, required

## Response `201`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/sonenta/apis/sonenta-api.md) · [All operations](https://skmtc.dev/sonenta/apis/sonenta-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sonenta/apis/sonenta-api/revisions/f853ea49fb05?raw)
