Outbound Webhook Step
Send HTTP requests to external endpoints during a workflow, and optionally capture the response so you can map values into later steps.
The Outbound Webhook step sends an HTTP request to an external URL while a workflow runs. Use it to notify another system, create or update a record in a third-party API, or upload a file. You can run the request in the background, or wait for a response and pass response data to steps that follow.
For mapping placeholder syntax, see Mapping.
Waiting for a response
Set waitForResponse to true if the workflow should pause until the HTTP call finishes. When the external service returns a body (and a content type is present), Streamline stores that response so later steps can map values from it. response.statusCode is always available as a numeric field when the response is captured.
For JSON responses, the body is flattened into dot-notation paths that start with body. (for example, body.id or body.user.email). Non-JSON bodies, or JSON that fails to parse, are exposed as a single string field named body.
If waitForResponse is false, the workflow does not capture the HTTP response for mapping into later steps.
Continue on error
When continueOnError is true, HTTP error status codes (4xx/5xx) or network failures do not stop the workflow. The step can finish with a completed-with-errors state instead of failing the run. Default is false (failures stop the step).
Configuration
| name | type | required | description |
|---|---|---|---|
request | object | yes | The HTTP request to send. See Request below. |
waitForResponse | boolean | no | When true, the workflow waits for the HTTP response before continuing. Required if later steps should map response values. Default: false. |
continueOnError | boolean | no | When true, the workflow continues when the request fails or returns an error status. Default: false. |
listeningModeEnabled | boolean | no | When true, the next test request captures the response for field extraction. Streamline resets this to false after extraction completes. Default: false. |
requestPayload | string | no | String snapshot of the outbound request. Streamline sets this when a test succeeds; you can also set it when updating the project. Field extraction reads this together with responsePayload. |
responsePayload | string | no | String snapshot of a sample response body. Streamline sets this when a test succeeds; it feeds field extraction. Default: empty string. |
mappableFields | array | no | Field descriptors for mapping into later steps. See Mappable fields. Default: empty array. |
Request
The request object defines the HTTP call.
| name | type | required | description |
|---|---|---|---|
method | string | yes | HTTP method: GET, POST, PUT, or DELETE. |
url | string | yes | Endpoint URL. Path placeholders use the :name form (for example :userId); supply values in pathParams. |
authentication | object | yes | Authentication settings. See Authentication below. |
pathParams | array | no | Path parameter values. Each item has key and value (values support mapping). |
queryParams | array | no | Query string parameters. Each item has key and value (values support mapping). |
headers | array | no | Custom HTTP headers. Each item has key and value (values support mapping). Header names are normalized to lowercase. |
body | object | varies | Request body. See Body modes. Required for POST and PUT. Optional for DELETE. Not used for GET. |
Authentication
| name | type | required | description |
|---|---|---|---|
type | string | yes | NONE (no authentication) or AUTHENTICATED (use a stored connection). |
connectionId | string | yes | ID of the stored connection when type is AUTHENTICATED. Use null when type is NONE. |
Body modes
The shape of body is determined by requestMode.
RAW
Send JSON or plain text. String values support mapping placeholders.
| name | type | required | description |
|---|---|---|---|
requestMode | string | yes | Must be RAW. |
contentType | string | yes | JSON or TEXT. |
content | string or object | no | Body content. For JSON, either a string or an object whose string values support mapping. |
MULTIPART
Send multipart/form-data. Each part is either text (string value) or a file resolved from a file reference or mapping placeholder.
| name | type | required | description |
|---|---|---|---|
requestMode | string | yes | Must be MULTIPART. |
content | array | yes | Form fields: each item has key and value (values support mapping). |
RAW_BINARY
Send a single file as the entire request body.
| name | type | required | description |
|---|---|---|---|
requestMode | string | yes | Must be RAW_BINARY. |
rawBinaryFile | varies | yes | A file reference or a mapping placeholder (e.g. {{Form.uploadedDocument}}). See File object. |
File object
Use when referencing a file by ID or download URL (instead of only a mapping placeholder).
| name | type | required | description |
|---|---|---|---|
id | string | yes (variant A) | File identifier. Use either id or downloadUrl, not both. |
downloadUrl | string | yes (variant B) | File download URL. Use either id or downloadUrl, not both. |
name | string | yes | File name. |
metadata | object | no | Optional: contentType, size, createdAt, updatedAt. |
Mappable fields
mappableFields declares which response properties later steps can map and supplies type hints. Each key must match the flattened JSON path your endpoint returns, without the body. prefix (for example id or user.email, not body.id).
Supported type values include: string, number, boolean, date, datetime, object, array, and file.
| name | type | required | description |
|---|---|---|---|
key | string | yes | Flattened JSON key without the body. prefix (e.g. status, user.email). |
label | string | yes | Human-readable label for the field. |
type | string | yes | Data type (see list above). |
exampleValue | varies | no | Optional example value (string, number, boolean, or null) stored with the field and shown in Streamline where sample values are displayed. |
Populating mappable fields
mappableFields is a regular configuration property — you can populate it automatically from a test request, or write the array directly when you update the project.
Option A: Extract from a test request
To derive fields from a real HTTP call, use the outbound webhook test endpoint. Append ?test=true to the step's webhookSessionStartUrl from the project response:
POST {webhookSessionStartUrl}?test=true
Use the same authentication as for other /v1/sessions requests (bearer token). The body is a JSON array of objects with id, type, and sampleValue for each mapped input the test request should resolve; send [] when there are no mapped inputs. A successful response includes responsePayload, requestPayload, and extractedFields. On your next project update, persist extractedFields as mappableFields, and persist responsePayload and requestPayload so field extraction has both snapshots.
Option B: Set mappable fields directly
If you already know the response structure, you can include mappableFields in the step configuration when you create or update the project via PATCH /v1/projects/{projectId}:
PATCH /v1/projects/{projectId}
{
"workflow": {
"steps": [
{
"type": "outbound_webhook",
"description": "Notify CRM",
"config": {
"request": { "..." : "..." },
"waitForResponse": true,
"mappableFields": [
{ "key": "id", "label": "User ID", "type": "string" },
{ "key": "status", "label": "Status", "type": "string" }
]
},
"edges": []
}
]
}
}Customizing after extraction
Whether fields were extracted automatically or written directly, you can modify them at any time by updating the project. Add fields, remove fields, rename labels, or change types — then update the step's mappableFields array in the project. Later steps that reference these fields by key use whatever is currently stored on the step.
Examples
Simple GET with no authentication or body:
{
"request": {
"method": "GET",
"url": "https://api.example.com/users",
"authentication": { "type": "NONE", "connectionId": null }
}
}POST with a raw JSON body (string form):
{
"request": {
"method": "POST",
"url": "https://api.example.com/webhook",
"authentication": { "type": "NONE", "connectionId": null },
"body": {
"requestMode": "RAW",
"contentType": "JSON",
"content": "{\"message\": \"Hello\"}"
}
}
}POST with connection auth, path/query parameters, JSON object body with mappings, and response mapping:
{
"request": {
"method": "POST",
"url": "https://api.example.com/users/:userId",
"authentication": { "type": "AUTHENTICATED", "connectionId": "my-api-connection" },
"pathParams": [
{ "key": "userId", "value": "{{`Form`.`userId`}}" }
],
"queryParams": [
{ "key": "format", "value": "json" }
],
"headers": [
{ "key": "X-Custom-Header", "value": "custom-value" }
],
"body": {
"requestMode": "RAW",
"contentType": "JSON",
"content": {
"name": "{{`Form`.`userName`}}",
"email": "{{`Form`.`userEmail`}}",
"metadata": {
"source": "workflow",
"requestId": "{{`Form`.`requestId`}}"
}
}
}
},
"waitForResponse": true,
"mappableFields": [
{ "key": "id", "label": "User ID", "type": "string", "exampleValue": "usr-12345" },
{ "key": "status", "label": "Status", "type": "string", "exampleValue": "created" }
]
}Multipart POST with form fields:
{
"request": {
"method": "POST",
"url": "https://api.example.com/submit",
"authentication": { "type": "NONE", "connectionId": null },
"body": {
"requestMode": "MULTIPART",
"content": [
{ "key": "name", "value": "{{`Form`.`userName`}}" },
{ "key": "description", "value": "Static description" }
]
}
}
}Binary file upload with a file object:
{
"request": {
"method": "POST",
"url": "https://api.example.com/upload",
"authentication": { "type": "AUTHENTICATED", "connectionId": "file-api" },
"body": {
"requestMode": "RAW_BINARY",
"rawBinaryFile": {
"id": "file-123",
"name": "document.pdf",
"metadata": {
"contentType": "application/pdf",
"size": 1024000
}
}
}
}
}Binary file upload with a mapping placeholder:
{
"request": {
"method": "PUT",
"url": "https://api.example.com/files",
"authentication": { "type": "NONE", "connectionId": null },
"body": {
"requestMode": "RAW_BINARY",
"rawBinaryFile": "{{`Form`.`uploadedDocument`}}"
}
}
}DELETE with an optional body:
{
"request": {
"method": "DELETE",
"url": "https://api.example.com/resources/:resourceId",
"authentication": { "type": "AUTHENTICATED", "connectionId": "api-connection" },
"pathParams": [
{ "key": "resourceId", "value": "{{`Form`.`resourceId`}}" }
],
"body": {
"requestMode": "RAW",
"contentType": "JSON",
"content": "{\"reason\": \"cleanup\"}"
}
}
}Updated about 1 month ago
