Skip to main content
Stage three of Sending Partner Events to Extole.
You probably do not need this page. It covers building a partner platform into a reusable integration — a connector meant to be installed and maintained across accounts. To get your own purchases, shipments, or account activity into Extole, send them to the Events API or use one of the paths in Integrating with Extole; if Extole already maintains a source for the platform, install it from the My Extole Integrations page.When building one is the job, run the build through the Extole MCP server in an agentic coding tool rather than issuing these calls by hand — see Build with Extole AI Tools.

Overview

This is the core of a Partner to Extole integration: each event arriving from the partner platform becomes a canonical Extole business event.
Never rename an Extole business event to match a partner wire event: the partner name belongs in an input_event trigger rule, the canonical name on the business-event component. The three baseline views are the same for every category — see Integration Categories. This page adds a fourth, the test-events view, which lets you send an editable test event from My Extole. Build the sender against Send Events from the Partner Platform. This page assumes the event arrives with a name in event_name and its fields readable in data. When the partner’s own webhook defines the payload instead, a prehandler renames and flattens it first — see Normalize Partner Events with a Prehandler.

Add Reusable Business Events

Choose the template by meaning:
  • template_transacted_business_event — the event carries transaction value or represents the program outcome.
  • template_tracked_business_event — a lifecycle milestone without transaction value.
Duplicate the source into the businessEvents socket:

Name Each Event for Its Outcome

Use the canonical v10 name for the business outcome: converted, shipped, canceled, returned, account_opened, application_approved. Do not use a transport-specific name such as partner_order_created, and do not create duplicate legacy controllers alongside the reusable component. Create one business event per distinct outcome. Two wire events share one only when nobody would need them apart in a report, a rule, or a clawback: a refunded charge is returned, not canceled.

Set the Reporting and Ordering Variables

Set these on every duplicate: Two events from the same template report under identical labels until you override these: a tracked template calls everything “Tracked Events” with a “Tracked Event Rate”, and singularNounName defaults to an expression echoing the display name.

Set the Alias Set the Platform Already Uses

Set aliases to the set the platform already uses, read from an existing program’s business event of the same name. They are additional names the business event matches, and platform consumers subscribe to them: an extension listening for outcome sees a converted event only because converted carries that alias. Do not invent partner-flavored aliases or clear a set the template provides. One alias must never appear on two business events in one campaign, which makes the match ambiguous.

Preserve the Journey and Role Defaults

Inspect the duplicated component’s evaluated journeyName and roleName. Both depend on the surrounding role and journey hierarchy, so keep the template’s defaults unless the contract requires otherwise, and record the published values during verification.

Configure Input Event Rules

Duplicate input_event from the rules program into each triggerRules socket:
Keep the duplicated rule under its source name input_event, and put the partner event name in triggerEventNames. When a prehandler renames the event, list the name the prehandler produces — an integration-owned name such as example_order_completed, never the canonical name the business event carries. A rule still listening for the wire name never matches, and reads as correct in the component tree. Add a legacy alias only when a real sender still emits it.

Configure Event Data

Create the data components in the same run as their business events. A business event with an empty data socket produces a step with no transaction identifier, no person key, and no value, so nothing downstream can deduplicate, attribute, reward, or report on it. Take the field names from the partner’s documented payload — a partner page in this documentation set, the partner’s developer documentation, or a captured sample. One unknown field does not defer the rest. Define the mapping first: Duplicate one business_event_data component into the data socket for each field:
Set valueExpression explicitly when the partner field and Extole field have distinct names — do not rely on the name-derived default — and verify it against a real sanitized partner payload. Use NO_ADDITIONAL_DATA when the event must store only declared fields, and capture no more than identity, deduplication, attribution, rules, and reporting need.
Quote the key with escaped double quotes, as above. A single-quoted --data payload cannot contain single quotes: the shell closes the string at the first one, so getData()['order_id'] reaches the API as getData()[order_id], which reads an undefined variable instead of the partner field and silently captures nothing.
Give every business event its own data components; a field captured on one is not visible on another:
  • Identity, on every event: the partner customer identifier as PARTNER_PROFILE_KEY when the partner sends a stable one, email when it is the only identity available.
  • The transaction identifier as UNIQUE_PARTNER_EVENT_KEY, on transaction events, so an event tied to a partner-side record can deduplicate. A standalone event such as account_opened has none.
  • The amount as VALUE, on revenue events.
Lifecycle events such as shipped and canceled arrive independently, so repeat the identity set on each: they must resolve to the same person and, through the transaction identifier, the same original transaction.

Add the Test Event Payload

