GunSpec

Seller

A shop reaches these endpoints in four steps, and the third is the one nothing else explains.

  1. Hold an Enterprise plan. Listings are a plan perk. Nothing in these tables bills anyone and there is no separate advertising product.
  2. Apply, and be approved by a person. Apply at https://gunspec.io/en/sellers. Approval creates the shop; until then nothing of yours is public.
  3. Name a key. There is no such thing as a "vendor key" and no scope column on keys. You create an ordinary API key, then name it on the shop in Profile > Seller > Shop settings > Pushing from a server. That mapping is the entire vendor scope: the shop says which key it accepts a push from, and your key value is never sent to us. Several shops may name the same key; when they do, every call below needs ?vendor=, and GET /v1/vendor/shops lists the ids that key may act for.
  4. Read, then write. GET /v1/vendor/offers for what we hold, PATCH for a price or stock change, PUT for a bulk upsert, DELETE to withdraw. Read first and a nightly sync sends the rows that changed rather than all of them.

Four rules the API enforces and a retailer usually meets late:

  • Money is integer minor units plus an ISO 4217 code. 139900 with AUD is A$1,399.00. A float is refused at the boundary rather than rounded quietly. Minor units are not always hundredths: JPY has none, KWD has three. Send the units of the currency you name.
  • `stock_qty` is private and never appears in a public response. 0 renders as "No stock at this supplier", any other number as in stock, null as not tracked. A live count is competitive information, so we store it and never publish it. If you do not count units, send in_stock instead: a row that carries a quantity derives the flag from it, so the two cannot disagree.
  • Writing is also a claim that the price still stands. An offer nobody has refreshed in 30 days from a feed (90 from the console) stops appearing, because a stale price is worse than none. Re-pushing an unchanged row is how you say nothing changed.
  • A mapping error is a review, not a rejected batch. SKUs naming an id we do not hold come back in unmatched. A file of 400 rows is not refused because three ids were wrong.

GunSpec never takes the order. An offer carries a URL and links out; there is no basket, payment or customer anywhere in this surface. Public rows link through /v1/out/{clickId}, which counts the visit and redirects to you, so the traffic we send is measurable - read it in Profile > Seller > Traffic. region on an offer hides sellers who do not ship somewhere: a display convenience, never a statement about what is lawful to own.

ÖffentlichExplorer+

The outbound link behind every 'Where to buy' row. Redirects to the seller's own product page and counts the visit against that listing, which is how a shop can see what their placement sent them. The destination comes from the offer row and never from the request, so it cannot be used as an open redirect. Bots are not counted, and repeat clicks from one visitor within half an hour count as one visitor rather than one each. A listing that has lapsed, been unpublished or whose shop is suspended redirects to the catalog page for the product instead, and counts nothing. Public, because the readers it serves are anonymous visitors.

GET/v1/out/{clickId}

Keine Authentifizierung. Dieser Endpunkt antwortet ohne Schlüssel.

  • stringerforderlich

    The listing's tracking token, from clickId on an offer

  • string

    Locale for the catalog page a lapsed listing falls back to

    Akzeptiert

  • 404NOT_FOUNDResource not found
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Mindeststufe
Explorer+
Monatskontingent
200/mo
Anfragerate
10/min
Tageslimit
50

Die Werte gelten für die Mindeststufe dieses Endpunkts. Höhere Stufen erhöhen alle Limits.