HTTP client for making web requests.

Functions

delete

fn (url: Str): HttpResponse

Send an HTTP DELETE request to url.

Example


response ::hot::http/delete("https://api.example.com/users/1")
// response.status = 204

get

fn (url: Str): HttpResponse

Send an HTTP GET request to url.

Example


response ::hot::http/get("https://api.example.com/users/1")
// response.status = 200
// response.body = {"id": 1, "name": "Alice"}

get-stream

fn (url: Str): StreamingHttpResponse
fn (url: Str, format: StreamFormat): StreamingHttpResponse

Make a streaming HTTP GET request.

Example

response get-stream("https://api.example.com/events", "sse")

for-each(response.body, fn (event) {
    print(event.data)
})

is-ok-response

fn (response: HttpResponse): Bool

Return true if the HTTP response status is between 200 and 299.

Example


response ::hot::http/get("https://api.example.com/data")
if(::hot::http/is-ok-response(response), response.body, err("Request failed"))

patch

fn (url: Str, body: Any): HttpResponse

Send an HTTP PATCH request to url with body.

Example


response ::hot::http/patch("https://api.example.com/users/1", {"email": "new@example.com"})

post

fn (url: Str, body: Any): HttpResponse

Send an HTTP POST request to url with body.

Example


response ::hot::http/post("https://api.example.com/users", {"name": "Bob"})
// response.status = 201

post-stream

fn (url: Str, body: Any, headers: Map, format: StreamFormat): StreamingHttpResponse
fn (url: Str, body: Any, headers: Map): StreamingHttpResponse
fn (url: Str, body: Any): StreamingHttpResponse

Make a streaming HTTP POST request.

Example

response post-stream("https://api.example.com/stream", {query: "test"}, {}, "ndjson")

for-each(response.body, fn (item) {
    print(item)
})

put

fn (url: Str, body: Any): HttpResponse

Send an HTTP PUT request to url with body.

Example


response ::hot::http/put("https://api.example.com/users/1", {"name": "Updated"})

raw-body

fn (request: Map): Str | Bytes

The verbatim body of an inbound request for signature verification: body-bytes when present (the body was not valid UTF-8 and body-raw is lossy), otherwise body-raw ("" when absent). Webhook verifiers should hash this value rather than reading body-raw directly.

Example

::hmac/hmac-verify-hex(secret, ::http/raw-body(request), signature, "sha256")

request

fn (request: HttpRequest): HttpResponse
fn (method: HttpMethod, url: Str, headers: Map, body: Any): HttpResponse

Perform an HTTP request.

Accepts either an HttpRequest or positional arguments (method, url, headers, body).

Transport failures (DNS failure, connection refused, TLS errors, timeouts, ...) return a Result.Err; branch on it with is-err / if-err. An unhandled error halts at first use with the same message. Non-2xx responses are normal HttpResponse values — check response.status.

Examples

// Using HttpRequest
response request(HttpRequest({method: "POST", url: "https://api.example.com/data", body: {name: "Alice"}}))

// Using positional arguments
response request("POST", "https://api.example.com/data", {"Content-Type": "application/json"}, {name: "Alice"})

// Handling transport failure
response request(HttpRequest({method: "GET", url: url}))
if-err(response, (failure) { println(`network error: ${failure}`) })

request-stream

fn (request: HttpRequest): StreamingHttpResponse
fn (request: HttpRequest, format: StreamFormat): StreamingHttpResponse
fn (method: HttpMethod, url: Str, headers: Map, body: Any): StreamingHttpResponse
fn (method: HttpMethod, url: Str, headers: Map, body: Any, format: StreamFormat): StreamingHttpResponse

Make a streaming HTTP request that returns an iterator for the body.

Use this for Server-Sent Events (SSE), NDJSON streams, or any response you want to process incrementally.

Accepts an HttpRequest (with optional format), or positional arguments.

Formats

  • "sse" - Server-Sent Events, parses event/data/id fields
  • "ndjson" - Newline-delimited JSON
  • "raw" - Raw chunks as strings or bytes (default)

Examples

// Using HttpRequest
response request-stream(HttpRequest({method: "GET", url: "https://api.example.com/events"}), "sse")

// Using positional arguments
response request-stream("GET", "https://api.example.com/events", {}, "", "sse")

for-each(response.body, fn (event) {
    print(event.data)
})

Types

HttpMethod

HttpMethod type "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS"

HttpRequest

HttpRequest type {
    method: Str,
    url: Str,
    original-url: Str?,
    headers: Map?,
    query: Map?,
    body: Any?,
    body-raw: Str?,
    body-bytes: Bytes?,
    ip: Str?,
    auth: Map?
}

HTTP request. Used for both inbound webhook requests and outbound HTTP calls.

Fields

  • method - HTTP method (GET, POST, PUT, etc.)
  • url - Request URL (full URL for outbound, path for inbound webhooks)
  • original-url - The URL as the caller originally requested it, before any platform rewriting: scheme, host, full path, and query intact (inbound webhooks only). Providers that sign the URL they call (Twilio, HubSpot) are verified against this field, never url. Contains the webhook token — do not log it.
  • headers - Request headers (keys are lowercase for inbound)
  • query - Query string parameters as a Map (inbound only)
  • body - Parsed body (JSON auto-parsed to Map/Vec for inbound, or the body to send for outbound)
  • body-raw - Original request body as a raw string (inbound only, useful for signature verification)
  • body-bytes - The verbatim body bytes, present only when the body is not valid UTF-8 (inbound only). body-raw is lossy in that case; signature verification should prefer body-bytes when present.
  • ip - Client IP address from proxy headers (inbound only)
  • auth - Caller identity when a webhook or MCP endpoint uses required authentication

Examples

Outbound request:

response request(HttpRequest({method: "POST", url: "https://api.example.com/data", body: {name: "Alice"}}))

Inbound webhook handler:

on-hook
meta {webhook: {service: "demo", path: "/hook"}}
fn (request: HttpRequest): HttpResponse {
    HttpResponse({status: 200, body: request.body})
}

HttpResponse

HttpResponse type {
    status: Int,
    headers: Map?,
    body: Any?,
    body-bytes: Bytes?
}

HTTP response returned from request functions or webhook handlers.

Example

response ::hot::http/get("https://api.example.com/users/1")
response.status   // 200
response.headers  // {"content-type": "application/json", ...}
response.body     // {"id": 1, "name": "Alice"}
response.body-bytes // Raw response bytes

StreamFormat

StreamFormat type "sse" | "ndjson" | "raw"

StreamingHttpResponse

StreamingHttpResponse type {
    status: Int,
    headers: Map,
    body: Any
}

HTTP response with a streaming body iterator.

Fields

  • status - HTTP status code
  • headers - Response headers
  • body - An iterator that yields chunks from the response stream