xMatix
Sign in Request demo
xMatix
PRODUCTS
SalesField Sales & SFACRMRewardsClaimsInventoryProcurementWarehouse ManagementField ServiceServiceSupportTelephony & MessagingFinance & AccountingPayrollExpense ManagementCommercePortalsAnalytics & ReportingData StudioMobile AppSee all products →
PLATFORM
Platform overviewApp BuilderAutomationIntegrationsSecurity & GovernanceChange ManagementDevelopers
SENSE AI
Sense AI overviewSense AssistSense ControlSense VisionAI StudioTrust & governanceIn Claude & ChatGPTUse cases
SOLUTIONS
Auto DMSConsumer Goods DMSSales Force Automation (SFA) FMCG & DistributionManufacturing & Dealer NetworksAutomotive & DealershipsPharma & HealthcareConsumer DurablesAgri-InputsBuilding MaterialsService NetworksWarehousing & 3PLFinancial AccountingERP SoftwareIndia GST ComplianceUAE VAT & e-InvoicingSaudi ZATCA & VATAll solutions →
RESOURCES
Knowledge CenterDeveloper & CLIBlogGuidesWhat is xMatix?Company facts
COMPANY
AboutCareersPartnersEventsContactAuthorsLegal
Sign in Request demo
Home/Docs/Integrations/Connect an external system
HOW-TO · Last reviewed

Connect an external system

VIDEO
Connecting an external system
A 5-minute walkthrough of this page is coming soon — the written steps below cover the same ground.

This walk-through takes one external system from nothing to a working integration: an app to own it, a secret for its credential, a tested connection, an entity binding, a published flow, and a first verified run. The same skeleton sits under every integration — including sync profiles, which build the flow part for you.

Overview

An integration app is the container for everything that talks to one external system. Once the app is saved, it gets its own set of pages in the Setup menu, listed under the app's name: Overview, Connections, Entity Bindings, Flows, Triggers, Approvals, Staging, Errors, Browser jobs, Secrets, Client credentials and Members. You set up an integration by working through those pages in this order:

PieceWhat it holdsPage
SecretAn encrypted credential, used by its reference nameSecrets
ConnectionThe connector type and its settings (URL, account, headers)Connections
Entity bindingThe xMatix entity the integration reads or writes, and howEntity Bindings
FlowA step graph (source → transforms → sink), in numbered versionsFlows
TriggerWhat starts a run: schedule, poll, webhook, record event, data lake event or manualTriggers
RunOne execution, with status and step dataOverview → Recent Runs

Prerequisites

  • The Manage integrations capability. It controls Setup → Platform → Integrations and lets you create an app. Everything inside an app also needs a role on that app (see Permissions). Creating an app gives you that role automatically.
  • Credentials for the external system: an API key, a token or OAuth client details, depending on the connector.
  • The xMatix entity you will read from or write to.
  • In a sandbox tenant, an extra switch on the app (see Configuration).

Procedure

Step 1 — Create the integration app

Go to Setup → Platform → Integrations and select New. The New integration app dialog asks for one thing: Name (for example, Finance ledger sync). Name the system and the purpose, and never put a credential in the name. Select Create.

The new integration app dialog: one Name field with Cancel and Create buttons

The app is created as Active. You and the System Administrator profile get the app's Admin role, and the app gets a Public ID, which appears on its Overview. Open the app from the list to see its pages. To change the name, switch the app off, or set Run as user, select Edit on the Overview.

Step 2 — Store the credential as a secret

Open the app's Secrets page and select Add Secret. Fill in Reference, the name you will use in configuration (letters, digits and . _ - : only — for example ledger-token), and Value, the credential itself. Select Save.

The value is stored encrypted and never shown again. Everywhere else you type the reference instead of the value: ${secret:ledger-token}. For rotation, see credentials and rotation.

Step 3 — Create and test the connection

Open Connections and select New Connection. Fill in Name, leave Active on, and choose a Connector Type. The configuration panel then shows that connector's own fields. You can also switch on Raw JSON and edit the settings directly. When a field needs a credential, enter the secret reference, never the value. Select Create.

Test Connection works only on a saved connection. Open the connection again with Edit and select Test Connection. You see Connection OK or Test failed, with a message underneath. Read it carefully, because each connector tests something different:

  • HTTP REST sends a single request to the URL. Any response below 500 counts as reachable, so a 401 or 403 still shows Connection OK. Check the HTTP status in the message.
  • Salesforce REST and Zoho do the sign-in (token exchange) only. Bad credentials fail the test.
  • SFTP connects to the host. Web site (browser) runs a short browser job and may ask you for input while it runs.
  • A secret reference that does not exist is filled with an empty value during the test, so the test can still pass. A real run stops before the call instead.

Step 4 — Bind the entity

