HTTP Step Type: Call HTTP Endpoints from Workflows and Custom Commands
Workflows and custom commands now support a native http step type that performs an HTTP request — any verb, query-string parameters, headers, and a request body (raw or form/JSON) — with per-attempt timeouts and retries that compose with the existing retry: policy. No more shelling out to curl. (Prefer type: webhook? It's an accepted alias.)
The Problem
Calling an external endpoint from a workflow used to mean a shell step running curl:
steps:
- type: shell
command: |
curl -sf -X POST "https://ci.example.com/hook" \
-H "Authorization: Bearer $TOKEN" \
-d '{"status":"deployed"}'
That works until it doesn't: curl isn't guaranteed to be on the box (especially on Windows), quoting and templating the payload is fiddly, and you get no first-class handling of timeouts or transient failures. Retrying a flaky 5xx meant hand-rolling a bash loop.
The Solution
The http step makes HTTP a first-class citizen:
workflows:
notify:
steps:
- name: trigger
type: http
url: "https://ci.example.com/hook/{{ .env.JOB_ID }}"
method: POST
query:
ref: "{{ .env.GIT_SHA }}"
headers:
Authorization: "Bearer {{ .env.TOKEN }}"
Content-Type: application/json
body: '{"status":"deployed"}'
expect:
status: [200, 201, 202, 204]
response:
- /"status"\s*:\s*"deployed"/
timeout: 30s
retry:
max_attempts: 5
backoff_strategy: exponential
initial_delay: 1s
max_delay: 30s
- name: report
type: info
content: "Endpoint returned HTTP {{ .steps.trigger.metadata.status_code }}"
Everything templates, including the URL, headers, query params, and body — so you can thread values from earlier steps or the environment straight into the request.
Here's the http step calling a local endpoint end to end:
