Skip to main content
The ecommerce surface is read-only. It exposes what Keebai knows about your catalog, the carts your customers built (including the ones they abandoned), and the sales that closed — everything under the /v1/ecommerce prefix, authenticated with a PAT and gated by scope. Writes stay in the portal and in the integrations. If you need to create a sale or push a product from your own system, that goes through the platform integration, not this API.

Data model

Products

The catalog: price, stock, variants, images. Includes both products created in Keebai and those synced from an integration.

Carts

What a customer put together, whether or not they finished. Abandoned carts carry a recovery status and a link back to checkout.

Sales

Closed transactions with their line items, amount breakdown, and payment state.

Sale events

Three webhooks fire as a sale is created, paid, and cancelled.
A cart is not the draft of a sale. They are separate records with no foreign key between them: a cart is what a customer assembled on a storefront, a sale is what your team or the assistant closed. Correlate on the customer’s phone or email, or on customer_id, which both carry when Keebai could resolve the contact.

Scopes

The three are separate because they leak different things. Carts and sales carry customer contact details and money; the catalog carries neither. A pricing widget on your website needs ecommerce:products:read and nothing else.
Reads are company-wide. Like CRM, these endpoints return records from every project in your company, not just the project your token belongs to.

Products come from two places

stock is only meaningful when stock_managed is true. On integration products, stock is whatever the last sync brought over — not a live read of the platform.

Abandoned carts

A cart with abandoned_at set and completed_at absent is the recoverable case. recovery_status tracks what has been done about it: recovery_url is the link that puts the customer back in checkout with the cart intact. Sending it over WhatsApp with a cta_url message is the intended pairing.

Money is stored in minor units

Every amount — price, unit_price, subtotal, total, and the whole amounts block on a sale — is an integer in the currency’s smallest unit. Read currency alongside it, and never assume two decimals: JPY and CLP have none.

Pagination

List endpoints take limit and offset and return the same envelope as the rest of the API:
limit defaults to 50 and caps at 200.
The catalog paginates by page internally, so an offset that is not a multiple of limit is rounded down to the page containing it. Keep offset a multiple of limit — the standard offset += limit loop is always correct.

Errors

Next steps

Browse the catalog

Start with products — the simplest of the three.

React to sales

Subscribe to ecommerce.sale.paid and push it into your accounting system.