Skip to main content
POST
Create a webhook endpoint

Authorizations

Authorization
string
header
required

API Key Authentication

Use your API key in the Authorization header:

Key Types:

Secret Keys (Server-Side Only):

  • Format: tybrite_sk_live_* (production) or tybrite_sk_test_* (sandbox)
  • Full read/write access to all endpoints
  • ⚠️ NEVER expose in client-side code or public repositories
  • Required for: every write a shopper does not make for themselves, authentication, payment verification, AI recommendations

Publishable Keys (Client-Safe):

  • Format: tybrite_pk_live_* (production) or tybrite_pk_test_* (sandbox)
  • Catalogue reads, plus the actions a shopper takes for themselves
  • ✅ Safe for client-side JavaScript, mobile apps, and public code
  • Allowed for: browsing products, search, CMS content, pricing queries, cart and wishlist, reviews, storefront events, and the Agent API's quotes, cart drafts and checkout intents

Endpoint-Specific Requirements:

  • Authentication endpoints (/v1/auth/*): Secret key required
  • Payment verification (POST /v1/payments/verify): Secret key required
  • AI Recommendations (POST /v1/recommendations): Secret key required
  • Semantic Search (POST /v1/search): Both key types allowed (read-only operation)
  • Shopper actions (cart, wishlist, reviews, storefront events, Agent API quotes, cart drafts and checkout intents): Both key types allowed
  • All other write operations: Secret key required
  • All read operations: Both key types allowed

Using a publishable key for restricted operations returns 403 Forbidden.

Body

application/json
url
string<uri>
required

HTTPS destination URL. HTTP is rejected.

Example:

"https://yourapp.com/webhooks/tybrite"

events
string[]
required

Array of event types to subscribe to. Use ["*"] for all events.

Order lifecycle: order.created, order.paid, order.fulfilled, order.shipped, order.cancelled, order.refunded, order.updated

In-store sales: sale.completed, sale.refunded — a sale rung up at the point of sale rather than online. Subscribe to these alongside the order events to receive every sale a store makes, whichever channel it came through.

Your connection: connection.revoked — the key pair your application holds for this store was revoked, rotated, deactivated or expired. Only reaches applications connected through Login with GC, and carries pair_id so you revoke the affected connection rather than every one you hold for the store.

Payment lifecycle: payment.succeeded, payment.failed, payment.refunded

Agent checkouts: agent.checkout_intent.created, agent.checkout_intent.confirmed, agent.checkout_intent.expired — a checkout an assistant prepared through the Agent API, the shopper's confirmation of it (the order now exists), and one that lapsed unconfirmed. agent.mandate.triggered — a shopper's standing instruction found its condition met and a checkout was prepared; the payload carries confirmation_url for the shopper to confirm it.

Customer lifecycle: customer.created, customer.updated, customer.deleted

Inventory & catalog: product.created, product.updated, product.stock_low, product.out_of_stock

Cart & checkout: cart.created, cart.updated, cart.abandoned, checkout.abandoned, wishlist.added

Gift cards: gift_card.issued, gift_card.redeemed, gift_card.expired

Promotions: promotion.applied (a promotion was applied to a checkout), promotion.created, promotion.activated (a promotion went live or was scheduled to), promotion.deactivated (a live promotion ended, was paused, or expired). A promotion awaiting approval is not yet a promotion: no event fires while it is a draft, and promotion.created arrives when it is approved.

Pricing: pricing_rule.created, pricing_rule.activated (a dynamic-pricing rule went live), pricing_rule.updated (a live rule's discount, scope, priority, or window changed — the prices it produces are now different), and pricing_rule.deactivated. Like promotions, a rule awaiting approval emits nothing until it goes live. Subscribe to these if you render prices and need to re-read when the rules behind them change.

Content & collections: collection.created, collection.updated (a product collection was added, its homepage placement / banner changed, or its membership changed — products added, removed, or re-ordered). A membership change carries members_changed: true, and fires once per collection per change, not once per product.

post.published, lookbook.published, review.approved (a review passed moderation and is now visible)

Deletion & restore: product.deleted, product_variant.deleted, promotion.deleted, collection.deleted, post.deleted, lookbook.deleted, pricing_rule.deleted, customer.deleted, subcategory.deleted — the record has left the API. It no longer appears in any list, cannot be fetched by id, and stops taking effect (a deleted promotion stops discounting; a deleted product cannot be bought). Each carries the record's id and name, plus deleted_at and restorable_until.

Deleting is reversible for 90 days, so every one of these has a matching .restored event (product.restored, promotion.restored, and so on) that fires when the merchant brings the record back. restorable_until tells you how long you have: you may tear down your copy immediately and rebuild it on .restored, or hold it until the window closes.

Deleting a product also deletes its variants, so a product.deleted is followed by a product_variant.deleted for each one. Restoring the product restores them together.

Visibility: category.activated, category.deactivated, subcategory.activated, subcategory.deactivated. A category that is switched off is filtered out of every catalog read, so it disappears from your storefront exactly as a deleted one would — these events tell you when that happens. Categories cannot be deleted (they are a fixed platform set a merchant enables or disables), so this is the only lifecycle signal they produce. Subscribe if you render navigation, a category strip, or any layout built from the taxonomy.

Store lifecycle & configuration: store.updated (the store's name, logo, branding, contact, base currency, or the shopping assistant's name or logo changed — carries a changed_fields list, which names agent_assistant_name and agent_assistant_logo_url for the assistant), payment_provider.connected (a payment provider was connected), shipping_provider.connected (a shipping-rate provider was connected), channel.connected (a sales channel was connected)

Store profile & policies: store.profile_updated (the store's support contact details, addresses, legal identity or social profiles changed — carries changed_fields; read the new values from GET /v1/store/profile), store.policy_published (a legal document was published or republished — carries slug, title, version, effective_date, published_at and external_url), store.policy_unpublished (a document was taken down and GET /v1/store/policies/{slug} now returns 404 — carries slug, title, version and unpublished_at)

Design system: store.design_system_updated (the store's design system changed, or was switched on or off — carries store_id, changed_fields and updated_at; read the new values from store.brand in GET /v1/store/info)

Feature availability: feature.status_changed — a capability's feature_status in GET /v1/store/info changed, e.g. the store publishes its first post and cms becomes available. Carries feature, status, and previous_status, each status one of available, awaiting_data, not_in_plan or unavailable. feature includes agentic_commerce and agent_hosted_helpers, so a shopping assistant can follow when the hosted helper tools become available or unavailable. Use this to light up a storefront surface the moment its data exists. See the automation-webhooks guide.

Catalog sync & syndication: feed.sync.completed (a scheduled inbound feed-pull finished — carries created/updated/failed counts), channel.sync.completed (a sales-channel push to Google/Meta/… finished — carries pushed/rejected counts)

Wholesale (B2B): for stores with wholesale enabled — the trade itself: b2b.rfq.created, b2b.quote.sent, b2b.quote.accepted, b2b.quote.rejected, b2b.po.issued, b2b.po.confirmed, b2b.po.fulfilled, b2b.invoice.issued, b2b.invoice.partially_paid (a payment arrived and a balance remains — fires for each such payment), b2b.invoice.paid, b2b.invoice.overdue

Wholesale credit and approvals: b2b.credit.threshold_reached and b2b.credit.exhausted fire when a buyer crosses a share of their credit limit, and b2b.buyer.on_hold / b2b.buyer.released when they are stopped or let go again. Each fires on the CROSSING, not the level, so a buyer who stays above a threshold produces one event rather than one per order. b2b.approval.requested, b2b.approval.approved and b2b.approval.rejected follow an order the buying organisation routes for internal sign-off before it reaches the supplier.

Wholesale replenishment: b2b.replenishment.needed fires when stock falls to its reorder point, and is the one wholesale event that fires in the BUYER's own store about their own stock rather than in the supplier's. It carries the supplier that line was last bought from, so an automation can raise the reorder rather than only report the need.

The store-lifecycle, content, and feature-availability events are designed for automation tools that keep a storefront in step with the store as it grows — the moment a promotion goes live, a collection becomes homepage-eligible, or a licensed capability gains its first data.

Example:
enabled
boolean
default:true

Whether the endpoint is active. Disabled endpoints are skipped on delivery.

metadata
object

Opaque key-value pairs for your own reference (not sent in deliveries).

Example:

Response

Endpoint created

webhook_endpoint
object