Overview

In the vast majority of cases, you do not need to use the Programmatic Tracking API. You can track page views, button clicks, form submissions, and e-commerce events out of the box via assigning events to particular URLs or via tagging interactive elements via classes without any developer involvement. This API is designed for advanced use cases that cannot be handled by standard tracking.

When the Programmatic API Makes Sense

Consider using the Programmatic Tracking API only when:

  1. Granular Event Control Required – You need precise control over when events are sent based on complex business logic, conditional workflows, or specific application states that automatic tracking cannot detect.

  2. Application-Level Data Access – You have customer or product data available in your application's JavaScript context (user objects, cart state, session variables) that you want to send with events without rendering them to the DOM and assigning CSS classes to appropriate elements.

Using this API requires developer involvement and JavaScript knowledge. If your tracking needs can be satisfied by PixelFlow's standard functionality, we recommend using those methods instead.

What This API Provides

PixelFlow's Programmatic Tracking API exposes the trackEvent function globally via window.pixelFlow.trackEvent(), along with utility functions for data normalization and hashing to ensure your data meets Meta's Conversions API requirements.

Getting Started

Wait Until PixelFlow Initializes

Prepare your payload (custom data) and normalized user data, then call the trackEvent function:

// Wait for PixelFlow to initialize, then track event
const trackPurchase = async () => {
  if (
    window.pixelFlow?.trackEvent &&
    window.pixelFlow?.utils?.normalizeCustomerData
  ) {
    try {
      const normalizedCustomerData =
        await window.pixelFlow.utils.normalizeCustomerData(customerData); // normalizes and hashes data 
      window.pixelFlow.trackEvent("Purchase", payload, normalizedCustomerData);
    } catch (error) {
      console.error("PixelFlow: Error tracking Purchase event", error);
    }
  } else {
    console.warn("PixelFlow: API not ready, retrying...");
    // Retry after 1 second if not ready
    setTimeout(trackPurchase, 1000);
  }
};

The trackEvent Function

Function Signature

trackEvent(
  eventName: string,
  customData: CustomData,
  userData: UserData
): Promise<boolean>

Parameters

1. eventName (string, required)

The name of the event you're tracking. Use Meta's standard event names.

2. customData (CustomData, required)

Object containing event-specific data like product information, pricing, and custom properties.

Common Properties:

{
  value: number;              // Monetary value (required for Purchase, recommended for value optimization)
  currency: string;           // ISO 4217 currency code (e.g., "USD", "EUR", "GBP")
  content_ids: string[];      // Product SKUs or identifiers
  content_name: string;       // Product or content name
  content_type: string;       // "product" or "product_group"
  contents: ContentItem[];    // Detailed product information
  num_items: number;          // Quantity of items
}

Pass an empty object {} if no custom data is needed, but never pass null or undefined.

3. userData (UserData, required)

Object containing customer information for better ad targeting and attribution.

Common Properties:

{
  em: string; // Email address (normalization and hashing required)
  ph: string; // Phone number (normalization and hashing required)
  fn: string; // First name (normalization and hashing required)
  ln: string; // Last name (normalization and hashing required)
}

Return Value

Returns a Promise<boolean>:

  • true - Event successfully queued and sent to Meta

  • false - Event failed to send (check console for errors)

The promise resolves after the event is queued, not after confirmation from Meta's servers. Check Meta Events Manager for actual event delivery status.

Available Utility Functions

PixelFlow exposes utility functions at window.pixelFlow.utils for data preparation:

Data Normalization Functions

Use these functions to prepare customer data before passing to trackEvent:

// Normalize entire customer data object
const normalizedData = await window.pixelFlow.utils.normalizeCustomerData({
  em: "[email protected]",
  fn: "  John  ",
  ln: "Doe",
  ph: "(555) 123-4567",
});
// Returns normalized and ready-to-use object

// Email normalization (lowercase, trim)
const normalizedEmail =
  window.pixelFlow.utils.normalizeEmail("[email protected]");
// Returns: '[email protected]'

// Name normalization (lowercase, trim)
const normalizedName = window.pixelFlow.utils.normalizeName("  John  ");
// Returns: 'john'

// Phone normalization (digits only, add country code)
const normalizedPhone = window.pixelFlow.utils.normalizePhone(
  "+1 (555) 123-4567",
  "US"
);
// Returns: '15551234567'

// Generic alphanumeric lowercase (for city, state, etc.)
const normalizedCity = window.pixelFlow.utils.normalizeAlnumLower("New York");
// Returns: 'newyork'

// Postal code normalization
const normalizedZip = window.pixelFlow.utils.normalizePostal("94103-1234");
// Returns: '94103'

// Country code normalization
const normalizedCountry =
  window.pixelFlow.utils.normalizeCountry("United States");
// Returns: 'us'

Real-World Examples

Example 1: Track Custom Form Submission

Scenario: Multi-step lead form where you want to track completion only after backend validation.

// After form validation succeeds on server
async function onFormValidationSuccess(formData) {
  // Prepare user data from form
  const userData = await window.pixelFlow.utils.normalizeCustomerData({
    em: formData.email, 
    fn: formData.firstName, 
    ln: formData.lastName,
    ph: formData.phone,
  });

  // Prepare custom data
  const customData = {
    value: 500, // Estimated lead value
    currency: "USD",
  };

  // Track the lead event
  const success = await window.pixelFlow.trackEvent(
    "Lead",
    customData,
    userData
  );

  if (success) {
    console.log("Lead tracked successfully");
  } else {
    console.error("Failed to track lead");
  }
}

Example 2: Track Third-Party Integration Event

Scenario: Stripe payment widget where you need to track the purchase event after successful payment.

// Stripe checkout success handler
stripe.on("checkout.session.completed", async (session) => {
  // Extract purchase data from Stripe session
  const purchaseData = {
    value: session.amount_total / 100, // Convert cents to dollars
    currency: session.currency,
    contents: session.line_items.data.map((item) => ({
      id: item.price.product,
      quantity: item.quantity,
      item_price: item.price.unit_amount / 100,
    })),
    num_items: session.line_items.data.reduce(
      (sum, item) => sum + item.quantity,
      0
    ),
  };

  // Extract customer data
  const userData = await window.pixelFlow.utils.normalizeCustomerData({
    em: session.customer_email,
    fn: session.customer_details.name?.split(" ")[0],
    ln: session.customer_details.name?.split(" ").slice(1).join(" "),
  });

  // Track purchase event
  await window.pixelFlow.trackEvent("Purchase", purchaseData, userData);
});

Test in PixelFlow Dashboard Events Page

Always verify events appear correctly in PixelFlow Events log:

  1. Send an event using the API

  2. Go to https://dashboard.pixelflow.so/dashboard/events

  3. Find your event, expand the event row and verify the event payload sent to Meta contains all the expected data

Events tracked programmatically will appear alongside your automatic events in the dashboard, making it easy to monitor and debug your implementation.

Was this helpful?