Store webhooks
Your store tells your server what happens in it through webhooks: an order
placed, a parcel delivered, a return asked for, a site published. Each event is signed with
Tuppence-Signature like every other, and carries the object as the API shows it.
Subscribe
Section titled “Subscribe”Choose the events when you add an endpoint: in the dashboard under Developers › Webhooks, where
they are grouped under Store, or with enabled_events on POST /v1/webhook_endpoints.
curl -sS https://api.tuppence.ai/v1/webhook_endpoints \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/hooks/tuppence", "enabled_events": ["order.created", "store.order_placed", "shipment.delivered"]}'An order from your store is an ordinary order: order.created carries it with
source: "online", then order.paid and order.completed. store.order_placed
follows with the store’s own view: its number, site, checkout and fulfilment.
Typed events
Section titled “Typed events”Every store event has its payload model in the API reference (x-webhooks), with an example, and
the SDKs know them all: narrow on type and data.object is that event’s object.
import { constructEvent, type StoreEvent } from "@tuppence/node";
const event = constructEvent<StoreEvent>(rawBody, req.headers["tuppence-signature"], secret);if (event.type === "order.created") { console.log(event.data.object.source, event.data.object.totals.total);}from tuppence import construct_store_event, models
event = construct_store_event(raw_body, request.headers["Tuppence-Signature"], secret)if isinstance(event.root, models.OrderCreatedEvent): print(event.root.data.object.source)Your connected businesses’ stores
Section titled “Your connected businesses’ stores”A platform’s endpoint with connect: true hears the stores of its connected businesses: the same
events, each with account naming the business. See
Connect: your connected accounts’ events.
The events
Section titled “The events”| Group | Events | When |
|---|---|---|
| Site | store.site_updated, store.site_published, store.site_reverted, store.site_scheduled | The site changed, a version went live, an earlier one went back live, a publish was scheduled |
store.domain_requested, store.domain_active, store.domain_failed, store.domain_removed, store.domain_switched | Your own domain: asked for, working, not working, removed, switched | |
merchant_sending_domain.verified | Your own sending domain verified: store emails go from it from now on | |
store.proposal_started, store.proposal_ready, store.proposal_failed, store.proposal_published | The store builder’s proposal for a site | |
store.snap_started, store.snap_ready, store.snap_failed, store.snap_published | A product made from photos taken in the app | |
store.import_started, store.import_completed, store.import_undone | An import from another platform | |
| Catalogue | product.created, product.updated, product.archived | A product, at the till and online |
store.product_published, store.product_unpublished | A product put online, or taken off | |
store.collection_created, store.collection_updated, store.collection_deleted | A collection | |
store.drop_created, store.drop_updated | A drop and its queue | |
stock.available, stock_alert.sent, stock_movement.created | Back in stock, a back-in-stock alert sent, any stock change | |
| Orders | store.order_placed | A store order, with its number, site, checkout and fulfilment |
order.created, order.updated, order.paid, order.completed, tender.created | The order itself, with source | |
store.checkout_abandoned, store.cancellation_received | A checkout left unpaid; a shopper cancelling within their rights | |
subscription.renewal_skipped, subscription.renewal_notice_sent | Subscribe and save: a renewal skipped, a shopper told of a higher price | |
| Delivery | fulfilment.shipped, fulfilment.delayed | A parcel left; one is late |
shipment.updated, shipment.in_transit, shipment.out_for_delivery, shipment.available_for_pickup, shipment.delivered, shipment.exception, shipment.returned_to_sender | The carrier’s news, every change and which change it was | |
| Returns | return.requested, return.approved, return.rejected, return.received, return.refunded, return.closed | A return, from asking to closed |
return.refund_due_soon | A refund the law wants within 14 days is still owed on day 10 | |
| Channels | store.channel_connected, store.channel_updated, store.channel_disconnected, store.channel_error | A sales channel, such as a marketplace |
listing.live, listing.rejected, listing.removed, listing.restricted | A product’s listing on a channel | |
| AI agents | store.agent_settings.updated | A switch on Store › AI channels changed: an assistant shown or hidden, its checkout or its most, hidden products |
store.agent.blocked, store.agent.unblocked | A shopper’s agent paused at your store (card testing, scraping, resale, or by Tuppence), and the pause lifted | |
| Shoppers | review.created, review.replied | A review of the business, and your reply |
product_review.requested, product_review.published, product_review.rejected | A product review: asked for, published, rejected | |
store_thread.message_received, store_thread.needs_you | Ask the shop: a shopper wrote; a thread needs a person | |
store.privacy_request_received | A shopper asked for their data or its deletion | |
store_flow.paused | An email flow paused itself: too many unsubscribes or complaints for its sends | |
| Assistant | change_set.applied, change_set.reverted, change_set.proposed, change_set.declined, change_set.expired | A change set: made, undone, waiting for a person, declined, past its time |
assistant_job.updated, assistant_job.paused, job_run.finished | One of the assistant’s jobs, and each of its runs | |
store_brief.ready | The morning brief is written | |
| Rules | store.tax_threshold_near, store.tax_threshold_reached, tax_registration.created | US sales tax thresholds, and a registration recorded |
policy.version_drafted, policy.version_published | Your store’s policies |
No event carries a shopper’s card, a label’s file, a token or a thread’s words.
- Webhooks: verifying, retries and the dashboard
- Store orders