Open Entity Bindings and select New Binding. Fill in:

  • Entity: the xMatix entity. You cannot change it after you create the binding.
  • Entity View (optional): limits the binding to a view of that entity. Leave it empty to use the whole entity.
  • Direction: Inbound, Outbound or Bidirectional (default Outbound).
  • Write Mode: Create, Update or Upsert (default Upsert).

Under Governance & staging you can also switch on Require operator approval before commit, Use staging table before publish and Bulk write. Select Create.

Step 5 — Create the flow and design a draft

Open Flows and select New Flow. This button stays disabled until the app has at least one binding. Fill in Name. The Slug fills itself in from the name, in lower case; you can edit it. Then pick the Entity Binding and the Direction, and select Create. For Inbound and Bidirectional flows, the list shows the flow's inbound address, POST /ingest/{appPublicId}/<slug>.

Select the flow's name, or Design, to open the flow designer. On a new flow, select Create first draft. Add steps from the palette and connect them: typically a source, one or more transforms, and a sink. Then select Save draft. If the graph is invalid, the draft is not saved and the errors are listed.

Step 6 — Preview the draft

Select Preview, paste a realistic Sample input, and select Run preview. The preview runs the saved version, not unsaved edits, and is a dry run:

  • Source steps simply pass the sample along.
  • Map, filter, batch, flatten and for-each transforms really run, so you can check your field paths.
  • Lookup steps pass their input through unchanged. At run time they do read xMatix.
  • Sink steps are Not executed: the preview shows the input they would receive. The exception is an HTTP response step, which does show the reply it would send.
  • A script step shows Error. Script steps are not implemented and fail at run time too, so use map, filter or for-each instead.

A clean preview shows that the flow is shaped correctly and the mapping works. It does not prove that the external system is reachable or will accept the data.

Step 7 — Publish the version

Select Publish version and confirm with Publish. The graph is checked again. If another version was published before, it stops being the published one, and runs use the new version from then on. A flow has only one published version at a time.

A published version cannot be edited. To change it, select Edit as new draft, which copies it into the next version number. Then edit, save and publish that version. Use Versions to switch between versions and Compare versions to see what changed.

Step 8 — Add a trigger and fire it

Open Triggers and select New Trigger. Pick the Flow and a Trigger Type:

  • Schedule (cron) or Poll (cron-driven connector read): fill in Schedule (cron expression). The schedule editor helps you build it.
  • Webhook (inbound HTTP): needs a slug and a secret reference used to check each request's signature. The trigger cannot be saved without both.
  • Entity Event (record change): pick an Entity, the Events (Create, Update, Delete) and an optional Filter.
  • Data Lake Event: fires on data lake builds and landings.
  • Manual (user-initiated): fires only when you start it. This is the best choice for a first test.

Leave Active on and select Create. On the trigger's row, select Fire now, enter a small JSON payload (or leave {}), and select Fire now again. For a flow about one record, put the record's id in the payload so that ${trigger:id} has a value. Each click starts a new run.

Step 9 — Verify the run

Open the app's Overview. Recent Runs shows the run with its Status: Pending, Running, PendingApproval, Succeeded, Failed and so on. Open Step data to see what each step received and returned. Failed runs always keep their step data. Then check the records themselves, in xMatix or in the external system, because that is what you are testing.

Expected result: the connection test shows the status you expect, the run reaches Succeeded, and the record appears or changes in the destination.

Business rules

  • Run as user. Every flow in the app reads and writes xMatix as the app's Run as user. If that is empty, flows run as the System Process user, which has no security profiles, so writes to secured entities are denied.
  • Everything must be on. A run starts only if the app, the trigger and the flow's published version all allow it. A switched-off app refuses every run with "Integration app is disabled. Re-enable the app to resume its flows."
  • Write modes. Create always adds a new record. Update needs a target: an id in the payload, or an external key the app has already mapped; without one the step fails. Upsert updates when it finds a target and creates otherwise. When an external key is supplied, the new record is mapped to it, so the next run with the same key updates the same record instead of adding a duplicate.
  • Approval. If a binding requires approval, an inbound write stops and the run shows PendingApproval. An Operator decides it on Approvals.
  • Deleting. Deleting a flow removes its triggers, versions and run history. Deleting an app removes all its connections, bindings, flows, triggers, runs, secrets and role assignments. Neither can be undone.

Example

Suppose a field team needs new Account records sent to an external ledger service.

  1. Create the app Ledger accounts.
  2. Add the secret ledger-token.
  3. Create an HTTP REST connection named Ledger API, with the service's base URL and an Authorization header of Bearer ${secret:ledger-token}. Test Connection shows "Reached … (HTTP 200)".
  4. Create an Outbound binding on Account, then the flow Account to ledger. In the draft: source → map (name ← Name, code ← AccountNumber) → a connector write to Ledger API. Preview with a sample Account and confirm the mapped output.
  5. Publish v1. Add a Manual trigger and fire it with {"entity":"Account","op":"Create","id":"<an account id>"}.
  6. Recent Runs shows Succeeded, and the account appears in the ledger. Finally, add an Entity Event trigger on Account for Create, so new accounts are sent automatically.

