HTTP and Fetch
WOML supports both managed HTTP and Bun native Fetch.
Managed request
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
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.