Blog · August 21, 2026

Publisher SDK v1.0

Publisher SDK v1.0 introduces Enhanced Tracking: consent-gated recognition that serves wallet-targeted ads on pages without a connected wallet.

What Enhanced Tracking does

Enhanced Tracking lets Specify recognise a returning visitor and serve a wallet-targeted ad when no wallet is connected on the current page. It works from wallets the visitor connected elsewhere on the Specify network.

Targeting stays based on onchain activity. Specify uses no pixels, profiles, third-party data, contextual filler, or lookalike targeting.

How recognition works

When a visitor connects a wallet on any site in the network, Specify can associate that wallet with their browser. The association lasts across visits.

With consent, one server-side cookie on Specify's own domain lets another publisher site recognise the browser and request an ad without knowing the wallet. The cookie never sits on the publisher's domain. The wallet remains the identity. The cookie only ties the browser to wallets the visitor has connected.

Clearing the cookie or changing devices removes browser recognition. Connecting a wallet again restores it.

What changes for publishers

serve() now works on blogs, docs, explorers, dashboards, logged-out views, and other pages without wallet UI. Placement responsibilities stay the same. Render a "Sponsored" label with an ad, and render nothing when serve() returns null.

Specify still returns at most one ad and never substitutes filler. The same moderation applies. Payments and reporting have not changed.

Consent and privacy

The SDK sends and sets the cookie only after the visitor consents through the publisher's consent banner or consent management platform. Specify never decides consent.

Without consent, serving behaves as it did in v0.4.x. Wallet-connected visitors can receive targeted ads, and other visitors receive none. Declining removes nothing that existed before.

Specify uses no fingerprinting or probabilistic matching and reads no other browser data. Wallet detection silently reads wallets that are already connected. It never prompts and publishers can disable it.

This consent flow maps to GDPR and ePrivacy requirements. The cookie is the only stored identifier that requires consent, and its disclosed purpose is cross-site ad targeting.

v1.0.0 removes no APIs. Every v0.4.x call still compiles and behaves the same. SpecifyAd, ImageFormats, and error classes are unchanged. There is no deprecation deadline.

Existing integrations can follow the migration guide. For integration steps, see the setup guide.

Features
  • New consent API: consentForEnhancedTracking(), revokeEnhancedTrackingConsent(), and hasEnhancedTrackingConsent(). Consent is not persisted; wire it on each page load.
  • New identify(addresses) registers wallets outside a serve call. Addresses accumulate into later serves.
  • Automatic passive wallet detection is on by default. It uses silent eth_accounts through EIP-6963 with a window.ethereum fallback and never prompts. Inspect it with getDetectedWallets() or opt out with privacy.disableWalletDetection. WalletConnect v2 sessions are invisible to detection; pass them to identify().
  • New options-only serve({ imageFormat, adUnitId }) form supports pages with no address. It resolves to null without a network request when nothing is known.
  • New destroy() tears down the SDK in single-page apps.
Changes
  • The serving endpoint moved from app.specify.sh/api/ads to spfsrv.com/api/ads, with credentialed requests after consent. Sites with a Content Security Policy must add https://spfsrv.com to connect-src.
  • Click redirects moved from app.specify.sh/r/... to spfsrv.com/r/.... Old links return a 302, and the returned ctaUrl is always correct.
Deprecations
  • cacheMostRecentAddress and its client-side cache are deprecated but still accepted with unchanged behaviour. Enhanced Tracking supersedes them with server-side recognition that survives cleared site data and works across the network.