Training

Practice exercise

In a sandbox, create an app, switch on Allow sandbox execution, and add an HTTP REST connection to a test endpoint. Bind an entity, build a source → map → sink draft, preview it, publish v1, and fire a Manual trigger. Expected result: Recent Runs shows one Succeeded run, and its Step data shows your mapped fields. Then pause the trigger and check that Fire now is unavailable.

Quick reference

  • Setup → Platform → Integrations → New creates an app; its pages appear under the app's name.
  • Put credentials in Secrets; type ${secret:<reference>} everywhere else.
  • Save a connection before you test it; HTTP REST "OK" can hide a 401 or 403.
  • New Flow needs a binding first.
  • Preview runs transforms only; sinks are not executed.
  • Publish version makes a draft live; published versions cannot be edited, so use Edit as new draft.
  • Fire now works only on an active trigger and starts a new run each time.
  • An empty Run as user means secured writes fail.

Permissions

To do thisYou need
See Setup → Platform → Integrations and create an appManage integrations capability
Open an app, see runs, errors and approvalsApp role Viewer or higher
Preview a flow, replay or cancel runs, decide approvalsOperator
Create, edit and test connectionsConnection Manager
Edit the app; manage secrets, members, bindings, flows, versions and triggers; fire triggersAdmin

Roles build on each other: each one includes the roles above it in the table. They are given to security profiles on the app's Members page (Grant Profile). If you have the capability but no role, you can see the app in the list, but opening it shows "You don't have access to this integration app".

Configuration

  • Active (app's Edit dialog): switch it off to stop every run of the app without deleting anything.
  • Run as user (app's Edit dialog): the identity whose security profiles limit what flows can read and write.
  • Allow sandbox execution (app's Edit dialog, shown only in a sandbox tenant): flows in a sandbox are refused until this is on. Turn it on only once the connections and secrets point at test systems.
  • Binding governance: approval, staging and bulk write, under Governance & staging.
  • Capture step data (flow designer, This version): keeps step data for successful runs too.
  • Members: which security profiles get which app role.

Common problems

I can see the app in the list but cannot open it

You have the Manage integrations capability but no role on the app. Ask an app Admin to grant one of your security profiles a role on Members.

New Flow is greyed out

The app has no entity bindings yet. Create one on Entity Bindings first.

Test Connection is greyed out

The connection is not saved yet. Select Create, then open it again with Edit and test.

The test passed but the real run fails on authentication

The HTTP REST test treats a 401 or 403 as reachable, and the test fills a missing secret reference with an empty value. Check the HTTP status in the test message, and check that each ${secret:…} reference exists on Secrets.

The preview looked right but the real run failed

The preview does not call connectors or write records. Credentials, reachability and the external system's own validation are only tested by a real run, so treat the first live run as part of setup. A step marked Error in Step data shows the reason.

"Published versions are immutable. Create a new draft to make changes."

You tried to save changes to the published version. Select Edit as new draft, then edit, save and publish that version.

Mapped fields come out empty

The map step's source paths do not match the incoming payload. Preview with a real captured payload and fix the paths. For connector reads, also check that the map points at the list of records inside the response, not at the whole response.

Fire now is unavailable on a trigger

The trigger is paused. Select Activate on its row first.

Writes are denied even though the run starts

The app has no Run as user, or that user's profiles cannot write the entity. Set a user whose profiles allow the write.

Common questions

Where do the credentials actually live?

In the app's secret store, encrypted and write-only from the moment they are saved. Connections and flow steps hold only ${secret:…} references, which are filled in when the flow runs. Looking at or exporting the configuration never shows a credential. Rotating a key replaces the value under the same reference, so no configuration needs to change. Sandbox copies never include secrets.

Do I have to build the flow by hand?

Only for one-off shapes. If the goal is to keep entities in step with another system, create a sync profile instead, or start from one of its templates. It finds the external objects, suggests field mappings and builds the flows for you. Hand-built flows are for everything else: one-way pushes with custom payloads, staged imports with approval, and queue or file transfers.

Can inbound data be reviewed before it lands?

Yes. Switch on Require operator approval before commit on the binding, and optionally Use staging table before publish. Inbound writes then wait as PendingApproval, and you can see the incoming records on Staging. An Operator approves or rejects them on Approvals.

Why does Fire now start a second run when I click twice?

Each manual fire is treated as a brand-new request, so two clicks always start two runs. This is by design: Fire now is a "run it now" button for testing. If the flow writes records with Create mode, each run creates them again. Use Upsert with an external key when you want repeat runs to update the same records.