Marketplace listing
A live offer to sell a bottle. Visible and purchasable.
Draft listing
A staged listing, visible only to the selling pharmacy. Not purchasable.
Cash offer
An offer to buy a medication at a stated price.
Marketplace listings
An offer to sell a particular bottle of medication.POST /api/v1/marketplace-listings
creates one; sellingPharmacyNpi determines which pharmacy is selling.
A listing can be updated with PUT or cancelled with DELETE only while it is Pending
— that is, unsold. Once purchased, both return 409 Conflict.
Two fields deserve attention beyond their validation rules.
DSCSA certification
dscsaCertified must be true. It is not a formality — it records the selling pharmacy’s
attestation that:
The item has been stored and handled under the manufacturer’s temperature and storage requirements, was not purchased using a government discount program (i.e. 340b) or preferred pricing, is not restricted to a limited distribution network, and was acquired from a manufacturer or wholesaler in compliance with the Drug Supply Chain Security Act (DSCSA). Seller further must agree that if asked to provide DSCSA T3 data in support of these facts, such data will be provided. Seller further must agree that InStockRx will deduct transaction fees of 10% of the purchase price, minus any credits, as applicable, if this medication is sold to a buyer. Seller must agree that you are authorized to sell this medication under the DSCSA and affirm that all of the required representations are true.
State restriction
showOnlyInState, when true, limits buyers to pharmacies in the same state as the seller.
The created listing returns a stateGroupId — a GUID when the restriction applies, null
when it doesn’t. The request field and the response field are deliberately different.
Quantity
quantity depends on fullPackage:
The 2D scan claim
populatedByTwoDScan records that the listing’s pedigree — gtin, serialNumber,
lotNumber and expirationDate — was captured by scanning the package’s 2D barcode
rather than typed in by hand.
It is not a cosmetic flag. Elsewhere on the platform a buyer can post a cash offer that
only a scanned listing may fill, so the flag decides whether your listing is eligible for
that kind of offer. An explicit false also costs the listing 0.1 of its rating once it
reaches a terminal state, and that rating feeds the selling pharmacy’s average — so it
follows the pharmacy, not just the listing.
The field is writable on PUT /api/v1/marketplace-listings/{id} and readable on search
results, but it is not on the create body. A listing created through v1 therefore starts
with no claim either way; set it with an update if a scan populated the pedigree.
Draft listings
A draft is a listing that isn’t live yet. It’s visible only to the selling pharmacy and can’t be bought, so it can be created with less information than a marketplace listing and filled in over time. The common use: the bottle is known, but the price isn’t decided. Create the draft now, set the price later, publish when ready. Pharmacy users publish drafts from the Draft Listings tab of their selling activity page, which converts the draft into a marketplace listing. Drafts are managed at/api/v1/draft-listings with the same create, update and cancel
pattern.
Cash offers
An offer to buy — the mirror image of a listing. Managed at/api/v1/cash-offers.
Where a listing describes a bottle you have, a cash offer describes a bottle you want,
with requirements attached: requireFullPackage, requireSealedPackage,
requireOriginalPackage, requireIntactPackageLabel and requireCertificationFile.
requireCertificationFile means “only fill this offer from certified listings.” When the
drug package requires certification, the field is mandatory and must be true —
otherwise the request is rejected.shippingRequestMethod. Medium requires a positive
maxShippingPrice; the other supported methods require it to be null or zero, and
Custom is not supported when creating a cash offer through this API. See
Enumerations.
Searching
All three types share a search pattern:POST to /search under the relevant path, with a
searchingContext that selects the perspective.
Search results are paginated with
start (offset, default 0) and take (page size,
default 10).
The response envelope
Every search returns the same wrapper rather than a bare array:
Page by comparing
start + take against recordsFiltered — data.length alone can’t tell
you whether you’ve reached the end.
Open returns on a listing
A marketplace listing search result carriesactiveReturn, which is populated only while a
return is open on that listing and null otherwise:
null means “no return is open” — not “no return ever happened.” A finished return, an
approved one the buyer kept, and a rejected request all read as null here. To see how a
return ended, read the listing’s own status: a completed return cancels the listing with
MarketplaceListingCancellationReason 5 — ReturnCompleted.