Skip to content

Integration Flows reference ​

This page covers the screens that build, release, run and repair integration flows: Integration Flows (with the visual designer), Templates, Mappings, Lookup Tables, Integrations (the governed release path), Events, Failed Items, Approvals and Waiting Runs, Go-Live Approvals and Trace an Event. They are used by integration developers, release approvers and operators. Terms such as connection, trigger and correlation id are defined in the Overview.

A flow is stored as JSON in the definition of a flow record. Every example in this page uses the real step vocabulary of the flow engine and is accepted by its validator.

Integration Flows ​

The list shows every flow with its monitoring counters, lets an operator run, switch on or off, delete and inspect flows, and opens the visual designer. The designer is where flows are built.

Where to find it ​

Studio Explorer > Workspace > Integrations > Integration Flows (page key integration-flows). The designer opens from New flow in the designer or Design on a row (page key integration-flow-designer). Start from a template opens Templates.

Key concepts ​

TermMeaning
Flow codeUnique identifier of the flow in the tenant. Fixed after creation.
StepOne unit of work with a code unique in the flow.
Dependency waveSteps are run in waves. A step with no dependsOn key depends on the step before it in the array. "dependsOn": [] makes a root that runs in the first wave in parallel with other roots. "dependsOn": ["a","b"] is a join. Steps of one wave run concurrently.
TriggerWhat starts a run: manual or API, a business event (with an optional filter), a schedule (cron) or an inbound web address (webhook).
Run (execution)One execution of a flow with a status, input, context and per-step records.
Saga compensationAn optional reverse call on a step. When a later step permanently fails, the reverse calls of already-succeeded steps run in reverse order.

List screen ​

Chips above the grid: Total, Running, Queued, Success, Failed, Dead, Avg duration, Failure rate (both a dash until a run has completed) and a Workers chip (Workers: active/core (max N), redis up|down, shown to callers who may manage).

ColumnContent
Integration FlowName and code.
PluginOwning plugin id, studio for flows made by hand.
VersionvN.
ScheduleCron expression or a dash.
Trigger eventEvent type or a dash.
StatusACTIVE or DISABLED.

Row actions: Execute now (enabled for ACTIVE flows only), Design, Activate or Disable, Delete. Selecting a row opens the history drawer (20 runs per page, columns Started, Trigger, Status, Duration). Selecting a run opens the step detail: for each step the code, status (SUCCESS, SKIPPED, FAILED...), type, attempt, duration, HTTP status and error. For FAILED or DEAD runs AI: Analyze failure produces a plain-language summary ("AI analysis unavailable (no API key configured)." when no model is set up). Sensitive fields in step requests and responses are masked.

Tabs: Integration Flows, Connections (a short form for REST connections; use Connections for everything else) and Dead Letter Queue (DEAD runs with a Retry from scratch action).

New Integration Flow dialog (JSON editor) ​

FieldTypeDefaultRequiredDescription
Prompt and AI GeneratetextemptyNoDescribes the flow in words, for example "Create an employee, then create their user account". The result fills the code, name and definition. It is a draft only.
Integration Flow CodetextemptyYes
NametextemptyYes
DescriptiontextemptyNo
Definition (steps JSON)JSONone GET stepYesThe object with a steps array.

Save runs the engine validator first. Validation errors are listed in the dialog, one per line (see the troubleshooting table).

Run statuses ​

StatusMeaningNext
QUEUEDWaiting for a worker.RUNNING, CANCELLED
RUNNINGA worker is executing steps.SUCCESS, FAILED, WAITING, CANCELLED
WAITINGPaused at a wait, a date, an event or an approval. Holds no worker.QUEUED when the wait ends, CANCELLED
SUCCESSAll steps succeeded or were skipped.
FAILEDA step failed permanently. Remaining unrelated steps stop; compensations run.Resume, Retry
DEADThe run could not be completed at all: the flow definition is gone or unreadable, or a worker crashed and the run made no progress for the stale threshold (default 600 seconds).Resume, Retry
CANCELLEDCancelled by a person.Resume

Step statuses: SUCCESS, FAILED, SKIPPED (a condition was false or an upstream step failed), TIMEOUT, WAITING. Trigger types recorded on a run include API, APP, EVENT, SCHEDULE, WEBHOOK and TEST.

Resume re-runs only the steps that never succeeded, in place, keeping the run id. Retry creates a new run from scratch with the same input. Cancel is available for QUEUED, RUNNING and WAITING runs.

Step reference ​

A step is a JSON object. type defaults to REST and is upper-cased.

