What is an integration?
An integration exposes actions that agents can call as tools during a conversation. When an agent needs to look up a CRM record, send a Slack message, or query a database, it invokes an integration action.
Integration types
| Type | Description | Example |
|---|---|---|
| tool | Actions the AI can invoke via function calling | Search CRM, send email |
| channel | Two-way messaging channels | Slack, Teams, webchat |
| knowledge_source | Data sources for RAG indexing | Confluence, Notion, Sharepoint |
| composite | Combines multiple types | Full Salesforce connector |
Integration definition structure
Every integration is defined as a JSON object with metadata, secret declarations, and action handlers. Akili's integration registry loads this definition at startup.
// packages/backend/src/integrations/built-in/my-tool/my-tool.integration.ts
import type { IntegrationDefinition, ActionContext } from "../../integration-registry.service";
export const myToolIntegration: IntegrationDefinition = {
name: "My Tool",
slug: "my-tool", // unique, URL-safe identifier
version: "1.0.0",
description: "Connects agents to My Tool API",
type: "tool",
// Secrets are stored encrypted — users configure these in Settings → Integrations
secrets: {
MY_TOOL_API_KEY: { description: "API key from My Tool dashboard", required: true },
},
configuration: {
baseUrl: { type: "string", description: "Your My Tool workspace URL" },
},
actions: {
search: {
title: "Search",
description: "Search for records in My Tool",
inputSchema: {
query: { type: "string", description: "The search query" },
limit: { type: "number", description: "Max results (default 10)" },
},
handler: async (ctx: ActionContext) => {
const apiKey = ctx.credentials["MY_TOOL_API_KEY"];
const res = await fetch(`${ctx.configuration.baseUrl}/search?q=${ctx.input.query}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
return res.json();
},
},
},
};Registering your integration
- 1Create your integration file in packages/backend/src/integrations/built-in/my-tool/
- 2Import and call registry.register(myToolIntegration) in the BuiltInIntegrationsService.onModuleInit() method.
- 3Restart the backend — your integration appears in GET /api/integrations.
- 4Users can enable it in Settings → Integrations by providing their credentials.
- 5Agents with the integration enabled can invoke its actions automatically during conversation.
Receiving webhooks
For integrations that push events (e.g. a Slack message arrives, a form is submitted), create a webhook controller:
// POST /api/webhooks/my-tool/:instanceId
@Post(":instanceId")
@Public()
async handleWebhook(
@Param("instanceId") instanceId: string,
@Body() body: MyToolEvent,
) {
// 1. Verify the webhook signature using the instance's signing secret
// 2. Route to the appropriate agent via AgentExecutionService
// 3. Return 200 immediately; process asynchronously
return { ok: true };
}Publishing integrations to the marketplace
- Package your integration definition as a marketplace listing (type: 'integration')
- Users who install it provide their own credentials — you never see their secrets
- Version your integration using semver; users see 'Update available' when you publish a new version
- Integrations go through the same review process as agents