The HTTP Listener turns an Etlworks flow into a callable HTTP endpoint. A trading partner, a webhook from a SaaS app, or a browser-side JavaScript client can POST, GET, PUT, DELETE, or OPTIONS against the listener's URL, and the flow runs in response. The listener handles authentication, the request lifecycle, and the response.
When to use this listener
Reach for an HTTP Listener whenever you need to expose an Etlworks flow as a callable API:
- Custom REST API — turn a query, a transformation, or a workflow into an endpoint other systems can call.
- Receive webhooks from SaaS apps (Stripe, GitHub, Salesforce, …) and trigger a flow per event.
- Browser-side integration — CORS preflight is handled, so client-side JavaScript can POST directly to a listener endpoint. See CORS / OPTIONS preflight.
- File / payload intake — accept POSTed JSON, XML, EDI, or arbitrary binary payloads.
- Bridging legacy systems — give a system that only speaks HTTP a way to drive Etlworks flows.
For end-to-end patterns — turning a database object into a REST endpoint, building PUSH-style APIs, and webhook intake examples — see Building custom APIs.
How HTTP Listeners work
Every HTTP Listener is bound to a flow. When a request arrives at the listener URL:
- The listener authenticates the caller (JWT or Basic, header or query-string).
- An optional preprocessor script runs to inspect or rewrite the request before the flow sees it.
- The flow runs. For POST / PUT, the request body is the source data; for GET, the flow produces the response body.
- The listener returns the response — either the flow's output, a configured static response, or a dynamically computed HTTP code.
One important rule: one listener → one flow. The URL pattern must be unique across every listener on every customer's instance; Etlworks blocks duplicate URL patterns at creation time.
URL patterns and the endpoint URL
The endpoint URL has three parts:
{integrator-host}/rest/v1/httplistener{URL Pattern}
| Part | What it is |
|---|---|
| integrator-host | Your Etlworks instance hostname — e.g., https://app.etlworks.com for the shared cloud, or your dedicated / on-premise instance URL. |
| /rest/v1/httplistener | Fixed Etlworks prefix. |
| URL Pattern | What you configure on the listener — e.g., /hl7/patient, /webhook/stripe, /orders/inbound. |
Example. Instance https://app.etlworks.com + URL Pattern /hl7/patient → endpoint https://app.etlworks.com/rest/v1/httplistener/hl7/patient.
The URL pattern should start with / and use kebab-case or /path/segments for readability. Stick to ASCII letters, digits, hyphens, and slashes.
CORS / OPTIONS preflight
HTTP Listeners process inbound HTTP OPTIONS requests for CORS preflight. Browser-side JavaScript clients can POST, PUT, or DELETE to a listener endpoint without the preflight being rejected — the listener responds to the OPTIONS request with the appropriate CORS headers (Access-Control-Allow-*) and the configured success code (default 204, configurable via Successful DELETE or OPTIONS response code).
What this means in practice. A web page hosted at https://yourapp.example.com can use fetch() to POST a JSON body to a listener at https://app.etlworks.com/rest/v1/httplistener/orders/inbound without configuring a separate API gateway for CORS — the listener handles preflight on its own.
Create an HTTP Listener
- Open Connections and select the Listeners tab.
- Click +, search for HTTP, and select HTTP.
- Set URL Pattern, Method, and Auth Type (the three required fields).
- Build a flow whose source is this listener.
- Schedule the flow with a continuous-execution schedule so the listener stays live.
Common parameters
| Parameter | Default | What it does |
|---|---|---|
| URL Pattern (required) | (blank) | The path appended to {integrator-host}/rest/v1/httplistener. Must start with / and be unique across all listeners on the instance. |
| Method (required) | GET | HTTP method the listener accepts: GET, POST, PUT, DELETE. OPTIONS preflight is handled automatically regardless of the configured method. |
| Auth Type (required) | JWT | Authentication scheme: JWT (Etlworks-issued access token, obtained via the authentication API) or Basic (username + password). See Authentication. |
| Auth Location (required) | Header | Where the caller passes credentials: in HTTP Header or as a Query parameter. Header is the standard, more secure choice; query-string auth is sometimes needed for clients that can't set headers. |
| Pass request headers to the flow as parameters | false | When enabled, all inbound HTTP headers are exposed to the flow as flow variables — reference them like any other parameter (e.g., {User-Agent}, {X-Webhook-Signature}). Useful for webhook signature verification and conditional flow logic based on request metadata. See About parametrization. |
| Request Preprocessor script | (blank) | JavaScript run against the raw request before the flow sees it. Can rewrite the request body, set the response body directly, and control success / failure. See The preprocessor script for the API and an example. |
| HTTP Code Variable | (blank) | Name of a flow variable that holds the HTTP response code at the end of the flow. When set and the variable is populated by the flow, the listener returns that code on the response. Empty or missing variable means the default code applies. |
GET / DELETE / OPTIONS parameters
| Parameter | Default | What it does |
|---|---|---|
| Empty GET response code (required) | 200 | HTTP code returned when the flow produces an empty response body (nothing, empty object, or empty array). REST convention prefers 404 for "not found" semantics; keep 200 when an empty response is a legitimate result. |
| Successful DELETE or OPTIONS response code (required) | 204 | HTTP code returned on a successful DELETE request and on the OPTIONS preflight response. 204 No Content is the REST standard for both. |
POST / PUT parameters
| Parameter | Default | What it does |
|---|---|---|
| POST/PUT processing (required) | Async | Sync: the flow runs and the response is returned on the same HTTP response. Async: the request is queued, the listener returns HTTP 200 immediately, and the flow runs in the background. Use Sync when the caller needs the result; use Async when the work takes longer than the caller's timeout. GET and DELETE are always synchronous. |
| POST/PUT Response File Name | (blank) | Path to a file whose contents are returned as the response body. Supports {token} substitution for dynamic file names. Leave blank to return the flow's output or the preprocessor's response value. |
| Default Payload | (blank) | Response body returned when a POST / PUT arrives with an empty body. Useful for endpoints that need a stable response even when the caller sends nothing. |
| Non strict UTF-8 payload encoding | false | By default, payloads containing non-UTF-8 characters throw an exception. Enable to accept them and let the flow handle decoding. |
| Preserve raw request body | false | When enabled, the POST / PUT payload is read as raw bytes, passed to the flow as Base64 via parameters like http_request_body_base64, and forwarded without parsing. Use for binary uploads (PDFs, images, EDI binaries) and signature-sensitive payloads where any re-encoding would break the signature (Stripe webhooks, GitHub webhooks). |
| Queue priority | (blank) | When global queuing is enabled and the listener is set to Async, this value sets the queue priority for inbound requests. Useful for prioritizing partner-A traffic over partner-B traffic during congestion. |
Authentication
Two authentication schemes are supported.
JWT (recommended for production)
The caller passes an Etlworks-issued access token. Token issue and refresh go through the Etlworks authentication API. JWT is the standard choice for partners and other Etlworks instances calling each other.
Header form (recommended):
Authorization: Bearer <access-token>
Basic (username + password)
The caller passes Etlworks credentials encoded in standard HTTP Basic form. Simpler to set up, less secure than JWT — pick when the calling system can't manage token refresh.
Header form (recommended):
Authorization: Basic <base64(username:password)>
Query-string form (when Auth Location is set to Query parameter):
https://app.etlworks.com/rest/v1/httplistener/hl7/patient?Authorization=Basic%20<base64(username:password)>
The preprocessor script
The Request Preprocessor script runs as soon as the request arrives, before the flow is invoked. Use it to:
- Rewrite the request body (clean up partner-specific quirks, normalize headers, redact PII).
- Short-circuit the flow with a direct response (validation failure, idempotency cache hit).
- Set the response code and body dynamically.
- Verify webhook signatures before the flow runs.
The script has access to a request object. Common methods:
| Method | What it does |
|---|---|
| request.getInput() | Returns the raw request body as a string. |
| request.setInput(text) | Replaces the request body before the flow sees it. |
| request.setSuccess(boolean) | true → success response (HTTP 200 by default). false → error response (HTTP 500 by default). |
| value (assign) | Setting the script's value variable returns that value as the response body without invoking the flow. |
Example: replace whitespace with dashes, return an error response without running the flow.
request.setInput(request.getInput().replace(/ /g, '-')); request.setSuccess(false); value = 'Expected response';
Synchronous vs asynchronous POST / PUT
| Sync | Async | |
|---|---|---|
| Flow execution | Runs inline; the caller waits. | Queued and run in the background; the caller doesn't wait. |
| HTTP response | Returns when the flow finishes — flow output, preprocessor response, or response-file body. | Returns immediately with HTTP 200. |
| Best for | Webhook responses, API gateways, anything where the caller needs the result. | Long-running flows (file processing, downstream-system loads), partner timeouts shorter than your processing time. |
| Caller sees errors? | Yes — HTTP 500 on flow failure. | No — the queued flow's failure is logged but not surfaced to the caller. Monitor through the Flow Findings dashboard or alerts. |
GET and DELETE are always synchronous (the caller always needs the result).
Related articles
- Building custom APIs — end-to-end patterns: PULL (expose a data source as an endpoint), PUSH (accept inbound POST and run a flow), webhook intake.
- HTTP API Connector — the outbound side of HTTP in Etlworks.
- AS2 listener — sibling listener for inbound AS2 (EDI over signed-and-encrypted HTTP).
- About parametrization — how to reference request headers and other variables in the flow.