Skip to content

Advertising & Publisher Embed

United Pet Club runs its own ad engine. Partners can surface its ads two ways, both backed by the same anonymous endpoints under /api/advertising/v1/public/:

TierEffortFor
Embed scriptone script tag + one div per slotWebsites that want UPC ads inline, with revenue share
Public decision APIdirect integrationNative apps and custom front ends
  1. In the UPC Dashboard, under Advertising → Earn From Ads → Partner websites, register your domain (a bare host name such as example.com; no scheme, port, path or IP address) and verify ownership with the <meta name="upc-ads-site-verification" content="…"> tag on your home page or a DNS TXT record upc-ads-site-verification=…. Verification gives you a site key.
  2. Add the loader once per page and a container per slot:
<script async src="https://gateway.unitedpetclub.com/api/advertising/v1/public/embed.js"
data-site-key="YOUR_SITE_KEY"></script>
<div data-upc-ad="EXTERNAL_SITE_NATIVE"></div>
<div data-upc-ad="EXTERNAL_SITE_BANNER"></div>

The script collects every [data-upc-ad] element, asks for all of them in one decision call (surface: EXTERNAL_SITE, your siteKey, the page URL and <html lang>), renders a native card or a 300×250 banner with the Sponsored label and a click-through link, and hides a container that has nothing relevant to show. It is self-contained — no third-party code, no cookies; the viewer key is a random value kept in localStorage only to cap frequency. Ads on partner sites are never personalised.

Placements available to partner sites: EXTERNAL_SITE_NATIVE (one native card) and EXTERNAL_SITE_BANNER (300×250). Earnings accrue per billable impression/click under the publisher program’s site rate and are paid out from the Dashboard.

POST /api/advertising/v1/public/decisions
Content-Type: application/json
{
"surface": "MOBILE",
"slots": [{ "placement": "MOBILE_FEED_NATIVE", "count": 1 }],
"viewerKey": "random-stable-per-install",
"locale": "de-DE",
"geo": { "country": "DE", "region": "BY", "isPrecise": true },
"context": { "speciesCode": "DOG", "breedSlug": "labrador-retriever" },
"deviceKind": "MOBILE",
"consentAdvertising": false,
"pageUrl": "app://feed"
}

The response envelope carries resultCode (Advertising_Engine_GT_Decision_SU on success) and data:

FieldMeaning
slots[].placement / ads[]One entry per requested placement; an empty ads with collapse: true means render nothing
ads[].kindPAID, HOUSE, AFFILIATE, EXTERNAL_NETWORK or NETWORK_NATIVE — exactly one of creative, affiliate, external is set. NETWORK_NATIVE is an ad network’s ad that United Pet Club fetched for you: render its creative exactly like a PAID one (show advertiserName under it) and send its events the same way; there is no script to load. Treat any kind you don’t recognise as “render nothing”
ads[].token / expiresAtUtcSigned token you send back with every event; valid for 15 minutes
ads[].disclosureLabelThe label you must show on the unit (e.g. Sponsored; Affiliate link on AFFILIATE units)
affiliateAFFILIATE only: a product card (retailer, itemCode, title, imageUrl, clickUrl, priceMinor + currencyCode when a current price is known, isPrime). Show the retailer’s name (View on Chewy) and the label. Open clickUrl as-is: for retailer products it is a UPC click-through URL, for Amazon the product page
creative.clickUrlAlways a UPC click-through URL — open it as-is; the landing page is resolved server-side
creative.impressionPixelsRare, NETWORK_NATIVE only: image URLs the network counts views by. Load each once (as an image, never a script) when you send the IMPRESSION event; absent means there is nothing to load
geo.sourceWhich input decided the viewer’s region: CLIENT, PROFILE, IP or LOCALE

Report what happened:

POST /api/advertising/v1/public/events
{ "events": [ { "token": "…", "kind": "IMPRESSION" }, { "token": "…", "kind": "VIEWABLE", "viewableMs": 1200 } ], "viewerKey": "…" }

kind is one of IMPRESSION, VIEWABLE, CLICK, CONVERSION, VIDEO_START, VIDEO_COMPLETE, DISMISS. Each kind is counted once per decision — resending is harmless. Clicks should open GET /api/advertising/v1/public/c/{token}, which redirects to the landing page. Viewers can report a unit with POST /api/advertising/v1/public/reports (token, reasonCode: MISLEADING | OFFENSIVE | IRRELEVANT | BROKEN | OTHER).

Rules for direct integrations: show the disclosureLabel; never serve a slot the decision did not return; send consentAdvertising: true only when the user has actually opted in to personalised advertising in your app; request all of a screen’s slots in one call so the per-screen density limit can apply.