Skip to main content

Overview

A packaged integration is a campaign whose component tree connects Extole to an outside platform, assembled from reusable component types so the same build can be installed and configured in any account. The Management API builds that campaign and its components directly in a client account. The model is the same whether or not the finished build is published to Extole’s integration library:
  • Reusable component types, not one-off controllers.
  • Typed sockets — attachment points that accept only components of a declared type, such as a views socket holding view components.
  • Business-event templates — maintained components that produce a canonical Extole event such as converted or shipped.
  • v10 component types, named with the generation as a suffix: integration-v10.1, config-view-v10.0.
  • The naming conventions and validation rules the integration passes before publication.
Examples use a generic partner named example. Substitute the real partner name, event names, and field names.

Who Packages an Integration

Packaging is platform engineering on a reusable artifact — a partner connector meant to be installed repeatedly and maintained over time. It is not a step in launching a program, and most clients never do it. Extole solutions engineers, partner engineering teams, and clients building a connector for a platform Extole does not yet maintain are the audience for this guide. If you are connecting your own systems to Extole, one of these is your path instead: Even when packaging is your job, confirm Extole does not already maintain a source for the partner before you build anything — When You Would Build One starts there.

Build with Extole AI Tools

The recommended path is to run the build through the Extole MCP server from an agentic coding tool — Claude Code, Cursor, or Codex — with the Extole CLI alongside it. Point the tool at this guide and the partner’s page, and describe the integration you need. The build suits an agent better than it suits a person:
  • It is dozens of component duplications in a required order, each needing a fresh campaign version, and one stale value rejects the call.
  • Library components resolve by name at build time, so every duplication starts with a lookup whose result is used once and never stored.
  • Verification uses the same tool surface as the build: read the component tree back, send a test event, read the resulting steps.
  • Changes execute under your own Extole permissions and are attributed to you in the change log, exactly as they are through My Extole or the API.
The curl examples throughout this guide are the underlying contract. Read them to understand what a tool did, to check a finished build, or to work through the sequence by hand.

When You Would Build One

Integration Categories describes what each category contains. A partner that both sends outcomes and receives rewards uses two paths: build the inbound half first, then add the outbound resources. Adding inbound scope to a maintained outbound partner works the same way — install the library source, then add the inbound half to the installed campaign, business events for a partner that reports activity or an audience and credential for one that sends eligibility. Check the finished integration against every category the request matched. Check for a maintained library source before building anything. Query the duplicatable listing for an integration component whose name matches the partner, not a fixed type version — a source may be typed integration-v10.0, integration-v10.1, or later, and a query pinned to one revision reports a maintained partner as missing. Rebuilding a maintained partner from custom_integration produces a campaign that does none of the partner’s webhook or credential work. When this documentation set has a page for your partner, read it first. It carries that platform’s wire contract — event names, payload fields, status mapping. Partner pages use the partner’s name as the page slug.

Client-Local Build or Registered Integration

Building the tree in one account does not register the partner for anyone else. The My Extole Integrations page lists components tagged internal:type:integration. It treats one as installed when its source client is this client, and as available to install when the source client is Extole. Two conditions decide whether a client-owned component appears at all:
  • The integration component must be a child of the campaign root. Root components are excluded.
  • Without internal:self-managed the entry renders as unavailable.
internal:integration-component-name:<component-name> is an older convention that library bundles carry for traceability. The Integrations page does not read it, so it neither reveals nor hides a build. When an integration is missing from the page, check the component’s tags, its owner, and whether it is the root.

Before You Start

Confirm the target client before the first write. A token pointed at the wrong account builds a live integration there. The last row does not block the build. Build everything that does not depend on those three values and track them as outstanding.

One Host, Two Access Tokens

Management calls and event submission both go to api.extole.io. Examples read it from EXTOLE_API_HOST:
Use separate access tokens for the two. The partner application receives only the token that can submit events, never the one that can manage campaigns and components.

How to Build

Work through the pages in order. Each build sequence is a page of its own: A campaign and an integration component alone are the container. The events, views, and webhooks are the integration.

Refresh the Campaign Version Between Mutations

Every campaign mutation creates a new version, and version-scoped endpoints reject a stale one. Read the version immediately before each mutation:
The path segment is singular — /version/{version}, not /versions/:
On stale_version or concurrent_update, retrieve the campaign, reconcile, and retry only the intended mutation.

Find Reusable Components

GET /v1/components/duplicatable returns the components this client can duplicate, including those available through subscriptions and grants:
Once the target component and socket exist, add target_component_id and target_setting_name to return only socket-compatible components. target_socket_name is deprecated. Narrowing this way matters because a widely used source such as input_event appears once for every campaign that installed a copy of it — those duplicates are copies of one maintained source, not alternative behaviors. Check each candidate’s type before duplicating, and prefer v10 when a legacy version shares the name.

Constraints

These hold on every path:
  • Resolve library components by name at build time. Stored identifiers go stale without failing loudly.
  • Use the reusable business-event, rule, and data components. Write a custom controller only where no template implements the behavior.
  • Carry all three baseline views — configuration, report-runner, and event-stream. The category decides what the report counts and what the feed filters to, not whether the tabs exist. Reward fulfillment adds a fourth, a reward-suppliers configuration view.
  • Create reward suppliers, client keys, and webhooks only for an outbound flow the integration has. An inbound integration needs none.
  • Keep partner event names and canonical Extole names separate. The trigger rule carries the wire name; the business event carries converted, shipped, or another canonical name. Renaming a business event to match a partner breaks every program and report reading the canonical name.
  • Map every field you persist, in the same pass that creates the business events. A business event with an empty data socket cannot deduplicate, attribute, reward, or report.
  • Assign key types by meaning, not spelling. A partner field named customer_id may hold the partner’s own identifier rather than an Extole person key.
  • Keep secrets in a webhook client key or protected setting — never in component descriptions, logs, or example payloads.
Reusing an active integration whose campaign and component identity already match is preferable to building a second one. Archived campaigns are not candidates: they receive no events, and an archived campaign holds no program label against a new one, so its label is free to reuse.

How to Test

Test every inbound event and every configured outbound path before you call the integration live. Inbound. Send a synchronous event to POST /v6/events with the current program label in data.labels, then read the step it produced:
Confirm the step carries the canonical event name, that the transaction identifier and value match the source record, that person keys resolve, and that resending the same source identifier produces a duplicate outcome rather than a second conversion. Repeat for every event the integration accepts. Send Platform Events to Extole covers the sending side and what to check when Extole accepts an event but no business event appears. Outbound. Trigger the Extole event the integration forwards and confirm the webhook fired against the partner endpoint. The component tree. Read the campaign and its built components back. Confirm every typed child carries its type, each webhook exists with its tags and resolved URL, and each WEBHOOK_ID setting resolves to a webhook identifier. A successful publish validates the model, not the behavior. Prehandler scripts and a data component’s valueExpression are stored without ever being executed, so only a real payload proves they run. Validate and Publish an Integration covers the full gate. The integration is not live while the campaign is in draft, a webhook is disabled, a URL is a placeholder, or an event is untested.

What to Record

Keep these identifiers as you build, for verification and for cleaning up test data:
  • Client and environment.
  • Campaign identifier, version, state, and program label.
  • Root and integration component identifiers.
  • Canonical business events and the partner trigger names that reach them.
  • Field mappings and key types.
  • View components, and the report runner and event stream each resolves to.
  • External resources created, or confirmation the category needed none.
  • Programs whose business events changed, or confirmation the integration is not yet connected to one.
  • Test event identifiers and results.
  • Partner-side steps that remain.