How do I manage extensions through the API?
http://localhost:3001 Extensions are how you configure Daemion. Every agent, job, app, command, theme, and integration is an extension — a JSON record in SQLite that the engine loads at runtime. There is no separate table per type, no code deployment required. Add an extension and it’s live immediately.
The preferred way to create extensions is through chat — just describe what you want to an agent and it will create the extension for you. The API exists for programmatic use: scripts, CI pipelines, and agent-initiated creation at runtime.
How do I list extensions?
List all extensions, with optional filters. Returns extensions ordered by creation date, newest first.
| Parameter | Type | Description |
|---|---|---|
type | string | Filter by extension type: command, agent, job, app, theme, renderer, integration, action, widget, artifact, capability, or control. |
enabled | boolean | Filter by enabled state. Omit to return both enabled and disabled. |
source | string | Filter by source: built-in, user, agent, or community. |
owner_agent_id | string | Filter to extensions created by a specific agent. |
List all enabled job extensions
curl “http://localhost:3001/extensions?type=job&enabled=true”
-H “Authorization: Bearer $DAEMION_TOKEN”
List extensions created by the opus agent
curl “http://localhost:3001/extensions?owner_agent_id=opus”
-H “Authorization: Bearer $DAEMION_TOKEN”
Response shape:
[ { “id”: “ext_01abc123”, “type”: “job”, “name”: “daily-digest”, “description”: “Summarize yesterday’s threads and send a digest.”, “definition”: { “schedule”: “0 8 * * *”, “agent_id”: “sonnet” }, “source”: “user”, “enabled”: true, “created_at”: “2026-03-31T08:00:00Z”, “updated_at”: “2026-03-31T08:00:00Z” } ]
How do I get a single extension?
Fetch a single extension by its ID.
curl “http://localhost:3001/extensions/ext_01abc123”
-H “Authorization: Bearer $DAEMION_TOKEN”
How do I create an extension?
Create a new extension. Validated against the Zod schema for the given type. Returns the created extension with its assigned ID.
| Parameter | Type | Description |
|---|---|---|
type REQUIRED | ExtensionType | One of the 12 extension types. |
name REQUIRED | string | Unique, kebab-case identifier for the extension. |
description REQUIRED | string | Human-readable description of what this extension does. |
definition REQUIRED | object | Type-specific configuration. Shape varies by type — see the schema for each. |
trigger_def | object | Optional trigger definition (cron, event, or webhook) that activates this extension automatically. |
source | string | Origin of this extension: user, agent, or community. Defaults to user. |
enabled | boolean | Whether the extension is active immediately. Defaults to false. |
The primary way to create extensions is through chat. Describe what you need to an agent — “create a daily digest job that runs at 8am” — and the agent writes the extension record for you. Use this API for scripts and CI pipelines.
Creating a command extension:
curl -X POST http://localhost:3001/extensions
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{
“type”: “command”,
“name”: “summarize”,
“description”: “Summarize the current thread in three bullet points.”,
“definition”: {
“prompt”: “Summarize this thread in exactly three bullet points. Be concise.”,
“agent_id”: “haiku”
},
“source”: “user”,
“enabled”: true
}’
Creating a job extension with a cron trigger:
curl -X POST http://localhost:3001/extensions
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{
“type”: “job”,
“name”: “morning-briefing”,
“description”: “Fetch headlines and post a morning briefing thread.”,
“definition”: {
“agent_id”: “sonnet”,
“prompt_file”: “jobs/morning-briefing/prompt.md”
},
“trigger_def”: {
“type”: “cron”,
“expression”: “0 7 * * 1-5”
},
“source”: “user”
}‘
How do I update an extension?
Partially update an extension. Only fields you provide are changed — omitted fields are left as-is.
| Parameter | Type | Description |
|---|---|---|
name | string | New name for the extension. |
description | string | Updated description. |
definition | object | Replacement definition object. This is a full replace, not a deep merge — send the complete definition. |
trigger | object | Replacement trigger definition. |
enabled | boolean | Enable or disable the extension. |
curl -X PATCH http://localhost:3001/extensions/ext_01abc123
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{
“description”: “Updated: summarize in five bullet points instead of three.”,
“definition”: {
“prompt”: “Summarize this thread in exactly five bullet points. Be concise.”,
“agent_id”: “haiku”
}
}‘
How do I enable or disable an extension?
Toggle an extension's enabled state. Faster than PATCH when you only need to flip the switch.
Toggle — flips enabled to disabled or disabled to enabled
curl -X POST http://localhost:3001/extensions/ext_01abc123/toggle
-H “Authorization: Bearer $DAEMION_TOKEN”
Response (full extension object):
{ “id”: “ext_01abc123”, “type”: “command”, “name”: “summarize”, “description”: “Summarize the current thread in three bullet points.”, “definition”: { “prompt”: “Summarize this thread in exactly three bullet points.”, “agent_id”: “haiku” }, “source”: “user”, “enabled”: false, “created_at”: “2026-03-31T08:00:00Z”, “updated_at”: “2026-03-31T09:00:00Z” }
Disabling a job extension stops it from firing on its trigger schedule. The extension record is preserved and can be re-enabled at any time. Disabling a command extension hides it from the command palette in the app.
How do I delete an extension?
Permanently delete an extension. This cannot be undone. Prefer disabling (toggle) if you might want to restore it.
curl -X DELETE http://localhost:3001/extensions/ext_01abc123
-H “Authorization: Bearer $DAEMION_TOKEN”
Returns 204 No Content on success.
How do I read extension files?
Some extension types (jobs, agents) are backed by files on disk in addition to their database record. These endpoints let you inspect those files without shelling into the host machine.
List files for an extension
List the files on disk associated with this extension. Returns relative paths within the extension's directory.
curl “http://localhost:3001/extensions/ext_01abc123/files”
-H “Authorization: Bearer $DAEMION_TOKEN”
{ “root”: ”~/.daemion/agents/daemion”, “files”: [ { “name”: “daemion.yaml”, “isDirectory”: false }, { “name”: “agents”, “isDirectory”: true }, { “name”: “soul.md”, “isDirectory”: false } ] }
Read a specific file
Read the content of a specific file in the extension's directory.
| Parameter | Type | Description |
|---|---|---|
path REQUIRED | string | Relative path to the file within the extension directory, e.g. prompt.md |
curl “http://localhost:3001/extensions/ext_01abc123/file?path=prompt.md”
-H “Authorization: Bearer $DAEMION_TOKEN”
Read and write the disk config
Read the YAML configuration file on disk (job.yaml, agent.yaml, etc.) as a parsed object.
Write config back to disk. Overwrites the existing file. The body is a JSON object (e.g. systemPrompt for agents).
Read the disk config
curl “http://localhost:3001/extensions/ext_01abc123/disk-config”
-H “Authorization: Bearer $DAEMION_TOKEN”
Write config back to disk
curl -X PATCH http://localhost:3001/extensions/ext_01abc123/disk-config
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{ “systemPrompt”: “You are a helpful assistant.” }‘
Frequently asked questions
/extensions during a conversation to create a new job, command, or integration on the fly. Set source: "agent" and owner_agent_id to the agent's ID so you can filter and audit agent-created extensions later.command — slash commands in the chat UI. agent — Claude agent identities with system prompts and model routing. job — autonomous work units that run on a schedule or trigger. app — Vite projects served by the gateway. theme — visual themes for the Daemion app. renderer — custom content renderers for chat turns. integration — connections to external services. action — discrete callable actions exposed to agents. widget — embeddable UI components. artifact — structured outputs produced by agents. capability — agent capability declarations (what it can do). control — runtime control surfaces (buttons, toggles, forms).~/.daemion/daemion.db. File-backed extensions (jobs, agents) also have a directory on disk under jobs/ or agents/. The database record is the authoritative source — disk files are referenced by the definition.built-in — shipped with Daemion, not editable. user — created by you through the UI or API. agent — created autonomously by an agent during a conversation (see owner_agent_id). community — installed from the extension registry. Source affects display grouping in the app and determines whether an extension can be deleted.What can go wrong
400 {"error": "validation failed", "details": [...]} — The request body failed Zod schema validation. The details array lists each failing field and why. Check that type is one of the 12 valid values and that definition matches the shape required for that type.
404 {"error": "extension not found"} — No extension with that ID exists in the database. Double-check the ID from GET /extensions.
403 {"error": "cannot disable essential extensions"} — Essential built-in extensions (core commands and actions) cannot be disabled. They can be inspected but not toggled off or deleted.
403 {"error": "cannot delete essential extensions"} — Essential extensions cannot be deleted. To customize behavior, create a new extension of the same type with source: "user".
404 on /extensions/:id/file?path=... — The file doesn’t exist in the extension’s disk directory. Use GET /extensions/:id/files first to see what files are present.
PATCH silently drops nested definition fields — The definition field is replaced wholesale on PATCH, not deep-merged. If you send "definition": { "agent_id": "haiku" }, any other keys that were in the definition before are removed. Always read the current definition first and merge client-side before patching.
What’s next?
- Conversations API — send messages to agents and read thread history
- WebSocket events — subscribe to real-time job and agent events
- Quickstart — get the full setup running end to end