HTTP and Fetch

Every managed failure is catchable as WomlServiceError with stable fields:

JavaScript
error.code
error.service
error.operation
error.callId
error.retryable
error.ambiguous
error.details

Give repeated effectful operations in one step stable { name: "..." } options. Names identify logical effects and must not depend on attempt number or loop order.

The default managed-capability boundary accepts 1 MiB input, 4 MiB result, an 8 MiB transport frame, and a 30-second operation timeout unless a particular service documents a smaller limit or the request supplies a supported timeout.

Native fetch()

JavaScript
const response = await fetch("https://api.example.com/data");
const data = await response.json();

This is Bun's standard Fetch API: it returns Response, supports streams, and does not throw merely because the status is non-2xx. WOML records redacted observations, but Bun owns the actual request/body. Use it for Web API compatibility and streaming. Prefer managed HTTP when you need Rust-owned limits, status policy, cancellation, and durable operation outcomes.

services.http.request()

JavaScript
const response = await services.http.request({
  url: "https://api.example.com/customers",
  method: "POST",
  headers: { authorization: `Bearer ${secrets.API_TOKEN}` },
  query: { source: "woml" },
  json: { customerId: "customer-42" },
  timeout: "10s",
  acceptedStatus: { minimum: 200, maximum: 299 },
  redirect: "follow",
  maximumRedirects: 10,
  idempotency: {
    header: "Idempotency-Key",
    value: attempt.idempotencyKey
  }
}, { name: "create-customer" });

Request fields:

FieldMeaning
urlRequired HTTP(S) URL.
methodDefaults to GET.
headersString header map. Credentials remain private operation input.
queryPrimitive query values.
json, text, bytesBase64Mutually exclusive body forms.
responseTypejson (default), text, bytes, or storage.
timeout / timeoutMsRequest deadline; default 30 seconds.
acceptedStatusAccepted status interval; default 200–299.
redirectfollow, error, or manual.
maximumRedirectsDefaults to 10.
storageDirect-to-storage target when responseType="storage".
idempotencyExternal idempotency header/value contract.

Return value:

JavaScript
{
  status,
  ok,          // true only for native HTTP 2xx
  headers,
  data,
  url,
  redirected
}

Rust owns pooling, TLS validation, redirect handling, decompression, parsing, timeouts, cancellation, response limits, and operation events. The local profile allows reachable HTTP(S) destinations, including private and loopback addresses; production users must apply egress controls when untrusted input can influence URLs.