> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eigenpal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP Request

> Make an HTTP request to an external API

`action.http`, Make an HTTP request to an external API

Use `action.http` when a workflow needs to call an external service: enrich a
record, fetch a small JSON payload, or write a result into a system of record.

Template the URL, headers, and body from previous step output. Prefer short
timeouts and explicit failure handling. Non-2xx responses fail the step; only
eligible transient failures are retried.

```yaml theme={null}
- name: notify-crm
  type: action.http
  with:
    method: POST
    url: "https://api.example.com/invoices"
    headers:
      Authorization: "Bearer {{ input.crmToken }}"
    body:
      vendor: "{{ steps.extract.output.vendor }}"
      total: "{{ steps.extract.output.total }}"
```

## Durable retries

Only `GET` and `HEAD` requests can use durable retries. In Studio, set the
workflow default under **Workflow settings → Retries**, then choose **Inherit
workflow default**, **Retry automatically**, or **Never retry** in this step's
**Retry** control.

```yaml theme={null}
- name: fetch-catalog
  type: action.http
  retry:
    mode: automatic
    maxAttempts: 3
  with:
    method: GET
    url: "https://api.example.com/catalog"
```

Automatic retries cover transient timeouts, rate limits, and selected retryable
server responses.
They use bounded exponential backoff, honor `Retry-After`, and stop after a
five-minute elapsed budget. Studio allows two or three total attempts,
including the first attempt. The YAML schema accepts up to 10, but the current
worker ceiling is three.

`POST`, `PUT`, `PATCH`, and `DELETE` are never replayed automatically because
they may have side effects. See [Workflows → Retries](/concepts/workflows#retries)
for workflow defaults and step overrides.

## Configuration

Configuration goes inside the step's `with:` block.

<ParamField path="url" type="string" required>
  Request URL (supports template expressions)
</ParamField>

<ParamField path="method" type="&#x22;GET&#x22; | &#x22;HEAD&#x22; | &#x22;POST&#x22; | &#x22;PUT&#x22; | &#x22;PATCH&#x22; | &#x22;DELETE&#x22;" default="GET" />

<ParamField path="headers" type="record<string, string>">
  HTTP headers
</ParamField>

<ParamField path="body" type="unknown">
  Request body (JSON or string)
</ParamField>

<ParamField path="timeout" type="number" default="30000">
  Timeout in milliseconds
</ParamField>

<ParamField path="insecureSkipTlsVerify" type="boolean" default="false">
  If true, skip TLS certificate verification (use only for read-only public endpoints with bad/expired certs)
</ParamField>

## Output

<ResponseField path="status" type="number" required>
  HTTP status code
</ResponseField>

<ResponseField path="statusText" type="string" required />

<ResponseField path="headers" type="record<string, string>" required />

<ResponseField path="body" type="unknown" required>
  Response body (parsed JSON or string)
</ResponseField>

<ResponseField path="responseCharset" type="string" required>
  Charset used to decode the response body (e.g. utf-8, windows-1250)
</ResponseField>
