4Paid
Reference

EventsDocs

Everything you need to track events with the 4Paid pixel.

Installation

Add this snippet to your site's <head>. Replace the API key with yours from the Settings page.

<script src="https://4paid.com/pixel.js" data-api-key="YOUR_API_KEY" defer></script>

defer — loads asynchronously, never blocks rendering.

data-api-key — your project API key. Generate one in Settings → API Keys.

Works with any framework — Next.js, React, Vue, static HTML, Shopify, WordPress. The pixel auto-detects SPA navigation.

Auto-Captured Events

The pixel automatically tracks these interactions — no code needed.

User InteractionsClicks, forms, search, and clipboard activity.
element_click

Clicks on buttons, links, and interactive elements.

{ tag: "button", text: "Buy Now", selector: ".cta-btn", id: "checkout" }
outbound_click

Clicks on links to external domains.

{ href: "https://stripe.com/docs", text: "Docs", hostname: "stripe.com" }
form_submit

Any form submission on the page.

{ formId: "signup", formName: "register", formAction: "/api/auth" }
site_search

Search queries detected from URL params (?q=, ?search=, etc).

{ query: "pricing plans" }
clipboard

Copy and paste actions on the page.

{ action: "copy", contentLength: 128 }
file_download

Clicks on downloadable files (pdf, zip, csv, etc).

{ href: "/report.pdf", filename: "report.pdf", extension: "pdf" }
EcommerceAuto-detected on Shopify, WooCommerce, and sites with product structured data. Zero config.
product_viewed

Detected from JSON-LD, meta tags, or Shopify globals.

{ name: "Wireless Headphones", price: 79.99, currency: "USD", brand: "Acme" }
add_to_cart

Shopify fetch intercept, WooCommerce events, or cart form submissions.

{ name: "Wireless Headphones", price: 79.99, quantity: 1, variant: "Black" }
checkout_started

Fires when URL contains /checkout. Shopify enriches with cart total.

{ total: 159.98, currency: "USD", itemCount: 2, platform: "shopify" }
purchase

Order confirmation / thank-you pages. Shopify enriches with order details.

{ orderId: "5001", total: 159.98, currency: "USD", itemCount: 2 }
MediaYouTube iframes, HTML5 <video>, and <audio>. Detects dynamically-added players.
media_start

Playback started. type distinguishes video from audio.

{ src: "/intro.mp4", type: "video", provider: "html5", duration: 124 }
media_pause

Paused mid-playback. Includes current position.

{ src: "/ep-12.mp3", type: "audio", provider: "html5", currentTime: 620, duration: 1840 }
media_complete

Played to the end.

{ src: "https://youtube.com/embed/abc", type: "video", provider: "youtube", duration: 312 }
media_milestone

Fires at 25%, 50%, and 75% of playback.

{ src: "/course-lesson.mp4", type: "video", provider: "html5", percent: 50, duration: 480 }
Page LifecycleNavigation, engagement, and time-on-page.
pageview

Fires on every page load or client-side navigation. Sent as type "pageview" (not a custom event). Includes referrer, UTMs, and session count.

{ pathname: "/pricing", referrer: "https://google.com", sessionPageCount: 3 }
page_leave

Fires when the user navigates away or closes the tab. Includes active/idle engagement time.

{ timeOnPage: 34200, activeMs: 28000, idleMs: 6200, finalScrollDepth: 82, pathname: "/pricing" }
page_load_time

Captures page load timing from the Performance API after the load event completes.

{ loadTime: 1100, pathname: "/pricing" }
Performance & ErrorsCore Web Vitals and JS exceptions.
web_vitals

LCP, CLS, and INP measured from real users.

{ lcp: 1240, cls: 0.03, inp: 85 }
js_error

Uncaught JS errors and unhandled promise rejections.

{ message: "Cannot read property 'id' of null", filename: "/app.js", lineno: 42 }
IdentityLink anonymous visitors to known users.
identify

Links a visitor to a known user ID via _4p.identify(). All past and future events are tied to this identity.

{ userId: "usr_abc123", traits: { plan: "pro", email: "[email protected]" } }
Track Custom Events

Send custom events from your app with a single line of code.

track("event_name", { ...props })track("waitlist_joined", { ref: "blog", tier: "pro" })
import { track } from "@/lib/track"

// Track after successful auth
const { error } = await signUp.email({ name, email, password })
if (!error) track("signup_success", { method: "email" })

// Track onboarding progress
track("onboarding_step", { step: 3, name: "connect_domain" })
No-Code Triggers

Track specific interactions by CSS, ID, or URL — no code needed. Create triggers from the Triggers tab.

Click
css: .plan-card[data-tier] | id: dark-mode-toggle

CSS selector, ID, class, or text content

Form
id: api-key-form | action: /api/webhooks

ID, class, CSS, or form action URL

Visibility
css: .pricing-table | id: onboarding-banner

Fire when element scrolls into view

Page View
/dashboard/*/settings | /docs/api/*

Contains, starts with, exact, or regex

How it works
1Create trigger rule2Pixel matches on page3Event fires automatically

Every key-value pair attached to any event shows up here — from custom events, pixel auto-capture, and registered properties. All aggregated, all filterable.

Properties come from the second argument to track(), or use register() to auto-attach properties to every event without repeating yourself.

register()
Attach to all events automatically

Instead of adding the same properties to every track() call, register them once. They merge into every event until you unregister. Persists across page loads.

register({ plan: "pro", role: "admin" }) // auto-attached to all eventsunregister("plan") // stop attaching
import { register, unregister } from "@/lib/track"

// Set once after login — attaches to every future event
register({ staffId: "staff_42", plan: "pro", role: "admin" })

// Now every track() call automatically includes staffId, plan, role
track("page_view")  // → { staffId: "staff_42", plan: "pro", role: "admin" }

// Remove a property (e.g. on logout)
unregister("staffId")
1
track() props
Custom event data
2
register() props
Auto-attached to all events
3
Pixel auto-capture
URL, referrer, device, etc.

Link anonymous visitors to known users with identify(). Pass a user ID and any traits — the pixel ties all past and future events to that identity.

Call once after login. Any traits you pass are stored with the user and shown here.

identify()
Link visitor to user
identify("user_id", { anyTrait: "anyValue", ... })
identify("usr_1", { email: "[email protected]", name: "Sarah" })identify("usr_1", { plan: "pro", role: "admin" })

Links anonymous visitor to your user ID

Any traits you pass are stored with the user

All past & future events tied to this identity

import { identify } from "@/lib/track"

// After login — link this visitor to your user record
identify("usr_a1b2c3", {
  email: "[email protected]",
  name: "Sarah Chen",
  plan: "pro",
  company: "Acme Inc",
})
1
Call identify()
After user logs in
2
Visitor linked
Mapped to your user ID
3
Events tied
All past and future