Hosted Wishlists & Share Links
Every product a shopper saves lands in a hosted wishlist on Share a Wish. Lists can be made public and shared with a link; friends and family open the page without an account, see the products and can mark items as purchased. Link previews on WhatsApp, iMessage, Slack or social networks are generated server-side.
Creating a hosted list
Lists belong to an end user, so every write needs the user's Supabase access token (Authorization: Bearer …). A list is created with a name and optional description; the response contains the new share token.
POST /hosted/me/lists
Authorization: Bearer <supabase access token>
Content-Type: application/json
{ "name": "Birthday", "description": "Ideas for my birthday" }
→ { "ok": true, "list": { … }, "token": "k3Jd9…" }
Then add products with POST /hosted/save (same contract as /widget/save, user token only) using the list's numeric db_id as wishlistId. POST /hosted/lists returns all lists the user owns or edits, including db_id, productCount, share_public and the collaborator role. Metadata can be changed with PUT /hosted/lists/{token} (name, description, share_public, image_path, occasion_slug) and a list is removed with DELETE /hosted/lists/{token} (owner only). Field-level details are on the Wishlist API page.
Public view without an account
Two endpoints power the share page and need no authentication at all. They only return lists whose share_public flag is true; anything else answers 404 not_found.
| Method | Path | Returns |
|---|---|---|
| GET | /hosted/public/lists/{token} | { list: HostedListDetail } — name, description, image, occasion, productCount, owner_username, owner_avatar, owner_is_premium. |
| GET | /hosted/public/lists/{token}/items | { products: HostedProduct[] } — each with title, imageUrl, affiliateUrl, price_minor, currency, purchased, priority, added_at. |
Both accept market (e.g. de-DE) and lang query parameters for localized titles and prices. A public list view is metered as one list view wishlist action per list, viewer and 10-minute window (see usage).
Signed-in users can additionally follow a public list with POST /hosted/public/lists/{token}/link (viewer role, auto-friends the owner) and unfollow with DELETE on the same path.
Mark-as-purchased flow
Gift-givers can tick off an item on the public page so nobody buys the same present twice. The endpoint is unauthenticated and works on public lists only:
PUT /hosted/public/lists/k3Jd9…/items/98765/purchased
Content-Type: application/json
{ "purchased": true }
→ { "ok": true, "purchased": true }
itemId is the item_id from the items response (not the product id). Sending { "purchased": false } reverts the flag. The list owner sees the same flag through the authenticated PUT /hosted/lists/{token}/items/{itemId}/purchased, and items come back with purchased: true in every items response.
Open Graph link previews
When a share link is posted in a chat or on a social network, the crawler receives a minimal HTML document with og:* and twitter:* tags instead of the JavaScript app:
GET /og/list/{token}?lang=de|en → text/html with og:title, og:description, og:image, og:url
GET /og/image/{file} → the rendered preview image (falls back to a default image)
The document sets og:type=website, og:site_name, a localized og:locale (de_DE / en_US), og:url and link rel=canonical pointing to https://shareawish.de/{lang}/list/{token}, plus a generated image with fixed width and height. Human visitors are redirected to the page immediately (meta refresh + location.replace). You do not need to call these routes yourself; they are what bots get when they fetch a share URL.
FAQ
Can people open a shared wishlist without a Share a Wish account?
Yes. Public lists are served by unauthenticated endpoints (GET /hosted/public/lists/{token} and …/items), and the share page works for anyone with the link.
How do I make a list public?
Set share_public: true via PUT /hosted/lists/{token} with the owner's user token. The share URL uses the list's token, e.g. https://shareawish.de/en/list/{token}.
Does marking an item as purchased require login?
No. PUT /hosted/public/lists/{token}/items/{itemId}/purchased with { "purchased": true } works without a token on public lists.
Where do link previews come from?
GET /og/list/{token} returns an HTML page with Open Graph tags and a generated preview image; crawlers receive it when they fetch the share URL.