FieldApplies toDefaultDescription
codeallnone, requiredUnique within the flow. Later steps read the result as ${steps.CODE.response}.
typeallRESTREST, MAP, APP, FLOW, DELAY, WAIT_UNTIL, WAIT_EVENT, WAIT_APPROVAL, FOREACH, LOOP, BATCH.
methodRESTnone, requiredHTTP method. The designer offers GET, POST, PUT, PATCH, DELETE.
urlRESTnoneFull address, or a path appended to the connection's address. One of url or connectionCode is required.
connectionCodeRESTnoneThe connection to call through.
headersREST{}Map of header name to value.
bodyRESTnoneAny JSON, with ${...} placeholders.
successStatusCodesREST200, 201, 202, 204Statuses counted as success.
timeoutSecondsREST30
retryRESTnone{enabled, maxAttempts, backoff, initialDelaySeconds, maxDelaySeconds}. backoff is NONE, FIXED, LINEAR or EXPONENTIAL (delay doubles per attempt, capped by maxDelaySeconds).
dependsOnallprevious stepSee dependency wave.
runAfterallSUCCESS, SKIPPEDList of SUCCESS, FAILED, SKIPPED: which outcomes of the upstream steps allow this step to run. Any other value fails validation.
conditionallnoneBoolean expression evaluated on the run context. False skips the step without failing the run.
forEach, batchSizeLOOP, BATCH, FOREACH, FLOWnone, 1The list to go through. LOOP runs sequentially; BATCH runs batchSize items at a time. Inside, ${item} and ${index} are bound.
stepsFOREACHnoneInner steps, at least one.
compensateRESTnone{method, url, connectionCode, headers, body} reverse call.
circuitBreakerThreshold, circuitBreakerCooldownSecondsREST0 (never), 60 in the designerPause calls to the same target after that many failures, for the cooldown.
rateLimitPerMinuteREST0 (no limit)
mappingCode or mapping, sourceMAPnoneA saved mapping by code, or a mapping written inline, applied to source (for example ${input}). One of the two mappings is required.
action, paramsAPPnoneA platform action. See the table below.
flowCodeFLOWnoneAnother flow to run. It must be switched on.
delaySecondsDELAYnone1 second to 30 days.
params.until, params.timezoneWAIT_UNTILnoneDate and time, or a placeholder; time zone defaults to UTC. At most one year ahead.
params.eventType, params.match, params.timeoutSeconds, params.onTimeoutWAIT_EVENTnoneEvent kind, up to 10 field=value conditions, give-up time 1 second to 90 days, FAIL or CONTINUE.
params.title, details, timeoutSeconds, onTimeout, stopIfRejected, assigneesWAIT_APPROVALnoneSee Approvals and Waiting Runs.

Engine limits: a list may hold at most 500 items; loops nest at most 3 levels; flows call each other at most 5 levels deep and never themselves; a delay longer than 300 seconds suspends the run instead of holding a worker; a wait cannot sit inside a loop except a delay of at most 300 seconds.

Platform actions (APP steps) ​

ActionParametersEffect
entity.createentity, valuesCreates a record.
entity.getentity, idReads one record.
entity.updateentity, id, valuesUpdates one record.
entity.deleteentity, idSoft-deletes one record.
entity.findentity, optional filterField, filterValue, limit (up to 5000)Result has count and items. The designer returns the first 200 when no limit is given.
sftp.readconnection, path, optional encoding text or base64File content. Files are limited to 1 MB.
sftp.writeconnection, path, content, optional encodingWrites a file.
sftp.deleteconnection, pathDeletes a file.
sftp.listconnection, path (folder)Files in the folder.
db.queryconnection, sql, paramsOne SELECT or WITH with :name placeholders; up to 5000 rows. Values are always bound, never concatenated.
db.writeconnection, sql, paramsOne INSERT, UPDATE or DELETE.
queue.publishqueue, message, optional delaySeconds (0 to 2592000), dedupeKeyPuts a message on a queue. Up to 256 KB.
file.parsecontent, optional format csv, xml, xlsx or xls, name, encoding base64, delimiter, header (default true), sheet, recordTurns a file into rows.
sync.runsync, optional previewRuns or previews a saved synchronization. A step test always previews.

APP steps run inside the platform as the person or process that started the flow, so their permissions apply.

Visual designer ​

The designer is a canvas of cards. The toolbar shows the flow name, a chip vN - On|Off (or New), undo and redo, Save, Deploy, Test, Flow checker (with a problem count), Copilot and, for a live flow, Switch off. An unsaved live flow shows "Unsaved changes - this flow is on, saving changes it right away".

AreaContent
Left panel tabsConnectors (apps with ready actions), Actions (Call an API, For each item, Transform data, Condition, Run in parallel, Run another flow, Wait, Repeat for each item, SFTP, database, Queue, File rows, Sync), Outline, Versions (with a compare dialog).
CanvasTrigger card, step cards, lanes for conditions (If yes, If no), parallel branches, loop bodies and "If it fails" paths. Zoom 40 to 150 percent, fit to width, mini-map.
Settings panelProperties of the selected card. With nothing selected: flow Name and "What it does".
Step dockConfiguration, Request, Results, Logs for the selected card; a step can be tested alone.
Problems drawerProblems found by the designer plus the server's checks.

New flow dialog: Name and Code ("Used in addresses and logs. It cannot be changed later."). An existing code shows "A flow with this code already exists."

Deploy saves the flow and switches it on. If the flow requires go-live approval, switching on creates a request instead (see Go-Live Approvals). A flow whose definition the designer cannot represent opens read-only with its JSON; it still runs as written.

Trigger panel ​

