Skip to main content

HTTP Activities

One activity, http.request, makes an HTTP call from a workflow. It is the most common way to reach a service that has no dedicated activity provider.

Setup

No configuration is required. Two environment variables on the worker affect every call:

VariableEffect
MOCO_HTTP_PROXYUsed as the proxy when proxy is not set on the activity
MOCO_HTTP_PROXY_BYPASSSemicolon-separated host patterns that skip the proxy, * glob supported — e.g. localhost;127.0.0.1;*.internal.corp

Bearer authentication uses an encrypted token rather than a secret key name — see Authentication below.

Destinations can be restricted

Every call asserts the internal.http_activities / invoke privilege with the target's <scheme>://<host> as evidence, so a deployment can allowlist destinations. If no such policy is deployed the check passes — see Authz Activities.


http.request

Sends an HTTP request and returns the status, headers and body. The body is returned as text by default, or parsed JSON with output_json: true.

A non-2xx response is not an error by default: the activity returns normally with is_success: false. Set raise_for_status: true to fail the activity instead.

Input

FieldTypeRequiredDefaultDescription
methodstryesHTTP method: GET, POST, PUT, DELETE, PATCH, …
urlstryesTarget URL
contentstrnonullRaw string body. Use for plain text or a pre-serialized payload
datadictnonullForm body, sent as application/x-www-form-urlencoded
json_dataanynonullJSON body. Sets Content-Type: application/json
headersdict[str, str]nonullExtra request headers
encrypted_auth_tokenEncryptedDatanonullEncrypted bearer token, decrypted inside the activity and sent as Authorization: Bearer <token>
follow_redirectsboolnoclient defaultFollow 3xx redirects
proxystrnoMOCO_HTTP_PROXYProxy URL, e.g. http://proxy.example.com:8080
output_jsonboolnofalseParse the response body as JSON into json instead of returning text
skip_cert_verifyboolnofalseSkip TLS certificate verification
raise_for_statusboolnofalseFail the activity on a 4xx/5xx response

Only one of content, data and json_data should be set.

EncryptedData

The output of builtin.secret.get. Pass it through unchanged.

FieldTypeRequiredDescription
encrypted_datastryesThe encrypted secret
encrypt_key_namestryesName of the key it was encrypted with

Output

FieldTypeDescription
status_codeintHTTP status code
is_successboolTrue for a 2xx response
headersdict[str, str]Response headers
textstrResponse body, when output_json is false or unset
jsonanyParsed response body, when output_json is true

text and json are mutually exclusive — exactly one of them is present.

Examples

A GET with an explicit retry policy, from moco-examples/moco-workflow-demo/src/activity-options-demo.yaml:

- activity:
name: fetch-with-retry
type: http.request
input_data:
method: GET
url: https://httpbin.org/get?demo=retry
retry_policy:
timeout_sec: 10
max_attempts: 3
initial_interval_sec: 1
backoff_coefficient: 2.0
non_retryable_error_types:
- ValueError
output_data:
- fetched_args: '{{ _raw_output.get("json", {}).get("args") if _raw_output else None }}'

A POST with a JSON body, reading the parsed response:

- activity:
name: create-order
type: http.request
input_data:
method: POST
url: https://api.example.com/orders
headers:
Accept: application/json
json_data:
order_id: "{{ order_id }}"
items: "{{ items }}"
output_json: true
raise_for_status: true
retry_policy:
max_attempts: 1 # POST is not idempotent
output_name: created # -> status_code, is_success, headers, json

Authentication

http.request does not take a *_secret_key field. Fetch the token with builtin.secret.get, which returns it still encrypted, and hand the blob straight to encrypted_auth_token — the activity decrypts it internally, so the plaintext token never enters workflow context.

- activity:
type: builtin.secret.get
input_data:
secret_name: PARTNER_API_TOKEN
output_name: api_token

- activity:
type: http.request
input_data:
method: GET
url: https://api.partner.example.com/v1/accounts
encrypted_auth_token: "{{ api_token }}"
output_json: true
output_name: accounts

For any other scheme — an API key header, basic auth — build the header yourself, but note that doing so puts the credential into workflow context and history.

The default retry policy retries writes

http.request inherits the platform default of 3 attempts. A POST that is not idempotent will be sent up to three times on transient failures; set max_attempts: 1 for those.

Request timeout

When retry_policy.timeout_sec is not set, the underlying HTTP client uses a 45-second timeout — shorter than the 60-second activity default. Set timeout_sec explicitly for slow endpoints.