Appearance
Embed API
The Embed API is the client-side JavaScript interface for apps running inside Poe canvas frames. It provides store initialization, data access, bot interaction, and permissions — all from your app's frontend code.
Poe Employee Note
Currently the platform injects an import map into the app's index.html at serve time, which is what makes import { Poe } from "@poe/embed-api/v1.js" work without a bundler. In the future we'll probably want creators to include a script tag instead (e.g. <script src="https://poe.com/v1/embed-api.js"></script>) so the mechanism is more explicit and doesn't require server-side HTML rewriting.
Core APIs
Poe.setupStore()
Initialize a synced store inside your app.
javascript
async function addTodo(ctx, input) {
await ctx
.table("todos")
.set({ itemKey: input.id, value: { text: input.text, done: false } });
}
const client = Poe.setupStore({ mutators: { addTodo }, schemaVersion: 1 });Poe.store
A SyncedStoreClient reference. Available after calling setupStore().
Poe.stream()
Stream a response from a Poe bot. Returns an async iterator that yields partial message chunks as they arrive.
javascript
for await (const chunk of Poe.stream({
botName: "Claude-3.5-Sonnet",
prompts: "What is the capital of France?",
})) {
console.log(chunk.text);
}prompts can be a string, a single message object { role, content }, or an array of either.
Poe Employee Note
Poe.stream() is not thoroughly tested outside of unit tests and may have rough edges.
Poe.call()
Call a bot with automatic tool execution. Like stream(), but runs an agentic loop — when the bot emits tool calls, they are executed automatically and the results are fed back until the bot produces a final response.
javascript
const weatherTool = Poe.createTool({
name: "get_weather",
description: "Get current weather for a city",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
run: async ({ city }) => `Weather in ${city}: 72F sunny`,
});
for await (const event of Poe.call({
botName: "GPT-4o",
prompts: "What's the weather in Tokyo?",
tools: [weatherTool],
maxIterations: 10, // default
})) {
console.log(event.text);
}Poe Employee Note
Poe.call() is not thoroughly tested outside of unit tests and may have rough edges.
Poe.createTool()
Create an executable tool definition for use with Poe.call(). Tools define a JSON Schema for their parameters and a run function that returns a string result.
javascript
const calculator = Poe.createTool({
name: "calculate",
description: "Evaluate a math expression",
parameters: {
type: "object",
properties: { expression: { type: "string" } },
required: ["expression"],
},
run: async ({ expression }) => String(eval(expression)),
});Poe Employee Note
Poe.createTool() is not thoroughly tested outside of unit tests and may have rough edges.
Permissions
Request and check permissions from the host application. The host shows consent UI when permissions haven't been granted yet.
Poe.requestPermission(scope)
Request a single permission scope. Shows consent UI if not already granted.
javascript
const { granted, error } = await Poe.requestPermission("google_drive.read");
if (granted) {
Poe.store.mutate.continueMessage({
messageId: messageThatRequestedGoogleDriveAccess,
});
}Poe.checkPermission(scope)
Check whether a permission is granted without showing any UI.
javascript
const { granted } = await Poe.checkPermission("google_drive.read");Poe.requestPermissions(scopes)
Request multiple permission scopes at once. Returns which were granted and which were denied.
javascript
const { granted, denied } = await Poe.requestPermissions([
"google_drive.read",
"github.read",
]);
// granted: ["google_drive.read"], denied: ["github.read"]Poe Employee Note
The permissions API is still in progress. It is not thoroughly tested outside of unit tests and the set of available permission scopes is not yet finalized.
No-Build vs Bundled
| No-Build | Bundled | |
|---|---|---|
| Import | @poe/embed-api/v1.js | @poe/client-runtime-v1 |
| Schema | Inline mutators | defineSchema() + defineClientConfig() |
| Config | { mutators, schemaVersion } | Pre-built client config object |
| Types | None (plain JS) | Full type inference from Zod schema |