FieldTypeDefaultDescription
StartsselectStarted by hand or by APIStarted by hand or by API; When a business event happens; On a schedule; When another system calls.
When a record of this kind / Starts when itentity, created or changed or deletedWrites the event kind entity.NAME.created, .updated or .deleted. The flow receives the record fields and an _event block with entity, record id and operation. Changes made by a flow's own actions do not start flows, so flows cannot loop.
Or a ready-made eventselectNone chosenqueue.message.received, sftp.ack.received, approval.requested, approval.decided, document.uploaded, sftp.file.arrived, poll.item.new, poll.item.updated. Each fills a sample.
Event kindtextemptyAny event from the Events screen.
One of these fields changesmulti-selectany fieldUpdates only. Compiles to input._event.changed.FIELD == true.
Extra rule on the event dataexpressionemptyUp to 2000 characters. On updates input._event.changed.FIELD and input._event.previous.FIELD are available.
Common schedulesselectCustomEvery 5 minutes 0 */5 * * * *; Every hour 0 0 * * * *; Every day at 9:00 0 0 9 * * *; Weekdays at 9:00 0 0 9 * * MON-FRI; Every Monday at 9:00 0 0 9 * * MON.
SchedulecronemptySix fields: seconds minutes hours day month weekday, evaluated in UTC.
Address other systems callread onlyThe flow's receiver address once the flow is saved. Add a secret or New secret generates a whsec_ signing secret, shown once ("Copy this now. It is not shown again.").
Sample dataJSONemptyAn example of what the trigger delivers. Used for field lists and tests. Never sent anywhere.

Card properties ​

CardFields
All stepsName, Note (optional).
Call an API / For each itemMethod, Connection (or "None (full address below)"), Address or Path, Headers (one Name: value per line), Body (JSON). For each item also "List to go through" and "How many at the same time" (1 means one after another). Advanced: Give up after (seconds, default 30), Try up to (times; 0 or 1 no retry; retries wait longer each time), Counts as success (status codes), At most this many calls per minute (0 none), Pause after failures and Pause for (seconds, default 60). Only run if. Response mapping note. "If a later step fails, undo this with" (method, connection, address, body).
Transform dataData comes from (the trigger or the answer of an earlier step), Rules (written here or a saved mapping), Open the mapper, Run only if.
ConditionA rule builder (is equal to, is not equal to, is greater than, is at least, is less than, is at most, is empty, is not empty; "All must be true" or "Any can be true") and the rule as editable text, for example steps.step_1.response.total > 100.
Run in parallelBranches start together; the next step waits for all.
Repeat for each itemList to go through; inside ${item} and ${index}; Try the whole loop up to (times); the answer has count and items.
Run another flowFlow (switched-off flows are marked), What it receives (name and value pairs), Repeat (optional list), Wait for it up to (seconds), Try up to (times).
WaitWait mode: For a length of time (1 second to 30 days), Until a date and time, Until something happens, Until a person approves.
SPARK actionAction, Entity, Record id, Values to write, Filter.
SFTP, Database, Queue, File rows, SyncThe parameters of the actions above, using connection and queue pickers.

Messages from the designer check ​

MessageCause
"Add at least one step."The canvas is empty.
"The trigger needs an event kind." / "The trigger needs a schedule."The trigger type is chosen without its value.
"The trigger sample is not valid JSON."
"NAME needs an address or a connection."A call card without either.
"NAME has a body that is not valid JSON."
"NAME needs a rule, for example input.amount > 100."Empty condition.
"NAME has nothing in either branch." / "...in any branch."
"NAME needs the list to go through." / "...has nothing inside it to repeat."
"NAME needs the flow to run."
"NAME needs the queue." / "needs a message written as JSON."
"NAME needs the database connection." / "the statement to run." / "a value for :NAME."
"NAME needs the SFTP connection." / "the file's path."
"NAME shares its step code with another step."Duplicate codes.

Procedure: build and release a flow ​

  1. Select New flow in the designer, enter Name Order to partner and accept the code order-to-partner.
  2. Select the trigger card. Choose "When a business event happens" and enter the event kind order.created. Paste a sample such as {"id":"SO-1001","customer":"Acme Ltd","total":1200.5,"currency":"usd"}.
  3. Add a Transform data card, open the mapper, and map id to orderId, total to amount with a number transform.
  4. Add a Call an API card: Method POST, Connection partner-api, Path /events, Body {"event":"order.created","data":"${steps.step_1.response}"}, Try up to 3 times.
  5. Select Test. Fix anything the Flow checker lists. Select Save.
  6. Select Deploy. The chip changes to v1 - On. Publish a test event on Events and open the flow's history to see the run.

Permissions ​

integration.flow: view (list, get, validate, monitoring, AI explain), create (save, AI generate), publish (activate, deactivate, schedule, trigger event, trigger filter), execute (execute, test run, test step, publish test event), cancel, retry (resume, retry), viewHistory (versions, executions, run detail, dead runs, AI failure analysis), manage (webhook secret, go-live requirement, worker pool), delete. Without a permission the API returns 403 actor "X" lacks integration.flow.ACTION permission.

API and CLI ​

