Runtime API

The platform injects one frozen global, window.BRT, before your entry module runs. It contains the approved bridge between the isolated extension frame and the storefront.

Use brt-extension.d.ts for TypeScript and editor completion. The exact machine-readable operations are in contract.json.

Initialization

Wait for BRT.ready before reading settings or calling an API.

const {capabilities, settings} = await window.BRT.ready;

Initialization fails after 10 seconds when the host cannot establish a valid channel. Calls also time out after 10 seconds.

BRT.capabilities() returns the currently granted capability keys. BRT.settings() returns the public values configured in the builder. Both snapshots are deeply frozen.

A store user can decline or revoke a capability. Check availability, handle rejected promises, and leave the section useful when optional access is missing.

Theme

Capability: site.theme.read

const theme = await BRT.theme.read();

Returns strings for primary, secondary, background, surface, text, mutedText, link, button, headingFont, bodyFont, sectionGap, and buttonRadius.

Treat values as CSS values, not HTML. Set known style properties or custom properties directly.

Catalog

Capability: catalog.products.read

const result = await BRT.catalog.products({
    search: 'optic',
    page: 1,
    limit: 12,
    includeOutOfStock: false,
});

Use a limit of 12 or 24. The result has this shape:

{
    products: [{
        id: 123,
        name: 'Product name',
        url: '/product/example?pid=123',
        image: '/storage/example.webp',
        price: '$99.00',
        inStock: true,
    }],
    total: 1,
    page: 1,
    lastPage: 1,
}

Product values are public storefront data. Still render strings with textContent or equivalent safe DOM APIs.

The url identifies the product's storefront route, but protocol version 1 does not provide a product-navigation action. Do not navigate the isolated frame or try to reach its parent. If product-detail navigation is required, report that platform gap during review.

Cart

Capability: cart.manage

await BRT.cart.manage('add', {productId: 123, quantity: 1});
await BRT.cart.manage('update', {productId: 123, quantity: 2});
await BRT.cart.manage('remove', {productId: 123});

Returns {ok, itemCount, total}. The host also dispatches its normal cart-updated event so the surrounding storefront can refresh.

Booking

Capabilities: booking.availability.read and booking.create

const availability = await BRT.booking.availability({
    laneId: 4,
    date: '2026-09-15',
    durationMinutes: 60,
});

await BRT.booking.start({
    laneId: 4,
    startsAt: '2026-09-15T16:00:00-06:00',
    endsAt: '2026-09-15T17:00:00-06:00',
});

Availability returns the public response from the site's range-availability endpoint. booking.start opens the BRT booking flow and returns {opened, url}.

Waivers

Capability: waivers.start

await BRT.waivers.start('range');

The accepted values are range, rental, and class. A missing value defaults to range. The call opens the BRT waiver flow and returns {opened, url}.

Approved forms

Capability: forms.submit

Newsletter:

await BRT.forms.submit('newsletter', {email: 'visitor@example.com'});

Contact:

await BRT.forms.submit('contact', {
    questionType: 9,
    name: 'Visitor name',
    email: 'visitor@example.com',
    phone: '555-555-0100',
    subject: 'Store question',
    message: 'Question text',
});

Both return {ok}. BRT supplies its own anti-abuse state. Extensions never receive CSRF tokens or application sessions.

Text messaging

Capability: communications.sms.open

await BRT.communications.text('I have a question about this item.');

The call opens the visitor's messaging app with the store's configured number. It returns {opened: true}. It fails with ADAPTER_UNAVAILABLE when the site has no valid text-message link.

Analytics

Capability: analytics.events.write

await BRT.analytics.track('Select product', {
    label: 'Featured products',
    value: 99,
});

Returns {tracked}. BRT honors the site's tracking configuration and consent state. Do not encode customer information in event names, labels, or values.

Raw requests

BRT.request(capability, action, payload) is available for forward-compatible low-level use. Prefer the named methods above. The host rejects unknown capabilities and actions even when a raw request is syntactically valid.

Messages must contain plain JSON-compatible data. Functions, DOM nodes, class instances, non-finite numbers, prototype keys, excessive nesting, and payloads above 65,536 bytes are rejected.

Errors

Rejected calls use an Error with a stable code property. Handle at least:

Code Meaning
CAPABILITY_NOT_GRANTED The store user did not grant or later revoked access.
ADAPTER_UNAVAILABLE The site cannot provide the requested operation.
INVALID_REQUEST The action or payload failed validation.
INVALID_PAYLOAD The request contains a value that cannot cross the isolated bridge.
INITIALIZATION_TIMEOUT The host did not initialize the extension within 10 seconds.
REQUEST_TIMEOUT No response arrived within 10 seconds.
TOO_MANY_REQUESTS The frame already has 64 pending calls.
PAYLOAD_TOO_LARGE Serialized request data exceeds 65,536 bytes.
PAYLOAD_TOO_COMPLEX Data exceeds depth, node, or collection limits.
REQUEST_FAILED The host rejected the operation without a more specific public code.

Show a useful local fallback. Do not display raw exception details to storefront visitors.