HTTP and Fetch

WOML supports both managed HTTP and Bun native Fetch.

Managed request

JavaScript
const response = await services.http.request({
  method: "POST",
  url: "https://api.example.com/orders",
  headers: { authorization: `Bearer ${secrets.API_TOKEN}` },
  json: context.payload
}, { name: "create-order" });

return response.data;

Managed HTTP provides bounded parsing, status policy, timeout, cancellation, durable operation history, and stable naming.

Native Fetch

fetch() is Bun's standard Fetch implementation with normal Response, streaming, and non-2xx behavior. WOML observes safe metadata but does not rebuild Fetch in Rust. Neither HTTP surface is an SSRF sandbox in the local trust profile.

Choose the correct surface

Use native Fetch when a library expects the Web API, when you need streaming, or when you must inspect a Response directly. Remember that Fetch does not throw merely because a server returns 404 or 500.

Use managed HTTP for ordinary JSON APIs when you want accepted-status policy, bounded parsing, redirect control, timeout, cancellation, durable operation identity, or direct-to-storage responses.

Make an idempotent managed request

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

return {
  status: response.status,
  customer: response.data
};

The external API must actually honor the selected idempotency header. Sending a key to an API that ignores it provides no exactly-once guarantee.

Protect outbound access

The local runtime can reach private and loopback addresses. If untrusted payload data can influence a URL, apply production egress controls and validate allowed hosts in the workflow. WOML's local HTTP profile is not an SSRF sandbox.