Skip to main content
The Signals browser API is available as window.signalq after you install the generated v3 pixel. Calls made before the asynchronous script loads remain in the queue. Connect signalq to your consent-management platform. Send the current advertising consent state after initialization and whenever the visitor changes it.
Each permission accepts granted, denied, or unknown. Missing or unrecognized permissions remain unknown; PlainRouter never upgrades them to a grant. You can provide one or more supported consent adapters: When you provide more than one adapter, their derived permission states must agree.
Do not infer consent. Leave each permission unknown until your consent-management platform has an explicit choice.
PlainRouter sends browser events only when all three permissions are granted. Granting ad_storage alone can permit local visitor state, but no event is transmitted while either downstream advertising permission is denied or unknown. A complete grant creates or refreshes the first-party identifiers used for session joins and eligible destination delivery. Denied storage, malformed input, or explicit withdrawal clears PlainRouter’s visitor and click identifiers. Send the latest structured state whenever the visitor’s choice changes. On a returning page, initialization stays fail-closed while your consent platform restores its decision: PlainRouter neither reads identifiers nor sends measurement during that undecided period. It also does not erase identifiers left by the visitor’s previous grant merely because the consent platform has not answered yet. An explicit denial, malformed consent update, or withdrawal still clears them.

Track an event

Call track with an event name and an optional payload:
The promise resolves to the collector-accepted event ID. It resolves to null if collection fails after one retry.
Send monetary value as a decimal string, such as "49.00". This avoids floating-point ambiguity.

Standard event names

Common names are normalized to Meta’s standard spelling. For example, page_view becomes PageView and initiate_checkout becomes InitiateCheckout. Frequently used standard events include:
  • PageView
  • ViewContent
  • Search
  • AddToCart
  • AddToWishlist
  • InitiateCheckout
  • AddPaymentInfo
  • Purchase
  • Lead
  • CompleteRegistration
  • Contact
  • Schedule
  • Subscribe
Custom event names are trimmed and otherwise preserved.

Payload fields

These convenience fields move into the event’s value data automatically: You can also provide a value_data object directly. Other custom fields remain on the event and are available to supported destinations.

Identify a consenting visitor

Call identify only after your consent policy permits advertising identity use:
The browser normalizes and SHA-256 hashes the values before sending them. PlainRouter never sends the raw email or phone in the identity request.
  • Email is trimmed and lowercased.
  • International phone numbers must start with + and include 8–15 digits after normalization.
  • Finnish local numbers require defaultPhoneRegion: "FI" in the initialization configuration.
  • Identification returns false on an insecure page where browser cryptography is unavailable.

Read the visitor ID

getVisitorId returns the current first-party visitor ID after consent is granted. It returns null while consent is pending or denied.
One use is attaching the value to a checkout session so a later server webhook can join the purchase to the browser visit:
Your server must copy the value into the payment or checkout metadata used by its integration.

Verify Stripe Checkout settlement

If PlainRouter is configured to receive Stripe webhooks for your Signal, copy the browser visitor ID into the Checkout Session’s metadata.visitor_id. This lets the settled server-side purchase join the consenting browser visit. Configure the Stripe webhook endpoint to receive:
  • checkout.session.completed
  • checkout.session.async_payment_succeeded
  • checkout.session.async_payment_failed
  • refund.created and charge.refunded when you track refunds
PlainRouter creates Stripe Checkout revenue only after Stripe confirms an exact payment_status of paid: Duplicate or out-of-order paid webhooks for the same Checkout Session converge on one Purchase. PlainRouter uses the settlement-confirming webhook time as the event time. Until settlement is confirmed, the Checkout Session does not enter Signals rollups or Meta delivery. Stripe refund webhooks create idempotent custom Refund events with a negative refunded value. PlainRouter links the refund to its known purchase when the order lineage is available.

Reliability behavior

  • Event requests use browser keepalive where available.
  • A granted event still in flight during pagehide is also sent as a text beacon.
  • Network failures and 503 responses receive one retry.
  • The snippet captures supported landing click IDs in memory and persists them only after consent is granted.
  • First-party browser identifiers can still have shorter lifetimes when a browser applies its own storage restrictions.

Avoid duplicate Meta events

After you connect Meta, continue to track through signalq. The managed browser Pixel and PlainRouter server delivery share one event ID. Remove other Pixel or CAPI integrations that send the same event to the same dataset after you confirm the managed flow is working.