PurposeRequest
List, getGET /api/v1/integration/flows, GET /api/v1/integration/flows/{code}
SavePOST /api/v1/integration/flows with flowCode, pluginId, name, description, scope, definition
ValidatePOST /api/v1/integration/flows/{code}/validate returns {"errors":[...]}
Switch on, offPOST .../{code}/activate (204, or 202 PENDING_APPROVAL), POST .../{code}/deactivate
DeleteDELETE /api/v1/integration/flows/{code}
VersionsGET .../{code}/versions
SchedulePUT .../{code}/schedule with {"cronExpression":"0 0 9 * * MON-FRI"}; an empty value clears it
Trigger event, filterPUT .../{code}/trigger-event with {"eventType":"order.created"}; PUT .../{code}/trigger-filter with {"expression":"..."}
Run nowPOST .../{code}/execute with the input object; header X-Idempotency-Key optional. Returns {"executionId":N,"status":"QUEUED"}
TestPOST .../{code}/test-run (works while switched off; run marked TEST), POST .../{code}/test-step with step, input, steps
Inbound callPOST /api/v1/integration/flows/webhooks/{code} (see below)
RunsGET .../{code}/executions?pageIndex&pageSize (page size up to 500), GET /api/v1/integration/flow-executions/{id}, .../dead
Run controlPOST /api/v1/integration/flow-executions/{id}/cancel, /resume, /retry, /ai-analyze-failure
MonitoringGET /api/v1/integration/flows/monitoring, GET .../flows/workers, POST .../flows/workers/resize with {"size":N}
AIPOST .../flows/ai-generate with {"prompt":"..."}, POST .../{code}/ai-explain
Publish a trigger eventPOST .../flows/events/publish with eventType, payload

Inbound receiver: the caller sends a JSON object body (up to 256 KB) with the X-Tenant-Id header. When the flow has a signing secret the call must carry webhook-id, webhook-timestamp and webhook-signature (v1, plus the base64 HMAC-SHA256 of id.timestamp.body, timestamp within 300 seconds), or the older webhookSecret query parameter. Failures: 401 "missing or incorrect signature or webhookSecret", 413 "the request body is larger than 256 KB", 429 "too many webhook calls; try again shortly" (default 300 per minute per tenant), 400 "the body must be a JSON object". A flow with no secret is open to anyone with the address. Set or clear the secret with PUT .../{code}/webhook-secret and {"secret":"..."}.

CommandPurpose
erp flow list, erp flow get <code>Read.
erp flow save <file.json>Save a file {flowCode, name, description, scope, definition}; validated by the engine before it is written.
erp flow activate <code>, erp flow deactivate <code>Switch on or off.
erp flow execute <code> [--input <json-string-or-@file>]Start one run.
erp flow require-golive-approval <code> on|offRequire a second person to switch the flow on.
erp integration run flow <key> [--input ...]Start through the endpoint applications use.
erp integration healthNeeds-attention summary.

A complete flow definition, accepted by the validator (it reshapes an order and posts it with retries):

json
{
  "steps": [
    {
      "code": "step_1",
      "type": "MAP",
      "dependsOn": [],
      "source": "${input}",
      "mapping": {
        "fields": [
          { "target": "orderId", "source": "id", "required": true },
          { "target": "customer", "source": "customer", "transforms": ["trim"] },
          { "target": "amount", "source": "total", "transforms": ["number"] },
          { "target": "currency", "source": "currency", "transforms": ["upper"] }
        ]
      }
    },
    {
      "code": "step_2",
      "type": "REST",
      "method": "POST",
      "dependsOn": ["step_1"],
      "url": "/events",
      "connectionCode": "target-system",
      "body": { "event": "order.created", "data": "${steps.step_1.response}" },
      "timeoutSeconds": 30,
      "retry": { "enabled": true, "maxAttempts": 3, "backoff": "EXPONENTIAL", "initialDelaySeconds": 2, "maxDelaySeconds": 60 }
    }
  ]
}

Limits and behaviour ​

  • Worker pool: default minimum 2 and maximum 50 workers, scaling 2 at a time. A run that shows RUNNING with no progress for 600 seconds is moved to DEAD.
  • POST /api/v1/integration/run is limited to 120 runs a minute per tenant.
  • Scheduled flows are evaluated by a tenant-by-tenant sweep on a tick; a schedule is not a precise timer.
  • Step requests and responses are stored per attempt with sensitive fields masked at read time.

Errors and troubleshooting ​

MessageCauseFix
a step is missing its "code" / duplicate step code "X"Step code absent or repeated.Give each step a unique code.
step "X" is missing "method" / is missing "url" (or a "connectionCode")A REST step without a call.Add the method and an address or connection.
step "X" depends on unknown step "Y"dependsOn names a missing step.Correct the code.
step "X" has an unknown runAfter value "Y"Not SUCCESS, FAILED or SKIPPED.
step "X" has runAfter but nothing before it to wait forrunAfter on a root.Add a dependency.
step "X" needs the list to go through / needs at least one step inside the loopLoop incomplete.
step "X" needs an action / needs a mapping / needs the flow to runAPP, MAP or FLOW step incomplete.
step "X" must wait between 1 second and 30 daysDELAY out of range.
step "X" must give up waiting between 1 second and 90 daysWAIT_EVENT or WAIT_APPROVAL timeout out of range.
step "X" has an onTimeout that is not FAIL or CONTINUE
step "X" has conditions that are not a set of at most 10 field and value pairsmatch too large.
the date is more than a year away, which is the longest a run can waitWAIT_UNTIL too far.
flows are calling each other more than 5 levels deepRun another flow chain too long.
invalid JSON: ...The definition could not be parsed.
403 lacks integration.flow.publish permissionMissing right.Grant the right.
422 on executeThe flow is not ACTIVE, or another state prevents queueing.Switch it on or use test-run.

