http#

Source: builtin/http

HTTP request provider.

Provider configuration#

NameTypeRequiredDefaultDescription
base_urlstringnoPrepended to relative URLs in requests. When unset, URLs must be absolute.
default_headersmap(string)noHeaders added to every request; per-request headers take precedence.
timeout_secondsnumberno30Per-request timeout in seconds applied to the full request/response round-trip.

Actions#

http_request#

Issue an HTTP request and capture the response.

Simple GET against a relative path resolved via base_url.

action "http_request" "fetch_user" {
  method = "GET"
  url    = "/users/42"
}

Attributes

NameTypeRequiredDefaultDescription
bodystringnoRequest body, sent as-is. Set the Content-Type header to control parsing on the server.
headersmap(string)noPer-request headers, merged over default_headers.
methodstringno"GET"HTTP method (GET, POST, PUT, PATCH, DELETE).
urlstringyesAbsolute URL, or relative path resolved against base_url.

Outputs

Type: object({body=string,headers=map(string),status=number}).

Response status code, body, and headers.

FieldTypeDescription
statusnumberHTTP status code (for example 200, 404).
bodystringFull response body, decoded as a string.
headersmap(string)Response headers. Multi-valued headers are collapsed to the first value.

Examples#

POST a JSON payload, then fetch the created resource.

scenario "http_demo" {
  required_providers {
    http = { source = "builtin/http" }
  }

  provider "http" {
    base_url = "https://api.example.com"
    default_headers = {
      X-Client = "orchard"
    }
    timeout_seconds = 10
  }

  action "http_request" "create_user" {
    method = "POST"
    url    = "/users"
    headers = {
      Content-Type = "application/json"
    }
    body = jsonencode({ name = "Alice", email = "alice@example.com" })
  }

  action "http_request" "fetch_user" {
    url = "/users/${action.http_request.create_user.body}"
  }

  output "created_status" { value = action.http_request.create_user.status }
  output "fetched_body"   { value = action.http_request.fetch_user.body }
}

Notes#

  • URL resolution. Relative URLs resolve against base_url via Go’s url.ResolveReference. Absolute URLs (starting with http:// or https://) bypass base_url.
  • Header merging. For each request, default_headers is applied first, then per-request headers. Per-request values override defaults on key collision.
  • No retries. The action fails on any transport error or non-2xx response interpretation — the provider simply returns whatever the server sent. Use the action-level retry { } block to retry on failure.
  • Response body. The body is read entirely into memory and decoded as UTF-8. Large responses or binary content may be unsuitable.