Build on the Partner API
View as MarkdownSyncing the catalog
This guide is for builders of a website or app on the Partner API.
Keep your own copy of the offers in your inventory scope and render your site from it, never live from Groupon. Every field of a product is in the API documentation.
What to list
- List a product only when its
statusisactiveandavailabilityRequiredis false, and an option only when itsactiveis not false (nullmeans unknown: treat it as sellable). A product withavailabilityRequired: trueneeds a booked time slot and cannot be added to a cart. option.price.retailis the per-unit price the shopper pays: send it asexpectedPriceon cart calls.option.price.originalis the strike-through price.option.promotionis informational: the shopper enterspromotion.promoCodeon Groupon's checkout page. Cart totals always use retail.- Pick a picture from
mediaby itsrole(small,medium,large,extra_large,wide_crop), falling back to the largestwidth. Not every size exists on every offer.
Keeping your catalog fresh
| Run | When | What it reads |
|---|---|---|
| Full sync | First, once | Every product in your scope |
| Daily resync | Every day: the minimum | Every product again, then stop listing what the walk did not return |
| Delta refresh | Every two hours: optional | Only what changed since your last refresh (updatedSince) |
A delta alone is not enough. It cannot show you an offer that left your scope, and when a
promotion starts Groupon ignores updatedSince and returns the whole catalog, so handle a delta
of any size.
One walk serves all three runs:
text
seen = empty set # resync only
params = { country: "US", limit: 100 } # delta: add updatedSince: lastRefreshAt
cursor = none
repeat:
page = GET https://api-core.livingsocial.com/partner_storefront/products?params (+ cursor if set)
upsert every product in page.data by its id # replace options, prices, status
add every id in page.data to seen # resync only
cursor = page.nextCursor
until page.hasMore == false
stop listing every product whose id is not in seen # resync only; keep the row
lastRefreshAt = page.timestamp # the final page's timestampRules for every walk
- Send the same parameters on every page; only
cursorchanges. Keep paging untilhasMoreis false: a page can be short, or empty, while more follow. - A page holds at most 100 products (
limit), and 10 when you send none. - Save
lastRefreshAtand stop listing missing products only after a whole walk succeeds. If a walk fails part-way, change nothing and run it again.lastRefreshAtis the final page'stimestamp, Groupon's clock, never your own. - Never send
activeon a delta: you need the deactivated rows to stop listing them. - Run one walk at a time: skip a delta that falls due during a resync.
- If a page answers
BAD_REQUESTfor its cursor, discard the cursor and restart the walk. - Your database is a cache. The cart re-checks price and availability live.