Custom Adapter
Beyond standard connectors (source and destination), Flowlyze can be extended through external Apps called Custom Adapters.
There are no constraints on the technology used: the only requirement is support for the HTTP protocol, following the rules defined by the communication protocol.
In the context of the protocol, the role of System Integrator is performed by Flowlyze, which sends HTTP requests to the Custom Adapter and processes responses.
Architecture and Integration Flows
Execution Modes
The Custom Adapter provides two operational modes:
Synchronous Mode
- Flowlyze sends data in batches (e.g. 1000 rows at a time) via API.
- The Custom Adapter processes the batch within the single HTTP call and returns a standard payload that, for each message, reports:
- processing outcome,
- any errors and metadata.
- The call is subject to timeout and limitations on maximum duration (typically 30 seconds).
This mode is suitable for fast, idempotent integrations with limited volumes per single batch.
Asynchronous Mode
- Flowlyze sends data in batches as in the synchronous case, but the Custom Adapter can process them in a deferred manner (background jobs, internal queues, etc.).
- In the initial response, the Custom Adapter signals that processing is asynchronous.
- Flowlyze performs polling on the destination system (via the
progressaction) until job completion.
This mode is ideal for heavier or slower processing, where it is not realistic to complete everything within the timeout of a single HTTP request.
The synchronous mode has a typical timeout of 30 seconds. If processing requires more time, use the asynchronous mode.
Synchronous Communication Protocol
Every external system that wants to receive data from Flowlyze via Custom Adapter must expose one or more HTTP endpoints.
All endpoints share the same basic body structure:
{
"action": "execute",
"payload": { ... }
}
action: request type. The expected values are:"execute"→ starts message processing,"progress"→ (used in asynchronous flow) requests progress status.
payload: specific content of the request, which varies based on the action.
Execution Endpoint
`POST <domain>/system-integrator/handler1 (action "execute")`
This endpoint is called by Flowlyze to deliver a batch of messages to process.
Request
{
"action": "execute",
"payload": {
"requestId": "<guid>",
"messages": [
{
"msgId": "<guid>",
"msg": {
"...": "..."
},
"meta": {
"...": "..."
}
}
],
"meta": {
"...": "..."
}
}
}
Field meanings:
payload.requestIdUnique identifier of the request (batch) sent by Flowlyze.payload.messagesArray of messages to process.payload.messages[i].msgIdUnique identifier of the single message within the batch.payload.messages[i].msgActual message payload (data record to process).payload.messages[i].metaMetadata referring to the single message (context, specific configurations, etc.).payload.meta`` Metadata shared by the entire batch (e.g. connection strings, credentials, downstream endpoints, configuration parameters).
Temporal and Outcome Constraints
- The external system must process the request within 30 seconds of sending.
- HTTP 200 Requirement:
- If the system responds with a status other than
200, the entire request is considered failed, and all messages in the batch result as unprocessed. - The retry policies configured in Flowlyze will handle resending the batch or unprocessed messages, according to configuration.
- If the system responds with a status other than
Synchronous Response
If processing is handled in synchronous mode, the Custom Adapter responds with:
{
"requestId": "<requestId>",
"isAsync": false,
"messages": [
{
"msgId": "<guid>",
"status": "success",
"date": "<date>",
"meta": { }
}
]
}
-
requestId`` Must match the one received in the request. -
isAsyncfalseindicates that processing was handled entirely within this call. -
messagesArray of outcomes for each sent message. -
messages[i].msgIdMust correspond to amsgIdpreviously sent by Flowlyze. -
messages[i].statusProcessing status of the single message:"success"→ message processed correctly,"error"→ processing failed,"in_progress"→ used only in asynchronous scenarios, when processing is not yet complete.
-
messages[i].dateEnd processing date/time in ISO8601 format. -
messages[i].metaAny metadata returned by the external system (e.g. created resource ID, error messages, summary log).
In case of processing error, messages with status = "error" will be handled by Flowlyze according to configured retry policies (retries, dead-letter, logging, etc.).
Asynchronous Communication Protocol
In asynchronous mode:
-
Flowlyze sends an
action = "execute"request identical to the synchronous case. -
The Custom Adapter:
- responds with
HTTP 200, - sets
isAsync: true, - can mark messages as
"in_progress"until processing is complete.
- responds with
-
Flowlyze makes subsequent calls with
action = "progress"to update the status of messages associated with a specificrequestId. -
The Custom Adapter returns the updated status (
success/error) for eachmsgIdprogressively.
The body structure remains aligned with the contract described previously (same requestId, same messages list with updated status).
Manifest and Endpoint Discovery
To allow Flowlyze to dynamically discover which handlers are exposed by a Custom Adapter, the external system must publish a manifest at a well-known endpoint.
Discovery Endpoint
**GET <domain>/.well-known/system-integrator.json **
Responds with a JSON of the form:
{
"version": 1,
"handlers": {
"handler1": "<domain>/system-integrator/handler1",
"handler2": "<domain>/system-integrator/handler2"
}
}
versionManifest version, used for future compatibility.handlersMap[handler name] → [handler endpoint]. Each handler represents an entry point for processing data from a different subscriber/flow. In this way, a single Custom Adapter can serve multiple Flowlyze flows with dedicated logic.handlers.<handler>URL of the endpoint to which Flowlyze sendsexecute progressrequests relative to that specific handler.
Constraints:
- The discovery endpoint MUST always be exposed exactly at
/.well-known/system-integrator.json. - URLs of other endpoints (handlers) are free, at the discretion of the external system; the example with
/system-integrator/handler1and/system-integrator/handler2represents only a recommended convention.
Libraries
See Platforms\Custom section for libraries and project templates