Skip to content

Animal listings API

Base path through the gateway: /api/animallisting/v1. The public surface lives under /public and needs no bearer; everything else needs a signed-in profile. Every response is the platform envelope { data, resultCode } — resultCode values come from the AnimalListing response-code category, and the wire message is intentionally empty (the UI catalogue supplies the text). This page is the reference. The service’s own OpenAPI document is for UPC platform staff only.

Feature gate. The service sits behind the animal-listings feature key. On an environment where it is not released the gateway answers a bare 404 for every route below — that is the gate, not a missing endpoint.

Animals are listings, never store items. An animal or a litter is not a Catalog item, a Marketplace offer, a cart line or an order line, and no Catalog kind or Marketplace subject describes one (the old ANIMAL_LISTING_TEMPLATE item kind and LITTER offer subject were retired in October 2026). The only money that moves through UPC for an animal is the protected deposit on its listing. A cart or checkout call with an ANIMAL_LISTING line is refused (422).

GET /public/listings — query parameters:

ParameterMeaning
qfree text over title, breed and description
kindSALE, ADOPTION, REHOMING, FOSTER, STUD_SERVICE, LITTER, PLANNED_LITTER (repeatable)
species, breedtaxonomy ids (repeatable)
sex, ageBand (BABY / YOUNG / ADULT / SENIOR), size (XS…XL)repeatable
priceMin, priceMaxUSD minor units (prices are normalised for filtering; the card carries the seller’s currency)
country, subdivisionISO codes
lat, lng, radiusKmdistance filter; use sort=distance
sourceKindUPC, RESCUE_FEED, RESCUE_SITE
rescueOnly, verifiedSellerOnlybooleans
trustTier, ratingMinseller trust tier code; minimum rating
flagshealthTested, vaccinated, microchipped, altered, registered, titledParentsVerified, goodWithKids, goodWithDogs, goodWithCats, shipping, delivery, videoCall …
sortrelevance (default), newest, priceAsc, priceDesc, distance
page, pageSize (max 60), localepaging and display language

The result carries items (cards), paging, and facets — one array per dimension (kind, species, breed, sex, age band, size, price band, country, subdivision, source kind, trust tier, rating band, flags), each entry { value, label, count, selected }. Facet counts are computed with every other selection applied, so a selected value still shows its siblings. Promoted results are flagged isPromoted and always labelled in the UI; they never displace organic results beyond the promoted bucket.

  • GET /public/landing/{kind}/{species}/{breed?} — a search result plus localised headings for SEO hub pages (/public/landing/adoption/dog).
  • GET /public/listings/{shortCode} — card, media, items (per-animal availability for litters), declared parents (with the admin-verified titled flag), seller block, similar listings, and jsonLd (ItemPage; animal pages are never Offer/product data). Imported listings carry an attribution block (source name, source URL, attribution URL, last sync, claimed flag) and have inquiries disabled — contact goes to the source. attributes holds the listing’s extra details by key, including the seller’s answers to the questions some kinds of listing ask (for example rehomingReason and biteHistory = yes / no on a rehoming listing).
  • GET /public/listings/{shortCode}/similar — same species / breed / kind nearby.
  • GET /public/profiles/{profileId}/listings — a profile’s public listings (paged).
  • GET /public/profiles/{profileId}/showcase?surface=PROFILE|PETLINK — the listings the profile pinned for that surface.
  • GET /public/profiles/{profileId}/summary — counts by kind for profile headers.
  • GET /public/lookups/{set} — listing-kinds, listing-statuses, subject-kinds, source-kinds, price-kinds, report-reasons, size-bands, age-bands, … localised by locale.
  • GET /public/policy/summary?country= — the public policy facts a page may state (listing period in days, minimum photos, deposit cap, waitlist offer hours, promoted-label rule).

POST /public/listings/{shortCode}/inquiries (message; contact details in the text are masked; one conversation per listing and inquirer; velocity limited → 429), POST …/waitlist (preferences → position), POST …/items/{itemId}/deposits (returns the checkout session the client completes with the Payment SDK; the item is held for the checkout window), POST …/reports (reason code, note). The member’s own side lives under /me/* (saves, saved searches with instant or daily alerts, inquiries, waitlist entries, deposits, showcase).

400 …_VL_Request_RJ (inline), 403 eligibility / ownership / inquiry rejected, 404 …Discovery_GT_Listing_FL (listing not public), 409 state / waitlist / deposit conflicts, and since 2026-10-12 409 AnimalListing_AnimalListingListing_AD_Ceiling_RJ when the signed-in profile reaches one of its listing limits (saved searches, showcase slots, and the seller-side listing, photo, video, deposit and promotion limits) with data.ceiling = { featureCode, window, limit, used, band, resetsAtUtc, raisedBy }, the same shape as the litter limit; the limits depend on the profile’s kind, verification, age and trust tier and are not entitlements; 422 publish policy / jurisdiction / screening (checklist in the detail), 429 velocity (retryable), 502 payment unavailable (retryable).