Share a Wish

Changelog

Breaking changes are announced here and by e-mail to the technical contact of each partner.

Widget token lifetime, token renewal, OAuth bridge and basket hardening (@shareawish/widget 1.1.0)

  • Widget tokens live 60 minutes (was 10). POST /widget/init reports exp_minutes: 60.
  • New error code widget_token_invalid (401) for a missing/expired/foreign-origin X-Widget-Token on every widget route (previously Invalid widget token / forbidden). It is distinct from unauthorized (user token): re-run /widget/init and retry instead of showing a sign-in. Fixes the sign-in loop in the hosted save dialog when the token expired during e-mail confirmation.
  • Popup URL carries key and origin: the SDK (v1.1.0, also the legacy save-sdk.js) and the Basket SDK now pass the public key and the page origin to /save and /basket, so the hosted pages can renew their token themselves. The open event payload gained popup: boolean; the blocking "opened as a tab" alert() is gone and off() really unsubscribes.
  • /widget/init rejects a body origin that differs from the request's Origin header (400 invalid_origin, reason: origin_mismatch).
  • OAuth bridge: /widget/oauth-state and /widget/oauth-poll require the widget token (X-Widget-Token) or public key (X-Widget-Key); states are bound to that key, single-use (409 state_consumed), valid 10 minutes, and the poll only releases tokens to the creating key (403 state_key_mismatch).
  • POST /baskets/{id}/event requires the basket owner's public key (X-Widget-Key header or ?key=); GET /baskets/{id} only returns rendering settings.
  • 429 on abuse-sensitive routes: /widget/init, /widget/oauth-* and /baskets/{id}/event now enforce per-IP and per-key per-minute limits with a Retry-After header. All other routes keep the informational headers only.
  • Correction: /sdk/save-sdk.js does not redirect. It is the deprecated legacy script and stays served unchanged (security fixes only); migrate to /sdk/v1/widget.js.

Developer docs split into guides

API v1.1 – OpenAPI, canonical SDK URL, allow-list rule, pricing v2

  • OpenAPI 3.1 spec published at /openapi/shareawish-public-api.yaml with an interactive reference. The spec is validated against the route registrations on every build.
  • Canonical SDK URL: https://shareawish.shop/sdk/v1/widget.js (basket: /sdk/v1/basket-integration.js). /sdk/save-sdk.js, cdn.shareawish.shop/sdk/v1/* and cdn.shareawish.com/widget.js are deprecated. (Corrected 2026-09-19: /sdk/save-sdk.js stays served as-is, it is not redirected.)
  • Allow-list rule for new live keys: POST /widget/init only accepts a pk_live_ key from origins on the key's domain allow-list. Test keys keep working on localhost.
  • Pricing v2: new plan structure in the Partner Portal; rate-limit and usage headers unchanged, plan figures are exposed via GET /api-usage/{apiKeyId}.
  • Documentation of environment: test keys and the informational (non-blocking) rate-limit model.

v1.0 – Initial release

  • Save Button SDK with hosted save flow (/widget/init, /widget/save, /widget/saved-products).
  • HTML data-shareawish attributes and programmatic window.ShareAWish.init() API, Shopify Liquid snippets.
  • Basket Integration SDK for partner shops (/baskets/{id}, /baskets/{id}/event).
  • Partner Portal with API key management, domain allow-lists and usage dashboard.