Skip to main content

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 progress action) 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.

Timeout

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.requestId Unique identifier of the request (batch) sent by Flowlyze.
  • payload.messages Array of messages to process.
  • payload.messages[i].msgId Unique identifier of the single message within the batch.
  • payload.messages[i].msg Actual message payload (data record to process).
  • payload.messages[i].meta Metadata 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.

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.

  • isAsync false indicates that processing was handled entirely within this call.

  • messages Array of outcomes for each sent message.

  • messages[i].msgId Must correspond to a msgId previously sent by Flowlyze.

  • messages[i].status Processing 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].date End processing date/time in ISO8601 format.

  • messages[i].meta Any 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:

  1. Flowlyze sends an action = "execute" request identical to the synchronous case.

  2. The Custom Adapter:

    • responds with HTTP 200,
    • sets isAsync: true,
    • can mark messages as "in_progress" until processing is complete.
  3. Flowlyze makes subsequent calls with action = "progress" to update the status of messages associated with a specific requestId.

  4. The Custom Adapter returns the updated status (success / error) for each msgId progressively.

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"
}
}
  • version Manifest version, used for future compatibility.
  • handlers Map [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 sends execute progress requests 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/handler1 and /system-integrator/handler2 represents only a recommended convention.

Libraries

See Platforms\Custom section for libraries and project templates