Templates ​

A catalog of ready-made integrations. Choosing one installs a draft flow, creates the connections it needs without secrets, and opens it in the designer switched off.

Where to find it ​

Studio Explorer > Workspace > Integrations > Templates. Page key integration-templates. Also Start from a template on Integration Flows.

Key concepts ​

StatusLabelMeaning
readyReady to useVerified against a stand-in service in automated tests.
untestedNot tested with the real serviceA starting point to try before relying on it.
plannedPlannedListed but cannot be installed. The button reads "Not available yet".

Screen ​

A search box ("Search templates, apps or words") matches name, summary, tags and vendors. The left column filters by Category and by Readiness. Each card shows the vendor initials, category, status, name, summary, vendor chips, the trigger and the step count. Selecting a card opens a dialog with the description, the status note, "How it works" (starting trigger and an outline of the steps), "What you need" and, for installable templates, a name field.

FieldTypeDefaultRequiredDescription
Address (per connection)textthe template's usual addressRequired when the template has noneMust start with https:// or http://.
Name for your flowtextthe template's nameNoThe flow code is the template key, or KEY-2, KEY-3 when taken.

Use this template is disabled for planned templates and while a required address is empty. After install the result dialog lists next steps (add each secret, test, publish) and offers Open in the designer.

Catalog shipped with the platform ​

KeyCategoryStatusTrigger
event-to-webhookGetting startedreadyevent
fan-out-two-systemsGetting startedreadyevent
route-by-amountOrdersreadyevent
scheduled-check-with-alertMonitoringreadyschedule
hubspot-contact-from-customerCRMuntestedevent
jira-issue-on-failureSupportuntestedevent
sendgrid-email-on-eventNotificationsuntestedevent
slack-message-on-eventNotificationsuntestedevent
teams-message-on-eventNotificationsuntestedevent
razorpay-payment-to-invoicePaymentsplanned
shopify-order-to-sales-orderOrdersplanned
zoho-crm-lead-from-customerCRMplanned

Permissions ​

integration.template / view lists and reads; install installs.

API ​

GET /api/v1/integration/templates?category=&status=&q=, GET /api/v1/integration/templates/{key}, POST /api/v1/integration/templates/{key}/install with {"flowCode": "...", "name": "...", "connectionAddresses": {"CONNECTION_CODE": "https://..."} }. The response has flowCode, name, connectionsCreated, connectionsReused and nextSteps. An installed flow is saved with plugin id studio, switched off, with the template's event trigger or schedule set. No erp command installs templates.

Errors and troubleshooting ​

MessageCauseFix
the flow code must be lower-case letters, digits, dot, dash or underscoreInvalid flowCode.
a flow with the code "X" already existsRequested code taken.Choose another or leave empty.
the address for "NAME" is needed: HELPA connection without a usual address and none supplied.Enter the address.
the address for "NAME" must start with https:// or http://
this template is not available yet: NOTE (409)Planned template.

Mappings ​

A mapping turns one JSON document into another by declarative rules. Nothing in a mapping runs code: sources are dotted paths, transforms come from a fixed list. A field that cannot be mapped is reported as an issue (target and reason, never the value) and the rest still maps.

Where to find it ​

Studio Explorer > Workspace > Integrations > Mappings. Page key mappings.

Fields ​

Dialog Add mapping (an existing mapping opens with Open):

FieldTypeDefaultRequiredDescription
NametextemptyYesThe code is generated from it while new.
DescriptiontextemptyNo
Rules (JSON)JSON objecta starter with three fieldsYesMust contain a fields list.
Sample to try it on (JSON)JSON objecta starter sampleUsed only by Try it. "Nothing is saved or sent when you try it."

Grid columns: Mapping, About, Version, Changed by (user and date).

Rule fields ​

KeyTypeDescription
targetstring, requiredDotted output path, customer.name builds nested objects.
sourcestringDotted input path, with [0] for lists.
templatestringText with ${path} placeholders.
formulastringAn expression, see below.
defaultanyUsed when the value is empty. A rule needs one of source, template, formula or default.
requiredbooleanA missing value is the issue "required value is missing".
lookupstringName of a table inside the mapping's lookups object or of a shared Lookup Table. A table inside the mapping wins.
valueMapobjectDirect value replacement, checked before lookup.
transformslistApplied in order: trim, upper, lower, string, number, integer, boolean (true, yes, y, 1 / false, no, n, 0), digitsOnly, substring:from:to, replace:old:new, date:inPattern:outPattern.
typestringstring, number, integer or boolean. Checked after transforms.
patternregexThe whole value must match.
minLength, maxLength, min, maxnumberLength and numeric bounds.

Formula operators: + - * / %, == != < <= > >=, && || !. Literals: numbers, 'text', true, false, null. Functions: if, coalesce, isEmpty, concat, upper, lower, trim, length, substring, replace, contains, startsWith, endsWith, join, number, text, round, abs, min, max, sum, today, now, addDays. A formula is at most 2000 characters.

