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
viewssocket holding view components. - Business-event templates — maintained components that produce a canonical Extole event such as
convertedorshipped. - 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.
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.
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-managedthe 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 toapi.extole.io. Examples read it from EXTOLE_API_HOST:
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:/version/{version}, not /versions/:
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-suppliersconfiguration 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
datasocket cannot deduplicate, attribute, reward, or report. - Assign key types by meaning, not spelling. A partner field named
customer_idmay 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.
How to Test
Test every inbound event and every configured outbound path before you call the integration live. Inbound. Send a synchronous event toPOST /v6/events with the current program label in data.labels, then read the step it produced:
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.
