---
title: "Plugin SDK Overview"
sidebarTitle: "SDK Overview"
summary: "Import map, registration API reference, and SDK architecture"
read_when:
- You need to know which SDK subpath to import from
- You want a reference for all registration methods on OpenClawPluginApi
- You are looking up a specific SDK export
---
# Plugin SDK Overview
The plugin SDK is the typed contract between plugins and core. This page is the
reference for **what to import** and **what you can register**.
**Looking for a how-to guide?**
- First plugin? Start with [Getting Started](/plugins/building-plugins)
- Channel plugin? See [Channel Plugins](/plugins/sdk-channel-plugins)
- Provider plugin? See [Provider Plugins](/plugins/sdk-provider-plugins)
## Import convention
Always import from a specific subpath:
```typescript
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
// Deprecated — will be removed in the next major release
import { definePluginEntry } from "openclaw/plugin-sdk";
```
Each subpath is a small, self-contained module. This keeps startup fast and
prevents circular dependency issues.
## Subpath reference
The most commonly used subpaths, grouped by purpose. The full list of 100+
subpaths is in `scripts/lib/plugin-sdk-entrypoints.json`.
### Plugin entry
| Subpath | Key exports |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `plugin-sdk/plugin-entry` | `definePluginEntry` |
| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` |
| Subpath | Key exports |
| --- | --- |
| `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface` |
| `plugin-sdk/channel-pairing` | `createChannelPairingController` |
| `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline` |
| `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` |
| `plugin-sdk/channel-config-schema` | Channel config schema types |
| `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` |
| `plugin-sdk/channel-lifecycle` | `createAccountStatusSink` |
| `plugin-sdk/channel-inbound` | Debounce, mention matching, envelope helpers |
| `plugin-sdk/channel-send-result` | Reply result types |
| `plugin-sdk/channel-actions` | `createMessageToolButtonsSchema`, `createMessageToolCardSchema` |
| `plugin-sdk/channel-targets` | Target parsing/matching helpers |
| `plugin-sdk/channel-contract` | Channel contract types |
| `plugin-sdk/channel-feedback` | Feedback/reaction wiring |
| Subpath | Key exports |
| --- | --- |
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile` |
| `plugin-sdk/provider-models` | `normalizeModelCompat` |
| `plugin-sdk/provider-catalog` | Catalog type re-exports |
| `plugin-sdk/provider-usage` | `fetchClaudeUsage` and similar |
| `plugin-sdk/provider-stream` | Stream wrapper types |
| `plugin-sdk/provider-onboard` | Onboarding config patch helpers |
| Subpath | Key exports |
| --- | --- |
| `plugin-sdk/command-auth` | `resolveControlCommandGate` |
| `plugin-sdk/allow-from` | `formatAllowFromLowercase` |
| `plugin-sdk/secret-input` | Secret input parsing helpers |
| `plugin-sdk/webhook-ingress` | Webhook request/target helpers |
| Subpath | Key exports |
| --- | --- |
| `plugin-sdk/runtime-store` | `createPluginRuntimeStore` |
| `plugin-sdk/config-runtime` | Config load/write helpers |
| `plugin-sdk/infra-runtime` | System event/heartbeat helpers |
| `plugin-sdk/agent-runtime` | Agent dir/identity/workspace helpers |
| `plugin-sdk/directory-runtime` | Config-backed directory query/dedup |
| `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` |
| Subpath | Key exports |
| --- | --- |
| `plugin-sdk/image-generation` | Image generation provider types |
| `plugin-sdk/media-understanding` | Media understanding provider types |
| `plugin-sdk/speech` | Speech provider types |
| `plugin-sdk/testing` | `installCommonResolveTargetErrorCases`, `shouldAckReaction` |
## Registration API
The `register(api)` callback receives an `OpenClawPluginApi` object with these
methods:
### Capability registration
| Method | What it registers |
| --------------------------------------------- | ------------------------------ |
| `api.registerProvider(...)` | Text inference (LLM) |
| `api.registerChannel(...)` | Messaging channel |
| `api.registerSpeechProvider(...)` | Text-to-speech / STT synthesis |
| `api.registerMediaUnderstandingProvider(...)` | Image/audio/video analysis |
| `api.registerImageGenerationProvider(...)` | Image generation |
| `api.registerWebSearchProvider(...)` | Web search |
### Tools and commands
| Method | What it registers |
| ------------------------------- | --------------------------------------------- |
| `api.registerTool(tool, opts?)` | Agent tool (required or `{ optional: true }`) |
| `api.registerCommand(def)` | Custom command (bypasses the LLM) |
### Infrastructure
| Method | What it registers |
| ---------------------------------------------- | --------------------- |
| `api.registerHook(events, handler, opts?)` | Event hook |
| `api.registerHttpRoute(params)` | Gateway HTTP endpoint |
| `api.registerGatewayMethod(name, handler)` | Gateway RPC method |
| `api.registerCli(registrar, opts?)` | CLI subcommand |
| `api.registerService(service)` | Background service |
| `api.registerInteractiveHandler(registration)` | Interactive handler |
### Exclusive slots
| Method | What it registers |
| ------------------------------------------ | ------------------------------------- |
| `api.registerContextEngine(id, factory)` | Context engine (one active at a time) |
| `api.registerMemoryPromptSection(builder)` | Memory prompt section builder |
### Events and lifecycle
| Method | What it does |
| -------------------------------------------- | ----------------------------- |
| `api.on(hookName, handler, opts?)` | Typed lifecycle hook |
| `api.onConversationBindingResolved(handler)` | Conversation binding callback |
### API object fields
| Field | Type | Description |
| ------------------------ | ------------------------- | --------------------------------------------------------- |
| `api.id` | `string` | Plugin id |
| `api.name` | `string` | Display name |
| `api.config` | `OpenClawConfig` | Current config snapshot |
| `api.pluginConfig` | `Record` | Plugin-specific config from `plugins.entries..config` |
| `api.runtime` | `PluginRuntime` | [Runtime helpers](/plugins/sdk-runtime) |
| `api.logger` | `PluginLogger` | Scoped logger (`debug`, `info`, `warn`, `error`) |
| `api.registrationMode` | `PluginRegistrationMode` | `"full"`, `"setup-only"`, or `"setup-runtime"` |
| `api.resolvePath(input)` | `(string) => string` | Resolve path relative to plugin root |
## Internal module convention
Within your plugin, use local barrel files for internal imports:
```
my-plugin/
api.ts # Public exports for external consumers
runtime-api.ts # Internal-only runtime exports
index.ts # Plugin entry point
setup-entry.ts # Lightweight setup-only entry (optional)
```
Never import your own plugin through `openclaw/plugin-sdk/`
from production code. Route internal imports through `./api.ts` or
`./runtime-api.ts`. The SDK path is the external contract only.
## Related
- [Entry Points](/plugins/sdk-entrypoints) — `definePluginEntry` and `defineChannelPluginEntry` options
- [Runtime Helpers](/plugins/sdk-runtime) — full `api.runtime` namespace reference
- [Setup and Config](/plugins/sdk-setup) — packaging, manifests, config schemas
- [Testing](/plugins/sdk-testing) — test utilities and lint rules
- [SDK Migration](/plugins/sdk-migration) — migrating from deprecated surfaces
- [Plugin Internals](/plugins/architecture) — deep architecture and capability model