The test event payload lets you, and anyone who installs the integration, send a sample partner event from My Extole and watch what it produces. Add it after the business events and input rules exist, because the payload is only useful once there is a rule for it to match. Add a testEventPayload JSON setting to the integration component. The setting holds a complete POST /v6/events request body, and My Extole sends it exactly as written. Include:
  • event_name: the partner wire event name your input_event rule listens for.
  • event_time: optional.
  • data: representative identity and event fields, the current program label, and container set to test.
  • advocate.email in data: a sample advocate address, distinct from the friend’s email, when the event produces a FRIEND journey.
For a prehandler-backed integration, set event_name to the path segment the prehandler matches with EVENT_NAME_MATCH, and put the partner’s raw webhook body in data. Extole reads that the same way as a partner delivery to POST /v6/events/{event_name}, so the prehandler receives the event name and data it would receive from the partner. A test event carries no partner HTTP headers, so a prehandler that requires a partner header never runs for it. Normalize Partner Events with a Prehandler shows how to write a header condition that also accepts test events.
Then add a config-view-v10.0 child named test-events to the integration component’s views socket, with settingsToDisplay naming testEventPayload. My Extole renders that setting as an editable JSON payload with a Send Event button, on a tab labeled with the view’s title.

How to Test

A successful send proves only that Extole accepted the event. To prove the mapping works, follow the event through the integration’s event stream until you see the business event it produced.

Prepare the Event Stream

Before you send anything, open the integration’s event-stream tab and confirm the stream is running and filtered to INPUT and STEP. Add the Activity and Event Views shows how to create that filter. The filter keeps the input event and the business-event step, and leaves the rest of the account off the feed. Search by the event’s identifier to pick this send out of what remains.

Send the Test Event

Open the integration’s Test Event tab, edit the payload with representative values, and click Send Event. My Extole confirms with the accepted event ID; copy it for the next step. The control sends the payload exactly as written and adds nothing, so every field the event needs must be in the payload.
  • Keep container set to test in data. To test another wire event, change event_name and the event-specific fields.
  • For a prehandler-backed integration, keep event_name as the segment the prehandler matches, and edit the partner’s body inside data.
  • For a FRIEND journey, keep advocate.email distinct from the friend’s email.
The test container keeps the event out of production dashboard analytics and reports. It does not turn off event processing or rewards, so a test event on a live program can still issue a reward. See Exclude Test Data from Analytics. The Send Event control and My Extole chat both send with your signed-in session, so neither needs a token. Never paste an access token or other credential into My Extole chat. To send from outside My Extole, submit the same payload to POST /v6/events with an event-submission token, not the token that created the campaign. The program label in data targets this campaign for the test; it does not belong in the partner’s production payload. The synchronous response returns the event_id and person_id.

Follow the Event in the Stream

In the event-stream tab, search with Event Stream Query Language, replacing EVENT_ID with the identifier you copied:
  1. Search event_id=EVENT_ID to find the INPUT event.
  2. Search root_event_id=EVENT_ID to find every event it caused.
Open the JSON for the INPUT event and the events it caused, and check:
  • The INPUT event’s name is the wire event you sent. Its raw_data holds the payload as Extole received it, including container and, for a friend journey, advocate.email.
  • One of the caused events has type STEP and the canonical name. That is the business event. Its data holds the mapped values, and its person_profile matches the person on the INPUT event.
  • The STEP event’s campaign_context.quality is HIGH or LOW, which means a campaign selected it. NONE, or no campaign_context at all, means Extole recorded the event without attributing it to a campaign.
  • duplicate is true when Extole already processed an event with the same unique partner event identifier. Expect that only when you are testing duplicate handling.
When no campaign selected the event, step_matching_campaign_contexts lists each campaign that considered it. Its trigger_results and log_messages, together with the INPUT event’s own log_messages, name the rule that did not match. Correct the mapping or rule that differs from what you expected, republish if the change requires it, and send a new event with a new unique identifier. If the stream stopped, or the filter no longer lists INPUT and STEP, restart the stream or restore the filter first.

Confirm the Result on the Person

If you sent from the command line, you can also confirm the result through the API with the returned person_id:
Confirm the canonical event name and every mapped value match what the stream showed.

Cover Every Case

Repeat the test with a new unique identifier each time, unless duplicate handling is what you are testing, until you have covered:
  • Every preferred partner input event.
  • Referral creation for each FRIEND journey event.
  • Test-container isolation from production dashboard analytics and reports.
  • Every supported legacy alias.
  • Missing required identity.
  • A repeated unique partner event identifier.
  • Invalid amount and status values.
  • Partner retry behavior.
  • Campaign targeting with the current program label.
  • Configuration view contents and status.