---
id: web--http-client
title: "Http client"
summary: "Sends an HTTP request to a remote server and emits the response as a `WebHttpResponse`. Use it to call REST APIs, download files or post forms. The request is built from the configuration, optionally overridden by a `WebHttpRequest` on the input."
audience: user
keywords: "input, output, method, uri, contenttype, encoding, headers, form, authtype, domain, username, password, bearer, consumerkey, consumersecret, accesstoken, tokensecret, authorization, timeoutms, securityprotocol, useragent, clientcertificate, ignorecertificate, expectcontinue, ignoreresponsecode, sendmetadatavariables, useformencoding, fileformvariable"
---
# Http client

Sends an HTTP request to a remote server and emits the response as a `WebHttpResponse`. Use it to call REST APIs, download files or post forms. The request is built from the configuration, optionally overridden by a `WebHttpRequest` on the input.

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | input | `Viaducta.Plugins.Http.Types.WebHttpRequest`, `Viaducta.TypeSystem.Metadata.NoInputData`, `Viaducta.Plugins.TextPlugin.Types.TextRecord`, `Viaducta.Plugins.FlowTest.Types.TestPluginData` | Triggers one request per record. |
| Output | output | `Viaducta.Plugins.Http.Types.WebHttpResponse` | The response (status, headers, body). |

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `Method` | dropdown: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS` | `GET` | HTTP method. A value other than `GET` overrides the method of an input `WebHttpRequest`. |
| `Uri` | string | | Full request URL. Used when the input has no `Uri`. Not combined with a relative input path. |
| `ContentType` | string | `text/json` | Request content type. If set, it wins over the input's `ContentType`. |
| `Encoding` | dropdown: `UTF8`, `UTF7`, `UTF32`, `ASCII` | `UTF8` | Ignored, see Notes. |
| `Headers` | dictionary (JSON object) | | Extra request headers, e.g. `{"Accept":"application/json"}`. |
| `Form` | dictionary (JSON object) | | Form variables, used with form encoding. |
| `AuthType` | dropdown: `0` None, `1` Basic, `2` Digest, `3` NTLM, `4` Bearer, `5` Jwt, `6` OAuth1, `7` OAuth2, `8` Other, `9` ClientCertificate | `0` | Authentication scheme. |
| `Domain` | string | | Windows domain (`AuthType` `3`). |
| `Username` | string | | User name (`AuthType` `1`, `2`, `3`). |
| `Password` | password | | Password (`AuthType` `1`, `2`, `3`). |
| `Bearer` | string | | Written as-is into the `Authorization` header (`AuthType` `4`, `5`, `7`), so include the scheme: `Bearer eyJ...`. |
| `ConsumerKey` | string | | OAuth 1.0a consumer key (`AuthType` `6`), HMAC-SHA1 signature. |
| `ConsumerSecret` | string | | OAuth 1.0a consumer secret (`AuthType` `6`). |
| `AccessToken` | string | | OAuth 1.0a access token (`AuthType` `6`). |
| `TokenSecret` | string | | OAuth 1.0a token secret (`AuthType` `6`). |
| `Authorization` | string | | Complete `Authorization` header value (`AuthType` `8`). |
| `TimeOutMs` | integer | `30000` | Timeout in milliseconds, `0` = unlimited. |
| `SecurityProtocol` | dropdown: `DEFAULT`, `TLS`, `SSL3` | `DEFAULT` | Ignored, see Notes. |
| `UserAgent` | string | | `User-Agent` header, if not already set by headers. |
| `ClientCertificate` | certificate | | Name of a certificate object in the repository (`AuthType` `9`). |
| `IgnoreCertificate` | boolean | `false` | `true`: accept any server certificate. |
| `ExpectContinue` | boolean | `false` | Sends `Expect: 100-continue`. |
| `IgnoreResponseCode` | boolean | `false` | `true`: non-2xx responses are emitted instead of raising an error. |
| `SendMetadataVariables` | boolean | `false` | `true`: sends the flow session and correlation ids as headers `ViaSessionId` and `ViaCorrelationId`. |
| `UseFormEncoding` | boolean | `false` | `true`: body is sent as `application/x-www-form-urlencoded`. |
| `FileFormVariable` | string | `file` | Multipart field name for file uploads. |

## Behaviour

- Input handling:
  - `NoInputData` / `TestPluginData`: request built only from the configuration.
  - `TextRecord`: `Value` becomes the body, `ContentType` is used if the config `ContentType` is empty. URL and method from config.
  - `WebHttpRequest`: its `Uri`, `Method`, `Headers`, `Cookies`, `Body` / `ByteBody` / `FileName` / `Form` are used. A request that came from an **Http listener** is not forwarded: the plugin then uses only the configuration (no proxying of the incoming body).
- Body, first match wins: form encoding (`UseFormEncoding` or a form content type: config `Form` plus input `Form`; for non-`WebHttpRequest` input also all input properties as form fields) → `Body` as text → `ByteBody` as binary → `ByteBody` + `FileName` as `multipart/form-data` with field `FileFormVariable` → empty body with content type.
- Headers from `Headers` are added first, then the input headers. `Content-*` headers are skipped; set the content type with `ContentType`.
- Responses: text content types (`text/*`, `application/json`, `application/xml`, ...) fill `Body`; everything else fills `ByteBody` with `IsByteBody` = `true`. gzip/deflate are decompressed. `StatusCode`, `Headers`, `ContentType`, `ContentCharset`, `ContentFileName`, `HttpCallDurationMilliseconds` are set.
- Non-2xx status (unless `IgnoreResponseCode`), connection errors and timeouts raise a recoverable error. Network errors and `503` are retried 3 times (after 2, 4 and 8 s). GET, HEAD, PUT, DELETE and OPTIONS are retried on any network error (connection refused, reset or aborted, response ended, name resolution); POST and PATCH only when the connection could not be established or on `503`, because the server may have processed a request whose response got lost. TLS, authentication and proxy errors are not retried. Each retry is logged as a warning and a request that fails on the network is logged as an error with all inner exceptions.
- Connections are reused while they are busy; a connection idle for 30 s is closed by the plugin. Servers commonly close idle connections after 60 s, and a request sent on a reused connection just as the server closes it fails with "The response ended prematurely" (a POST is then not retried). With the 30 s limit a flow calling every minute (e.g. a heartbeat) always gets a new connection.
- The sent request is stored in the `HttpClient` metadata (`Request`).

## Notes

- `Encoding` is ignored (bodies are always UTF-8) and `SecurityProtocol` is ignored (OS default TLS).
- OAuth1 (`6`) signs the request before the method is set, so the signature always uses `GET`; `POST`/`PUT` calls to OAuth1 APIs fail.
- A binary body (`ByteBody`) without any content type (config and input empty) fails with a null reference error.
- The timeout covers sending and the response headers; reading a slow body is not limited by it.
- Store secrets in expression settings (`=Secrets.ApiToken`) rather than in the flow.

## Example

```json
{ "Method": "GET", "Uri": "https://api.example.com/items", "AuthType": 4, "Bearer": "=Secrets.ApiToken", "Headers": { "Accept": "application/json" } }
```

Timer → **Http client** → Json deserializer → ...
