Skip to content

Backend API

The poe-apps-sdk/v1/backend.js module is the single import for everything a Poe app needs on the backend side. It wraps @synced-store/backend with Poe-specific defaults — system tables and hooks are pre-wired so apps don't configure them manually.

typescript
import {
  defineSchema, table, singletonTable, item,
  defineBackendConfig,
} from "poe-apps-sdk/v1/backend.js";

Schema Builders

defineSchema()

Define a synced-store schema with Poe system tables automatically configured. System tables ($users, $userInfo) are pre-wired — no need to pass systemTableTypes.

typescript
import { defineSchema, table } from "poe-apps-sdk/v1/backend.js";
import { z } from "zod";

export const mySchema = defineSchema({
  schemaVersion: 1,
  tables: {
    messages: {
      schema: table(z.object({
        text: z.string(),
        sender: z.string(),
      })),
    },
  },
  mutators: {
    send: {
      description: "Send a message",
      input: z.object({ text: z.string() }),
    },
  },
  actions: {
    summarize: {
      description: "Summarize the conversation with AI",
      input: z.object({}),
    },
  },
});

table(schema)

Define a homogeneous table where every row has the same Zod schema.

singletonTable(items)

Define a singleton table with a fixed set of typed keys.

typescript
import { singletonTable, item } from "poe-apps-sdk/v1/backend.js";
import { z } from "zod";

const settings = singletonTable({
  theme: item(z.enum(["light", "dark"])),
  language: item(z.string()),
});

item(schema)

Define a single item within a singletonTable.

defineBackendConfig()

Bundle your schema, mutators, actions, and hooks into a typed backend config. Hook names (onAddUser, onRemoveUser) are pre-wired with their input types.

typescript
import { defineBackendConfig } from "poe-apps-sdk/v1/backend.js";
import { mySchema } from "./schema";
import { myMutators } from "./mutators";
import { myActions } from "./actions";

export const myBackendConfig = defineBackendConfig({
  schema: mySchema,
  mutators: myMutators,
  actions: myActions,
  hooks: {
    onAddUser: async (ctx, { userId }) => {
      // Initialize user data when they join
    },
    onRemoveUser: async (ctx, { userId }) => {
      // Clean up when a user leaves
    },
  },
});

System Hooks

HookInputWhen it fires
onAddUser{ userId: string }User joins the store instance
onRemoveUser{ userId: string }User leaves the store instance

System Tables

These tables are automatically available in mutators and actions via ctx.table():

TableTypeDescription
$usersUserMembershipUsers currently in the store instance
$userInfoPoeUserInfoProfile information for each user
typescript
// In a mutator or action:
const user = await ctx.table("$users").get(userId);
const info = await ctx.table("$userInfo").get(userId);

Platform Capabilities

Actions have access to server-side services via ctx.platform.call() — API keys, blob storage, and more. See Platform for the full list.

typescript
const actions = {
  summarize: async (ctx, input) => {
    const { apiKey } = await ctx.platform.call("getPoeApiKey", {});
    const { hash } = await ctx.platform.call("blob.put", { content: btoa("result") });
  },
};

Type Exports

Type Inference Utilities

typescript
import type {
  InferActionHandlers,      // Action handler types from schema
  InferMutatorHandlers,     // Mutator handler types from schema
  InferSchemaTableTypes,    // Table types from schema
  InferSchemaActionSchemas, // Action input schemas from schema
  InferSchemaMutatorSchemas,// Mutator input schemas from schema
} from "poe-apps-sdk/v1/backend.js";

Core Types

typescript
import type {
  ActionContext, ActionFn,      // Server-side action context
  MutationContext, MutationFn,  // Shared mutation context (client + server)
  QueryContext, QueryFn,        // Query context
  JSONValue,                    // JSON-serializable value
  ScanResult,                   // Table scan result
  TableReader, TableWriter,     // Table operation interfaces
} from "poe-apps-sdk/v1/backend.js";

Poe Platform Types

typescript
import type {
  PlatformCaller,    // Type for ctx.platform.call()
  PlatformAPI,       // Platform capability types
  PlatformAPIName,   // Platform capability names
  SystemHookMap,     // Typed hook definitions
  SystemTableTypes,  // System table type map
  PoeUserInfo,       // User profile data
  UserMembership,    // User membership record
} from "poe-apps-sdk/v1/backend.js";

Migration Types

typescript
import type {
  AnyMigration,  // Single migration step
  Migrations,    // Array of migrations for schema versioning
} from "poe-apps-sdk/v1/backend.js";