Skip to content

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-BuildBundled
Import@poe/embed-api/v1.js@poe/client-runtime-v1
SchemaInline mutatorsdefineSchema() + defineClientConfig()
Config{ mutators, schemaVersion }Pre-built client config object
TypesNone (plain JS)Full type inference from Zod schema