Actions ​

ActionEffectAPI
Add mapping, OpenOpens the dialog.GET /api/v1/integration/mappings/{code}
Try itApplies the unsaved rules to the sample and shows "Every rule worked on this sample." or "N rule(s) did not work on this sample." with each issue and the output.POST /api/v1/integration/mappings/test
SaveCreates or replaces by code; the version rises by one.PUT /api/v1/integration/mappings/{code}
DeleteRemoves the mapping.DELETE /api/v1/integration/mappings/{code}

Example ​

json
{
  "fields": [
    { "target": "customer.name", "source": "fullName", "transforms": ["trim", "upper"], "required": true },
    { "target": "country", "source": "countryName", "lookup": "countries" },
    { "target": "amount", "source": "total", "transforms": ["number"], "min": 0 }
  ],
  "lookups": { "countries": { "India": "IN" } }
}

For the sample {"fullName":" ada lovelace ","countryName":"India","total":"12.50"} the output is {"customer":{"name":"ADA LOVELACE"},"country":"IN","amount":12.50}.

Permissions ​

integration.mapping: view (list, get, test, apply), manage (save, delete).

Limits and behaviour ​

At most 500 fields per mapping and 512 KB of rules. Saving validates structure (targets present, transforms known, lookups defined, patterns valid, formulas parse). POST /api/v1/integration/mappings/{code}/apply applies a saved mapping to a sample. No erp command manages mappings.

Errors and troubleshooting ​

MessageCauseFix
"The rules is not valid JSON." / "The rules must be a JSON object."Editor content.Correct the JSON.
the mapping is not valid: TARGET - needs a source, a template, a formula or a defaultA rule has no value source.
... - unknown transform "X"Transform not in the list.
... - lookup "X" is not definedNo table of that name in the mapping or shared tables.
... - the pattern is not validRegex error.
spec needs a fields list / spec is larger than 512 KB
Issue value is not of type numberType check failed after transforms.
Issue transform "number" could not be appliedValue is not numeric.

Lookup Tables ​

A lookup table keeps values such as country codes in one place so any mapping can look them up by name.

Where to find it ​

Studio Explorer > Workspace > Integrations > Lookup Tables. Page key lookup-tables.

Fields ​

Dialog Add lookup table:

FieldTypeDefaultRequiredDescription
NametextemptyYes
DescriptiontextemptyNo
Entries (one per line: what you receive=what you want)textemptyThe first = splits the line, so a value may contain =. Blank lines are ignored. A line without a key shows "Line N needs a key, then =, then the value." The helper shows the entry count and the example India=IN.

When the table is used, the dialog shows "Used by the mappings: ... Changing entries changes them all." Grid columns: Table, About, Entries, Changed by.

Actions and API ​

ActionAPI
OpenGET /api/v1/integration/lookups/{code} (includes usedBy)
SavePUT /api/v1/integration/lookups/{code} with {"name":"Countries","description":"...","entries":{"India":"IN"} }
DeleteDELETE /api/v1/integration/lookups/{code}
ListGET /api/v1/integration/lookups

Permissions ​

Same resource as mappings: integration.mapping / view and manage.

Limits and errors ​

At most 20000 entries. Values must be single values, not objects or lists.

MessageCause
a lookup table holds at most 20000 entriesToo many entries.
an entry has an empty key
the value for "X" must be a single value
the table is used by the mappings: A, B (409)Delete refused while mappings use it.
code must be lower-case letters, digits, dot, dash or underscore

Integrations ​

The governed release path for an integration. An integration definition names the flow and optional mapping that implement it, and moves through approval stages before it is switched on. Switching a definition on switches its flow on; switching it off switches the flow off.

Where to find it ​

Studio Explorer > Workspace > Integrations > Integrations. Page key integration-definitions.

Fields ​

Dialog Add integration:

FieldTypeDefaultRequiredDescription
NametextemptyYesCode generated from it.
What it doestextemptyNo
DirectionselectSend to the other systemYesoutbound, inbound (Receive from the other system) or bidirectional (Both ways).
How it runsselectLive, as things happenYesonline, offline (In batches, from files) or hybrid (Both).
Starts on this eventtextemptyNoExample order.created.
Flow that runsselectNot chosen yetNeeded to validate
MappingselectNoneNeeded for inbound

Editing an existing integration shows "Saving a change sends this integration back to draft, and switches its flow off if it was running, so it is checked and approved again." and lists its current problems.

Stages ​

StatusLabelMoves toPermission needed
DRAFTDraftTESTmanage
TESTTestingVALIDATED, DRAFTmanage
VALIDATEDCheckedAPPROVED, DRAFTapprove for APPROVED, manage for DRAFT
APPROVEDApprovedACTIVE, DRAFTactivate for ACTIVE
ACTIVERunningINACTIVEactivate
INACTIVESwitched offACTIVE, DRAFTactivate for ACTIVE

Row buttons are named by the target: Back to draft, Start testing, Mark as checked, Approve, Switch on, Switch off. Open edits, History lists every move with time, user, from and to and note, and the delete button is disabled while ACTIVE. Chips: Integrations, Running, Approved but not switched on, In draft or testing. Approving and switching on are separate rights from editing, so the author need not be the releaser.

