Skip to main content

Product discovery and buying

GET /api/public/v1/products searches products that you can purchase, and POST /api/public/v1/purchases buys a single unit of one.

Prerequisites​

  • The API key is authorized for products:read and purchases:write. Add purchases:read to read order state and history.
  • Your account has a saved payment method.
  • Your account has a default shipping address.

Which products are returned​

A product appears in search results and in GET /api/public/v1/products/{productId} only while all of the following hold:

  • It is actively listed.
  • It has available stock.
  • It is not one of your own listings.

Search returns an empty products array rather than an error when nothing matches, including when the only currently available listings are your own. Requesting one of your own products by ID returns 404.

Searching​

Filters include full-text query, price_min/price_max, year_min/year_max, categories, graded, graders, grade_min/grade_max, verified_cert, sport, game, manufacturer, subject, cert_number, upc, serial_numbered, offers_allowed, and has_shipping_discount.

sort accepts relevance, newest, price, year, grade, and title. It defaults to relevance when query is supplied and to newest otherwise. direction accepts asc or desc and defaults to desc.

Pagination​

Paging is cursor-based over a snapshot taken when the first page is requested:

  1. Send your filters and a limit with no cursor.
  2. Process the returned products.
  3. While has_more is true, send next_cursor unchanged as cursor on the following request.
  4. Repeat every filter, sort, and direction value from the first request on every page.

Changing any filter while reusing a cursor returns a validation error. Products listed after the first page was requested do not shift the remaining pages of that sequence.

Reading one product​

GET /api/public/v1/products/{productId} returns the current title, identifiers, aspects, images, price, and shipping figures. Read it immediately before purchase when the latest price, availability, or shipping total affects your decision.

shipping.total is the amount charged for shipping this product on its own, and shipping.can_combine indicates whether a lower combined total currently applies. offers_allowed indicates whether the product accepts offers; see Offers for that flow.

Buying​

Call POST /api/public/v1/purchases with:

  • The product UUID.
  • A new external_id generated by your integration for this purchase attempt. Reusing an external_id returns the original result instead of buying again.

The endpoint buys one unit. Availability is rechecked during checkout, so a product that is no longer purchasable returns 404 even if it was present in an earlier search response.

The response contains the order_id, the purchased items, the amounts charged, combined-shipping state, the destination address, and tracking fields once they are available. A purchase can be added to an existing order of yours that has not yet shipped, so treat the returned order and totals as the authoritative result of the call. Store order_id; the purchase endpoints are keyed by it.

After purchase​

  • GET /api/public/v1/purchases/{orderId} returns the current order and tracking state.
  • GET /api/public/v1/purchases returns paginated order history.
  • Subscribe to purchase.created and purchase.updated instead of polling frequently.

See Errors, pagination, and idempotency before implementing automatic retries.