AI Agents

Create AI agent

Creates a new AI agent. Choose the model, the skills it can call, any guardrails, channels it should respond on, triggers that wake it up, and an optional memory store. Subject to your plan's AI-agent quota.

post/v1/ai-agents

Request

  • Base URL: https://api.withone.ai
  • URL: https://api.withone.ai/v1/ai-agents
  • Auth: API key in header X-One-Secret

Request body

descriptionstring nullable
model'haiku' | 'sonnet' | 'opus' | 'fable' required
modelIdstring nullable
modelProvider'anthropic' | 'openai-api' | 'gemini'

The model provider powering a framework agent's brain. Values mirror the wire ids the console has always written into memory.modelProvider (openai-api, not openai) so the typed column and the historical marker can never disagree. Stored as text (the Role pattern) — the closed set lives here in Rust, so admitting a provider is a code change, never a Postgres enum migration.

namestring required
runtime'claude' | 'hermes' | 'openclaw' | 'clockwork'
tagsstring[] nullable
useTrialboolean

Put this agent on the caller's free-trial seat. Ignored when they have no live trial, or when its seat is already taken by another agent.

volumeIdstring uuid nullable

Response

Created AI agent

activeboolean required
createdAtstring date-time required
descriptionstring nullable
environment'test' | 'live' required
idstring uuid required
model'haiku' | 'sonnet' | 'opus' | 'fable' required
modelIdstring nullable
modelProvider'anthropic' | 'openai-api' | 'gemini' required

The model provider powering a framework agent's brain. Values mirror the wire ids the console has always written into memory.modelProvider (openai-api, not openai) so the typed column and the historical marker can never disagree. Stored as text (the Role pattern) — the closed set lives here in Rust, so admitting a provider is a code change, never a Postgres enum migration.

namestring required
organizationIdstring uuid nullable
projectIdstring uuid nullable
runnerStatus'pending' | 'running' | 'succeeded' | 'failed' | 'terminated'
runnerStopReason'user_requested' | 'seat_lapsed'

Why a pod was stopped. The same operation reached two ways, and the difference matters after the fact: a user pausing their runner and billing culling it for a lapsed seat leave an identical terminated row, and mean completely different things to whoever is asking why an agent went quiet - one is "I did that", the other is "resume will not help until you pay".

Null on a pod that has not been stopped, and on rows written before this was recorded.

Deliberately has no Default. "Why did this stop" has no sensible fallback: the column is nullable precisely because unknown is the honest answer for a pod stopped before it existed, and any default would answer that question with a guess. user_requested in particular is the one value that makes a console offer a restart.

runtime'claude' | 'hermes' | 'openclaw' | 'clockwork' required
status'active' | 'paused' | 'disabled' required
tagsstring[] required
trialSeatboolean nullable

Whether this agent occupies the owner's free-trial seat.

Worth surfacing because it decides what happens when the trial ends: this is the agent stopped first, ahead of the least recently used. It is also the only way a caller learns whether a useTrial create took effect, since that flag is ignored rather than rejected when there is no live trial or another agent already holds the seat.

Absent from the wire rather than false on the paths that do not resolve it, so "not on the trial seat" is never confused with "not asked".

updatedAtstring date-time required
userIdstring uuid required
versionstring required
volumeIdstring uuid nullable

Changes

No recorded changes to this operation across all 1 revision of this API.