Moving to VALIDATED or ACTIVE is refused while problems exist: "Choose the flow that runs this integration."; The flow "X" does not exist.; The mapping "X" does not exist.; mapping rule problems; and "An integration that receives data needs a mapping." for inbound and bidirectional integrations.

API ​

GET /api/v1/integration/definitions, GET .../{code} (adds problems), GET .../{code}/history, PUT .../{code} with name, description, direction, mode, eventType, flowCode, mappingCode, DELETE .../{code}, POST .../{code}/transition with {"to":"TEST","note":"..."}. Errors: 409 "from DRAFT it can only go to TEST", 409 "switch it off before deleting it", 422 with the problems. Permission resource integration.definition: view, manage, approve, activate. No erp command.

Events ​

Business events that happened, kept durably so they can be searched and sent again. Flows and webhooks that listen for an event receive it at least once.

Where to find it ​

Studio Explorer > Workspace > Integrations > Events. Page key integration-events.

Screen ​

Chips: Events recorded, Kinds shown, Sent again. A filter "Only this kind" (for example hcm.employee.created) re-queries the list (up to 100 shown). Columns: Event (kind and event id), About (business object and record number), From (source application), When, Sent again (replay count). Row actions: Details (event id, version, time, trace id, changed fields and the data) and Send again.

Send a test event dialog:

FieldTypeDefaultRequiredDescription
Event kindtextemptyYesExample order.created. At most 200 characters.
About (optional)textemptyNoBusiness object, for example Order.
Record number (optional)textemptyNo
Details (JSON, optional)JSON objectemptyNo"The details must be a JSON object, like {"total": 10}." / "The details are not valid JSON."

The event is recorded and goes to every switched-on flow and webhook listening for that kind. Send again replays the stored event to the same listeners and keeps the original event id.

API ​

PurposeRequest
PublishPOST /api/v1/integration/events with eventType, optional eventVersion (default 1), sourceApplication, businessObject, businessObjectId, changedFields, data (up to 256 KB), correlationId, idempotencyKey. Returns 202, or 200 with duplicate: true.
SearchGET /api/v1/integration/events?eventType=&businessObject=&businessObjectId=&correlationId=&page=&size= (size up to 200)
ReadGET /api/v1/integration/events/{eventId}
ReplayPOST /api/v1/integration/events/{eventId}/replay

A missing correlation id is taken from the current request or generated. Permission integration.event: view, publish, replay. Errors: eventType is required (up to 200 characters), event data is larger than 256 KB. No erp command.

Failed Items ​

One list of everything that failed for good: flow runs in status FAILED or DEAD and outbound webhook deliveries that failed for good, that nobody has resolved. An item can be inspected, corrected and sent again, or set aside with a note.

Where to find it ​

Studio Explorer > Workspace > Integrations > Failed Items. Page key dead-letters.

Screen ​

A chip "Waiting for a decision: N" (or "Nothing is waiting") and filters All, Flow run, Webhook delivery. Columns: What failed (flow code or webhook code, with kind and id), Why (the recorded error, or "No reason was recorded"), When.

ActionEffectAPI
Look and fixOpens the item with its error and the original input (flow run input or webhook payload) as editable JSON. "The content must be a JSON object." / "The content is not valid JSON."GET /api/v1/integration/dead-letters/{type}/{id}
Send againReplays unchanged. A flow run is retried as a new run; a webhook delivery is requeued.POST .../{type}/{id}/replay
Send again with these changesReplays with the corrected content. A flow starts a new run with the corrected input; a webhook payload is replaced then requeued. The original stays as it was.POST .../{type}/{id}/replay with {"input":{...} }
Set asideRemoves it from the list with an optional note kept in the audit log.POST .../{type}/{id}/discard with {"note":"..."}

type is flow_execution or webhook_delivery. Replay returns replayed, corrected and newExecutionId or deliveryId; if it fails again the item returns to the list.

Permissions and errors ​

Resource integration.deadletter: view, replay, discard. Lists are 50 per page by default, up to 200.

MessageCause
type must be flow_execution or webhook_deliveryBad type in the path.
no open dead letter (404)Already resolved or never failed.
delivery is no longer dead (409)The webhook delivery changed state.
input is not valid JSON

Approvals and Waiting Runs ​

Lists the approval requests that flows are waiting on, and everything paused runs are waiting for. A flow asks for an approval with a Wait card in "Until a person approves" mode, which is a WAIT_APPROVAL step.

Where to find it ​

Studio Explorer > Workspace > Integrations > Approvals and Waiting Runs. Page key flow-approvals.

Tabs ​

