Overview
A prehandler is a rule that runs against an inbound event before the platform decides what the event is. It sees the untouched HTTP request and can rename the event, add and remove data, and set the app type and sandbox. Everything downstream, starting with theinput_event rules in Map Inbound Partner Events, sees only what it left behind.
When You Need One
You need a prehandler when the partner, not the client, defines the webhook payload.POST /v6/events requires event_name in the request body, and a partner webhook does not send one: platforms name the event in a body field such as type or topic, in a header, or only implicitly in the endpoint you registered, and none flatten their payload into the keys data components read.
A prehandler does that reshaping inside Extole; the alternative is a customer-built translation service this guide does not describe.
Before You Start
Give the Partner a URL It Can Post To
Partner webhook configuration usually accepts a URL and nothing else, so use the named form of the Events API:example_webhook, never converted — and match it with EVENT_NAME_MATCH.
Extole reads the access token from the access_token query parameter, an Authorization header, or a cookie, in that order, and a partner that can only set a URL has the query parameter (see Send Platform Events to Extole).
One body field is inspected at the API boundary: a top-level event_time, which must parse as a date or the delivery is rejected as invalid_event_time_format.
Render that endpoint in the configuration tab, computed from the campaign, with the partner events to enable.
Request Signatures Are Not Verified
Extole does not verify a partner’s request-signature header —Stripe-Signature, X-Shopify-Hmac-Sha256, or any other — on packaged or client-local integrations; the token in the URL authenticates the event. A condition matching a signature header therefore recognizes the partner’s traffic rather than authenticating it, working from the header’s presence rather than its contents. Escalate a demand for cryptographic verification rather than scripting it.
The partner’s webhook signing secret is not required, and the build is not blocked on obtaining it.
Create the Prehandler
A prehandler is a name, ordered condition and action lists, and a component reference:enableddefaults tofalse. A prehandler created without it is stored, listed, and never run.orderdefaults to0, and prehandlers run in ascending order — the dependency when one sets an app type another reads.- Conditions are ANDed, and an empty condition list matches everything, including web events unrelated to the partner.
example_v10_order_created_to_conversion_event.
Give each wire event its own prehandler, sequenced with order.
component_references scopes the prehandler to its component and gives context.getVariable(name) something to read; the deprecated component_ids is accepted and echoed back. An element carries at most one reference, and it resolves against the published campaign, so publish before you create.
Choose the Conditions
Recognize the partner before you reshape anything. An
EVENT_NAME_MATCH on the path segment you chose keeps the prehandler off unrelated traffic; add a header condition as a second signal, confirming the header name against a real delivery because partner header lists are often incomplete.
Two instances of one integration answer the same event name and see the same header, so scope each with an expression comparing a request value — the store URL, the partner account identifier — against that instance’s setting.
Choose the Actions
Prefer
MAP_DATA_ATTRIBUTES for a flat rename. The mapping types address top-level keys, so write an EXPRESSION for what they cannot reach: an order nested under a data key, a line-item array to sum, an amount in minor units to divide.
A reshape adds rather than replaces: addData keeps existing values, MAP_DATA_ATTRIBUTES leaves the source attribute in place, and SET_DATA removes only the keys named in delete_data.
Flatten the Whole Identity Set, Including the Email Address
A data component can only read a key the prehandler left behind, so flatten the full set Map Inbound Partner Events requires — transaction identifier, partner customer identifier, email address — on every event, including lifecycle ones. The email address is the one that gets dropped: Stripe carries it asreceipt_email on the payment intent and billing_details.email on the charge, while the ids sit at the top of the object. Extole resolves a person from person_id, email, partner_user_id, and any key a published campaign registers as PARTNER_PROFILE_KEY, but without an email address there is no destination for a reward or message.
Write the prehandler and the data mappings against one shape: a valueExpression aimed at the partner’s raw nesting captures nothing once the prehandler has flattened it.
What the Scripts Can Reach
A condition returns a boolean; an action returns nothing and mutates through the builder. Both receive a context object:getHttpHeaders() returns each header as an array, so read a single-valued header as getHttpHeaders().get("x-example-signature")[0]. getData() returns a map; packaged scripts read it as both data.get("field_name") and data.field_name, so use .get(name).
Guard every call on getCandidatePerson(): it returns null on anonymous and first-touch traffic, and an unguarded call is the most common cause of prehandler_action_execution_failure alerts.
Produce a Name This Integration Owns
Prehandlers run first, so theinput_event rule in Map Inbound Partner Events lists the name the prehandler produced. Produce a name this integration owns — example_order_completed, stripe_payment_succeeded, example_order_refunded — and leave the canonical vocabulary on the business event that rule feeds.
An input_event rule matches by case-insensitive equality on the event name and nothing else: not the app type, not the component, not the campaign. A business event’s alternate names are consulted only for the step it produces, never for an inbound event. A packaged business event’s rule listens for its own name by default, so renaming a webhook to converted at ingest points it at every converted event in the account, bypassing the integration built to interpret it.
Shopify is the exception: its prehandler produces
conversion, and it ships no business events of its own, so it deliberately owns no rules.Change a Prehandler That Is Already Live
Correct a prehandler in place by sending the create body to its own resource,/v6/prehandlers/{prehandler_id}.
An omitted field keeps its value, the only additive part of this body: a conditions or actions list that is present replaces the whole list, and a tags set that is present and empty removes every tag. The call takes no campaign version, so it does not wait on a publish, and it is validated no more than a create is.
Error Handling
How to Test
A script failure surfaces when an event arrives, as aprehandler_condition_execution_failure or prehandler_action_execution_failure notification. A prehandler that throws leaves the event unmodified rather than rejecting it, so the symptom is an integration that receives events and creates no steps.
Read the built form, which shows enabled, order, and the evaluated name as the runtime sees them:
