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:
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.
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 Metafalse- 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:
Send an event using the API
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.