TabContent
To approve (N)Pending requests. Columns Request (title and details), Flow (code and run number), Who can answer, Asked, Gives up. Actions Approve and Reject. A Mine switch shows requests assigned to the signed-in person or to anyone.
Waiting runs (N)Paused runs. Columns Flow (code, run, step), Waiting for (kind chip: A length of time, A date and time, An event, A person's approval, with a sentence such as "The event payment.received (orderId = A-1)"), Since, Until / gives up, Started by.
AnsweredHistory with Outcome (approved, rejected, timed out, cancelled), who answered and when.

The answer dialog shows the details, a warning "Rejecting stops the flow with an error." when the step has stopIfRejected, and an optional Comment of up to 1000 characters. "The flow can use it, and it is kept with the answer."

Request statuses ​

StatusMeaning
PENDINGWaiting for an answer.
APPROVEDApproved; the run continues with approved true.
REJECTEDRejected; the run continues with approved false, or fails if stopIfRejected.
TIMED_OUTNo answer before timeoutSeconds; the step fails or continues per onTimeout.
CANCELLEDThe run was cancelled.

The WAIT_APPROVAL step ​

json
{
  "code": "hold",
  "type": "WAIT_APPROVAL",
  "dependsOn": ["create"],
  "params": {
    "title": "Approve order ${input.orderNo}",
    "details": "Total ${input.total}",
    "timeoutSeconds": 172800,
    "onTimeout": "FAIL",
    "stopIfRejected": false,
    "assignees": ["finance.lead"]
  }
}

title is required; timeoutSeconds is required, 1 second to 90 days (the designer defaults to 2 days); onTimeout is FAIL or CONTINUE; assignees is a list of user ids, empty meaning anyone with the approve right. Later steps read approved, decidedBy and comment. Creating a request publishes approval.requested; answering publishes approval.decided.

API and permissions ​

GET /api/v1/integration/approvals?status=&limit=&mine=, POST /api/v1/integration/approvals/{id}/decide with {"approved":true,"comment":"..."}, GET /api/v1/integration/waits?limit=. Resource integration.flow: view for the lists, approve to answer. A request for specific people can be answered by others only with manage; otherwise 403 "this request is for specific people, and "X" is not one of them". Errors: 400 "say whether it is approved or rejected", 400 "the comment is longer than 1000 characters", 409 "This request was already answered, or the flow is no longer waiting for it." No erp command.

Go-Live Approvals ​

A flow or synchronization can be marked so that switching it on needs the approval of a different person. The request appears here.

Where to find it ​

Studio Explorer > Workspace > Integrations > Go-Live Approvals. Page key golive-approvals.

How it is used ​

  1. Set the requirement: erp flow require-golive-approval order-to-partner on or erp sync require-golive-approval hr-people on (or PUT /api/v1/integration/flows/{code}/require-golive-approval and PUT /api/v1/integration/syncs/{code}/require-golive-approval with {"required":true}). Needs manage.
  2. When someone activates the flow or enables the synchronization, no switch-on happens. The API answers 202 with {"status":"PENDING_APPROVAL","request":{...} } and the request is listed.
  3. A different person with the publish right selects Approve or Reject and may add a comment (up to 1000 characters, "Kept with the answer."). Approving switches the item on straight away.

Tabs: To approve (N) with columns Wants to switch on (code and kind: Flow or Synchronization), Asked by, Asked; and Answered with Outcome (approved, rejected, cancelled), Answered by and Asked by.

Statuses ​

PENDING, APPROVED, REJECTED, CANCELLED.

Permissions and errors ​

integration.flow / view lists; publish answers.

MessageCause
"the person who asked cannot also approve this request" (403)Self-approval is refused.
"this request was already approved" (409)Already answered.
"no such request" (404)

GET /api/v1/integration/golive-requests?status=, POST /api/v1/integration/golive-requests/{id}/decide with {"approved":true,"comment":"..."}. erp integration health reports the number of pending requests.

Trace an Event ​

Follows one business event across every flow run, event, queue message and synchronization run that carries the same correlation id, in time order. Only what happened is shown, never message contents.

Where to find it ​

Studio Explorer > Workspace > Integrations > Trace an Event. Page key integration-trace.

Screen ​

Enter the correlation id (up to 100 characters) and select Trace. The id is shown in the event details and in server logs. The outcome chip is one of:

OutcomeLabelRule
OKEverything finishedHops exist and none failed or is unfinished.
IN_PROGRESSStill in progressA flow run is QUEUED, RUNNING or WAITING, a queue message is READY or IN_FLIGHT, or a sync run is RUNNING.
FAILEDSomething failedA flow run FAILED or DEAD, a queue message DEAD, or a sync run FAILED.
NOT_FOUNDNothing foundNo record carries the id. "Check it was copied whole; ids are case-sensitive."

Columns: When, What happened (for example "Flow order-to-partner", "Event order.created", "Queue orders", "Synchronization hr-people" with details such as run number, who started it, attempts, created, updated, in conflict, failed), Kind and Status.

API and CLI ​

GET /api/v1/integration/trace/{correlationId} (letters, digits and . _ : -, up to 100; at most 500 hops per kind). Permission integration.flow / view. erp trace <correlationId> [--json] prints the same, for example:

text
f51b6f74-28d1-499b-a144-8875e6462cc7: OK (2 hops)
  2026-09-28 08:08:29.883  event queue.message.received about message 29
  2026-09-28 08:08:29.894  flow live-handler run #102 SUCCESS (EVENT - event:queue.message.received)

A flow started by a schedule starts its own trace. Server log lines carry the same id: erp logs tail --grep <correlationId>. Error: 400 "the correlation id is up to 100 letters, digits and . _ : -".

Overview, Triggers and Synchronization, Connections, Move between environments, Connect to another system, Send events with webhooks.