Build on the platform commerce runs on.
CCEN is a platform first. Every first-party app consumes the same APIs third-party apps consume. The App Bridge SDK is publishable. The reference L1 apps are open source. The marketplace is open and operators pay no per-app tax.
import { CCEN, defineApp } from "@ccen/app-bridge";
export default defineApp({
id: "returns-pro",
scopes: ["orders:read", "returns:write"],
routes: {
"/": async ({ ccen }) => {
const rmas = await ccen.returns.list({
state: "open",
merchant: ccen.context.merchantId,
});
return { rmas };
},
"/refund/:id": async ({ params, ccen }) => {
const order = await ccen.orders.get(params.id);
await ccen.modal.open({
title: `Refund ${order.id}?`,
cta: { label: "Confirm refund" },
});
},
},
// Tools your agent can call
tools: {
"issue-refund": {
input: z.object({ orderId: z.string() }),
handler: async ({ orderId }, { ccen }) => {
return ccen.refunds.create({ orderId });
},
requires: "approval",
},
},
});From npm install to first commit in 90 seconds.
CCEN apps are TypeScript modules. The SDK handles iframe boundary, postMessage, theme syncing, and shortcut registration. You write business logic.
Pull @ccen/app-bridge from npm. Same package whether you're shipping a marketplace app or an internal micro-app.
npm install @ccen/app-bridgeDeclare scopes, routes, and tools in a single config. The SDK wires up postMessage, theme tokens, modals, and shortcuts for you.
defineApp({
id: "returns-pro",
scopes: ["orders:read", "returns:write"],
})Run a sandboxed CCEN host on localhost. Hot-reload your app inside it. Real data, mocked or real depending on your scopes.
npx ccen dev --app ./apps/returns-proSubmit to the marketplace, or publish privately to your org. Versioning and rollback handled for you.
npx ccen publish --version 0.4.0Every primitive an app developer needs.
App Bridge SDK
Typed contract for postMessage, modals, shortcuts, theme tokens, and locale. Same surface across web, mobile, and embedded host frames.
Read moreOpen reference apps
Every first-party L1 app is open source on GitHub. Fork the Returns app for your wholesale flow. Submit a PR back if it makes sense.
Read moreGraphQL and REST
Typed GraphQL for product surfaces and dashboards. REST for batch jobs and webhooks. Both backed by the same L0 entities, same audit trail.
Read moreAgent tools
Register tools your agent can call. Set approval policies. Tools execute with the same identity, the same audit log, the same RLS as your team.
Read moreL0 / L1 / L2 model
Build at the layer that fits. Extend an L1 contract. Wrap a third-party app. Compose your own L2 micro-app. The data model never duplicates.
Read moreIframe-grade isolation
Every app runs from its own subdomain with strict CSP, COOP and COEP, sandboxed iframe, and per-app secrets. No shared JS context.
Read moreRead. Write. UI. Tools.
Four primitives cover ninety percent of what apps need. The SDK is the same on the dashboard, the agent runtime, and the marketplace shell.
Query orders, products, customers
All L0 entities are typed. Filters compile to indexed queries. The SDK handles cursoring and back-pressure for you.
import { CCEN } from "@ccen/app-bridge";
const ccen = await CCEN.connect();
const orders = await ccen.orders.list({
status: "processing",
channel: ["shopify", "amazon"],
createdAt: { gte: "2026-04-01" },
limit: 200,
});
for await (const page of ccen.orders.paginate({ status: "open" })) {
await processBatch(page.items);
}Mutations, audit-trailed
Every write records actor, source app, scope, and timestamp. RLS scopes guard what your app can touch. No raw SQL.
await ccen.orders.update(order.id, {
tags: ["needs_review", "fraud-watch"],
hold: { reason: "Manual review", until: "2026-04-30" },
});
await ccen.refunds.create({
orderId: order.id,
lineItems: [{ id: line.id, quantity: 1 }],
reason: "damaged",
});Open host UI from your iframe
Modals render in the host frame so they escape your iframe boundary. The SDK serializes and validates the payload.
await ccen.modal.open({
title: "Confirm refund",
body: <RefundReview order={order} />,
cta: { label: "Refund $84.20", variant: "primary" },
cancel: { label: "Cancel" },
});
ccen.shortcut.register("cmd+s", () => save());
ccen.theme.onChange((tokens) => applyTheme(tokens));Register tools agents can call
Tools are typed. Approval policy is declared next to the handler. Agents execute with their own identity and audit trail.
import { z } from "zod";
ccen.tools.register({
name: "rebalance-inventory",
input: z.object({
sku: z.string(),
fromLocation: z.string(),
toLocation: z.string(),
quantity: z.number().int().positive(),
}),
description: "Move inventory between warehouses",
requires: "approval",
handler: async (input) => {
return ccen.transfers.create(input);
},
});Every reference L1 app on GitHub.
Read the code, fork it, customize it for your business, ship it back to the marketplace. The contracts our first-party apps implement are the same contracts you implement.
L1 reference app for unified order management.
L1 reference app for multi-location stock.
L1 reference WMS with 3D bin model.
L1 reference app for the returns lifecycle.
The typed SDK every CCEN app uses.
Agent and tool registration helpers.
Local dev host, scaffolds, and publish flow.
Stream L0 entities to your S3 bucket.
Tools that do the work.
CCEN agents call tools you register. Tools are typed with Zod schemas, scoped to the app that registered them, and execute under their own identity in the audit log. Approval policies are declarative.
An agent built on your data has the same RLS and the same audit trail your team has. There is no shadow database.
- Per-tool approval policies (auto, approval, dual-approval).
- Built-in dry-run mode for development.
- Token cost surfaced per call. Budget enforced per app.
- Human-in-the-loop is a first-class flow, not a hack.
import { defineAgent } from "@ccen/agent-sdk";
import { z } from "zod";
export default defineAgent({
id: "po-planner",
description: "Drafts purchase orders weekly",
schedule: "0 6 * * 1", // Mondays at 6am
tools: {
"draft-po": {
input: z.object({
vendorId: z.string(),
items: z.array(z.object({
sku: z.string(),
quantity: z.number().int(),
})),
}),
requires: "approval",
handler: async (input, { ccen }) => {
return ccen.purchaseOrders.create(input);
},
},
},
run: async ({ ccen, tools }) => {
const lowStock = await ccen.inventory.belowReorderPoint();
const moments = await ccen.calendar.activeMoments({ window: "21d" });
const drafts = planFromSignals(lowStock, moments);
for (const draft of drafts) {
await tools["draft-po"](draft);
}
},
});You price your app. You keep the revenue.
CCEN does not take a cut of marketplace revenue from operators. App developers price their apps directly, bill on their own terms, and keep what they earn. We charge for compute and storage at usage rates only.
On every dollar your app earns from operators.
Per-CPU-second and per-GB-month. Free dev tier.
We shipped our subscription app in nine days. The App Bridge SDK gave us read, write, modal, and shortcut in one typed surface, with isolation built in. The marketplace took zero cut. We just got paid.
Build something operators will install.
Twelve hundred operators are already on CCEN. Every one of them is a potential install.