Daemion docs

How do I create an integration extension?

An integration extension is a named connection to an external service. It stores the configuration — endpoints, credentials, and behavior hints — that agents reference when interacting with that service.


When would I use an integration?

Use an integration when you want Daemion to coordinate with a service outside the local system. Good candidates:

  • GitHub — watch for new PRs, post review comments, open issues from a conversation
  • Slack — send summaries to a channel, post alerts when a job finishes
  • Vercel — query deployment status, trigger a deploy from chat
  • Any webhook-backed service — if the service has an HTTP endpoint, an integration can describe it

Integrations don’t run code themselves. They are configuration records that agents read when they need to know how to talk to a service.


How do I create one by chatting?

Tell Daemion which service you want to connect. The agent creates the extension record:

You: Create an integration with GitHub that notifies me on new PRs

Daemion: I’ll set up a GitHub integration. I’ll need a few details — which repository should I watch, and where should I send the notifications?

You: Watch jordanhindo/daemion and post to the #dev channel in Slack

Daemion: GitHub integration created. It will poll for new PRs on jordanhindo/daemion and forward them to Slack via your Slack integration. I’ll check every 15 minutes — want to adjust that interval?

The extension is written to SQLite immediately. No restart needed.


How do I create one via the API?

The API is the programmatic path — for scripts, CI pipelines, or agents creating integrations at runtime. Chat is the primary path for humans.

bash
Verified

curl -X POST http://localhost:3001/extensions
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{ “type”: “integration”, “name”: “github-pr-watcher”, “description”: “Watches jordanhindo/daemion for new pull requests and surfaces them in chat.”, “definition”: { “service”: “github”, “repo”: “jordanhindo/daemion”, “events”: [“pull_request.opened”], “poll_interval_minutes”: 15 }, “source”: “user”, “enabled”: true }’

The gateway validates the envelope against ExtensionSchema and stores the record. The definition field is open (GenericDefinitionSchema) — structure it to match what your agents expect to read.


What does the integration schema look like?

Integration extensions use the generic definition schema — the shape of definition is up to you. The top-level envelope (shared across all 12 extension types):

typescript

interface Extension { id: string; // e.g. “ext_09def789” — assigned by gateway on creation type: “integration”; name: string; // unique per type, kebab-case, 1-100 chars description: string; // human-readable, max 500 chars definition: Record<string, unknown>; // service-specific config source: “built-in” | “user” | “agent” | “community”; enabled: boolean; created_at: string; // ISO 8601 updated_at: string; // ISO 8601 }

A typical definition for a webhook-backed service:

typescript

// Example definition shape — adapt to your service interface IntegrationDefinition { service: string; // e.g. “github”, “slack”, “vercel” endpoint?: string; // base URL if not well-known events?: string[]; // event types to subscribe to poll_interval_minutes?: number; [key: string]: unknown; // any additional service-specific fields }


Frequently asked questions

Q Where do credentials go?
Don't store raw secrets in the definition field. Reference the credential by name (e.g. "credential": "github-token") and store the actual token in a control extension or environment variable. The agent will resolve it at runtime.
Q Can an agent create integrations at runtime?
Yes. POST to /extensions with source: "agent". Agent-created extensions start disabled — the user enables them. This lets Daemion propose and wire up new service connections during a conversation.
Q How does an agent discover which integrations exist?
Agents can call GET /extensions?type=integration to list available integrations. The response includes each extension's name, description, and definition.
Q Does an integration run anything automatically?
Not by itself. An integration is a configuration record. To run something on a schedule — like polling for new PRs every 15 minutes — pair the integration with a job extension that reads the integration definition and performs the work.
Q How do I update or delete an integration?
Use PATCH /extensions/:id to update fields or DELETE /extensions/:id to remove it. See the Extensions API for the full reference.

What can go wrong

What can go wrong

400 &#123;"error": "validation failed"&#125; — The envelope failed ExtensionSchema validation. Check that type is exactly "integration", name is 1-100 characters, and description is under 500 characters.

401 &#123;"error": "unauthorized"&#125; — The Authorization header is missing or the bearer token doesn’t match. The token is in ~/.daemion/.gateway-token. Use $DAEMION_TOKEN in your shell.

403 &#123;"error": "cannot disable essential extensions"&#125; — Essential built-in integrations cannot be disabled.

403 &#123;"error": "cannot delete essential extensions"&#125; — Essential integrations cannot be deleted. Create a new integration with source: "user" and a different name to customize behavior.


What’s next?