Client API

    Client Types and Operations

    HTTP.TransportType
    Transport(; ...)

    Connection-pooling transport for HTTP/1 requests.

    It owns dial/TLS policy and decides when an idle connection can be reused versus closed.

    max_conns_per_host = 0 leaves per-host concurrency unlimited. Positive values bound the total live HTTP/1 connections (idle, in-flight, and dialing) for one pool key and cause additional acquires to wait for direct handoff or a freed dial slot.

    source
    HTTP.ClientType
    Client(; ...)

    High-level HTTP client with transport pooling, redirect policy, cookies, and optional HTTP/2. Also acts as a configuration container so that defaults set once on the client (headers, query parameters, timeouts, basic auth) apply to every request issued through it unless the per-call request/get/post keywords override them.

    Keyword arguments:

    • transport: reusable lower-level HTTP/1 transport/pool implementation
    • check_redirect: optional callback deciding whether a redirect should be followed
    • cookiejar: cookie jar implementation, or nothing to disable cookies
    • max_redirects: maximum redirect hops before failing
    • prefer_http2: whether secure requests should try HTTP/2 when available
    • default_headers: headers applied to every request issued through this client; per-call headers are appended on top, and per-call values for the same name take precedence
    • default_query: query parameters appended to every request URL; per-call query overrides any keys it shares with the default
    • default_basicauth: default basic-auth credentials applied unless the call passes basicauth or an explicit Authorization header
    • connect_timeout, request_timeout, response_header_timeout, read_idle_timeout, write_idle_timeout: defaults applied to every request unless the call passes the matching keyword. 0 disables.

    Pass a Client with the client keyword to request, get, open, or the other verb helpers when you want connection reuse and shared cookies across many calls. The verb helpers also accept the client positionally (HTTP.get(client, url; ...)). Close the client when you are finished; once closed, subsequent calls that use it raise ArgumentError.

    source
    HTTP.RetryBucketType
    RetryBucket(; backoff_scale_factor_ms=25, max_backoff_secs=20, capacity=500)

    Shared retry-budget bucket keyed by caller-supplied partitions.

    Each partition tracks its own remaining capacity. acquire(bucket, partition) reserves retry capacity for one retry attempt, and release(bucket, token, failure_cost) returns all or part of that reserved capacity. Use failure_cost = 0 for a full refund, or a positive cost to keep some or all of the reserved retry capacity consumed.

    source
    HTTP.RequestRetryErrorType
    RequestRetryError(err)

    Wrapper passed to retry_if for request-path failures. Inspect err.err to check the underlying transport or protocol exception.

    source
    HTTP.roundtrip!Function
    roundtrip!(transport, address, request; secure=false, server_name=nothing) -> Response

    Execute a single request through transport without the higher-level redirect, cookie, or retry orchestration provided by Client.

    source
    HTTP.requestFunction
    request(method, url::Union{AbstractString,URI}, headers=Pair{String,String}[], body=nothing; trace=nothing, kwargs...)
    request(trace, method, url::Union{AbstractString,URI}, headers=Pair{String,String}[], body=nothing; kwargs...)

    High-level one-shot HTTP request API.

    When trace is provided, it must be callable on any emitted client event. Current events are RequestEvent, ResponseHeadEvent, RetryEvent, RedirectEvent, and DoneEvent.

    Keyword arguments:

    • basicauth: optional basic-auth credentials supplied as (username, password) or username => password; explicit Authorization headers take precedence, and URL userinfo is only used as a fallback when neither is provided
    • retry: overall toggle for high-level request retries; lower-level reused-connection transport retries still happen independently
    • retries: maximum number of retry attempts after the initial request attempt
    • retry_non_idempotent: allow automatic retries for methods like POST/PATCH; PUT and DELETE are already treated as idempotent
    • retry_if: optional callback (attempt, err, req, resp) -> Bool | nothing; request-path failures are passed as RequestRetryError so implementations can inspect err.err, while response-based retry checks pass err = nothing and resp = response; true forces a retry when the request body is replayable, false suppresses retry, and nothing defers to built-in retry rules
    • respect_retry_after: honor server Retry-After on retryable 429/503 responses
    • retry_bucket: true uses the request transport's default RetryBucket, false disables bucket coordination, and a custom RetryBucket overrides the transport default
    • automatic retries only occur for replayable request bodies; built-in policy retries idempotent methods (GET, HEAD, OPTIONS, TRACE, PUT, DELETE) plus requests carrying Idempotency-Key/X-Idempotency-Key
    • status_exception: throw StatusError for non-success responses
    • redirect: follow redirects through do!
    • redirect_limit: maximum number of redirects to follow for this call; 0 disables redirect following while still returning the redirect response
    • redirect_method: override the method used for 301/302 redirects; pass :same to preserve the original method
    • forwardheaders: whether original request headers are copied onto redirect follow-up requests
    • request bodies may be passed positionally or, for convenience helpers like post(url; body=...), via the body keyword; supported inputs include strings, byte vectors, IO, Dict/NamedTuple form fields, HTTP.Form, iterable chunks, and existing HTTP.AbstractBody values
    • proxy: explicit proxy override for this call; pass a proxy URL string, a ProxyConfig, or nothing to force direct connections
    • cookies: true to use the effective cookie jar, false to disable cookie send/store for this call, or a dictionary of extra cookie name/value pairs to append to jar-derived cookies
    • cookiejar: optional cookie jar override for this call; explicit clients default to client.cookiejar, while implicit convenience calls default to the shared HTTP.COOKIEJAR
    • query: optional query string or key/value collection appended to the URL
    • response_stream: optional sink IO or byte buffer written with the final response body
    • decompress: nothing/true auto-decompress gzip and deflate responses, false leaves wire bytes untouched
    • sse_callback: callback receiving (event) or (stream, event) for successful SSE responses
    • trace: optional callback receiving request lifecycle events
    • verbose: false disables built-in logging; true/1 prints high-level request lifecycle lines to stdout; 2 also prints request and response heads. When combined with trace, verbose output is emitted before the user trace is called.
    • client: optional explicit Client; otherwise a default or ephemeral client is created
    • connect_timeout: connection establishment timeout in seconds, covering DNS, TCP connect, proxy CONNECT, TLS handshake, and HTTP/2 session setup in the high-level client paths
    • request_timeout: overall request deadline in seconds
    • response_header_timeout: maximum time to wait for response headers after the request has been sent
    • read_idle_timeout: maximum time between inbound read progress events
    • write_idle_timeout: maximum time between outbound write progress events
    • expect_continue_timeout: how long to wait for a 100 Continue response before sending the request body anyway; pass 0 to disable the wait
    • readtimeout: deprecated alias for read_idle_timeout
    • require_ssl_verification: disable certificate verification only for testing
    • protocol: :auto, :h1, or :h2

    HTTP.jl 2.0 accepts several HTTP.jl 1.x keywords as migration shims: readtimeout maps to read_idle_timeout; pool, retry_delays, retry_check, sslconfig, socket_type_tls, copyheaders, canonicalize_headers, detect_content_type, logerrors, logtag, and observelayers are accepted so older call sites fail less abruptly. Prefer the 2.0 forms listed above for new code: client / transport for pooling, retry_if / retry_bucket for retries, Reseau Transport TLS configuration for TLS/socket behavior, and verbose / trace for request observation.

    The built-in retry policy is intentionally conservative: it retries transient transport errors plus retryable 408/429/5xx responses for replayable requests, but does not automatically retry request read-timeout/deadline failures.

    Returns a high-level Response. When no response body sink is provided, response.body is a fully materialized Vector{UInt8}. When response_stream is provided, the final Response contains either the filled buffer/view or nothing for IO sinks.

    Working with the response body

    By default the buffered body is a Vector{UInt8}:

    using HTTP
    
    response = HTTP.get("http://example.com")
    @assert response.body isa Vector{UInt8}

    Convert it to a String with String(response.body):

    text = String(response.body)
    `String(response.body)` consumes the bytes

    String(::Vector{UInt8}) is the standard Julia conversion and it aliases the underlying byte buffer rather than copying it. After String(response.body) runs, response.body is left empty (length == 0). If you want to keep the bytes around, take a copy first (copy(response.body) or String(copy(response.body))), or use the response_stream keyword to write the body somewhere you own.

    Sending JSON

    There is no json= keyword. Serialize the payload yourself with the JSON library of your choice — JSON.jl is the recommended option — and set the Content-Type header explicitly:

    using HTTP, JSON
    
    payload = Dict("name" => "alice", "age" => 30)
    response = HTTP.post(
        "https://api.example.com/users";
        headers = ["Content-Type" => "application/json"],
        body = JSON.json(payload),
    )
    
    returned = JSON.parse(String(response.body))

    Form-encoded payloads (application/x-www-form-urlencoded) are auto-derived from Dict/NamedTuple bodies, so HTTP.post(url, [], Dict("a" => "1")) sends a=1 with the matching Content-Type header for you.

    Default headers

    If the caller does not supply them, HTTP.jl fills in:

    • User-Agent: HTTP.jl/<version> — override by passing your own User-Agent header.
    • Accept-Encoding: gzip, deflate — disable by passing decompress=false or by setting your own Accept-Encoding.

    Throws ArgumentError for unsupported inputs or invalid sink combinations, StatusError (with .status and .response fields) when status_exception=true and the response status is considered failing, HTTP.TimeoutError (alias HTTP.HTTPTimeoutError) for timeout failures, plus any lower-level transport or protocol exception raised during the request. Automatic retries only occur for replayable request bodies.

    source
    Base.getFunction
    get(headers, key, default) -> String

    Dict-style get on Headers. Returns the first value for key, or default if the header is absent.

    source
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.headFunction
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.postFunction
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.putFunction
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.patchFunction
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.deleteFunction
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.optionsFunction
    request(method, url, headers=Pair{String,String}[], body=nothing; kwargs...)
    get(url, headers=Pair{String,String}[]; kwargs...)
    head(url, headers=Pair{String,String}[]; kwargs...)
    post(url, [headers], [body]; kwargs...)
    put(url, [headers], [body]; kwargs...)
    patch(url, [headers], [body]; kwargs...)
    delete(url, [headers], [body]; kwargs...)
    options(url, headers=Pair{String,String}[]; kwargs...)

    High-level one-shot client request helpers. The verb helpers call request(method, ...) with a fixed HTTP method and accept the same keyword arguments as request — see the request docstring for the full keyword list, the body-encoding rules, and the JSON example.

    response.body is a Vector{UInt8} by default; convert with String(response.body). Note that the conversion aliases the underlying buffer and leaves response.body empty afterwards — see request for the full warning and the safe-copy idioms.

    source
    HTTP.openFunction
    open(method, url, headers=Pair{String,String}[]; kwargs...) -> Stream
    open(f, method, url, headers=Pair{String,String}[]; kwargs...)

    Create a streaming HTTP client request/response exchange.

    The returned Stream buffers request writes locally until startread(stream) or the end of the do block. Once reading starts, stream behaves like a readable IO for the response body. kwargs largely mirror request(...), including redirect, redirect_limit, redirect_method, forwardheaders, cookies, cookiejar, decompress, basicauth, retry, retries, retry_non_idempotent, retry_if, respect_retry_after, retry_bucket, client, connect_timeout, request_timeout, response_header_timeout, read_idle_timeout, write_idle_timeout, expect_continue_timeout, readtimeout, require_ssl_verification, and protocol. basicauth accepts (username, password) credentials; explicit Authorization headers take precedence, and URL userinfo is only used as a fallback when neither is provided. As with request(...), automatic retries only occur for replayable request bodies, retry_bucket=true uses the transport's default RetryBucket, and the built-in policy does not automatically retry request read-timeout/deadline failures. request_timeout applies an overall deadline, read_idle_timeout and write_idle_timeout bound inactivity between response and request I/O progress, response_header_timeout bounds the wait for response headers after the request is sent, and deprecated readtimeout behaves like read_idle_timeout.

    As with request(...), retry_if sees request-path failures as RequestRetryError and can inspect the underlying exception via err.err.

    Return values

    The plain form open(method, url, ...) returns the underlying Stream so the caller can drive request writes and response reads explicitly.

    The do-block form open(f, method, url, ...) runs the user-provided function f(stream) against that same stream, automatically closes the writable and readable sides on exit, and returns the final Response — not the value returned by f. Any data the caller wants to keep from inside f should be captured in an outer variable rather than relied upon as the function's return value:

    using HTTP
    
    response_text = ""
    response = HTTP.open(:GET, "http://example.com") do stream
        response_text = String(read(stream))
    end
    
    @assert response isa HTTP.Response
    @assert response.status == 200

    If the response indicates failure and status_exception is left at its default of true, an HTTP.StatusError is thrown after f runs.

    source
    HTTP.do!Function
    do!(client, address, request; ...) -> Response

    Execute a prepared Request through an existing Client.

    This is the low-level companion to request for callers that already own the address/target split and want to reuse client state directly.

    source
    Base.get!Function
    get!(client, address, target; secure=false, protocol=:auto)

    Convenience GET request using an existing Client.

    Returns the same low-level Response shape as do!.

    source
    HTTP.@clientMacro
    HTTP.@client request_middleware
    HTTP.@client request_middleware stream_middleware

    Define module-local request, verb helpers, and open methods that wrap the public HTTP client APIs with custom client-side middleware.

    Each middleware must be a callable of the form mw(next) -> wrapped, where wrapped matches either:

    • request(method, url, headers, body; kwargs...) for one-shot requests
    • open(method, url, headers; kwargs...) for streaming requests

    Pass either a single middleware or a tuple of middlewares for each position. Tuple middlewares are applied from left to right, so (outer, inner) runs outer(inner(HTTP.request)).

    source
    HTTP.close_idle_connections!Function
    close_idle_connections!(transport)

    Close and discard all currently idle pooled connections. Active in-flight requests are unaffected. Returns nothing.

    source
    HTTP.idle_connection_countFunction
    idle_connection_count(transport; key=nothing)

    Return idle pooled connection count globally or for one host key.

    When key === nothing, returns the transport-wide count. Otherwise key should match the transport's internal pool key such as https://example.com:443.

    source
    HTTP.isabortedFunction
    isaborted(stream) -> Bool

    Return true when the streamed response terminated in an aborted/error state that should not be reused as a keep-alive connection.

    source

    Request Trace Events

    HTTP.RequestEventType
    RequestEvent

    Trace event emitted immediately before a high-level request attempt is sent.

    Fields:

    • request: request head/body metadata for the attempt
    • url: absolute request URL for the attempt
    • attempt: 1-based request attempt number
    • redirect_count: number of redirects already followed before this attempt
    • protocol: :h1 or :h2 for the selected wire protocol
    source
    HTTP.ResponseHeadEventType
    ResponseHeadEvent

    Trace event emitted after response headers are available for a successful request attempt and before the body is fully consumed.

    Fields:

    • response: response head metadata for the attempt
    • url: absolute request URL for the attempt
    • attempt: 1-based request attempt number
    • redirect_count: number of redirects followed before this response
    source
    HTTP.RetryEventType
    RetryEvent

    Trace event emitted when the high-level request path schedules another attempt.

    Fields:

    • request: request metadata that will be retried
    • url: absolute request URL for the attempt being retried
    • attempt: current 1-based attempt number
    • next_attempt: next 1-based attempt number
    • redirect_count: redirects already followed when the retry decision was made
    • delay_ns: delay before the next attempt in nanoseconds
    • response: retry-triggering response, or nothing for request-path failures
    • err: retry-triggering exception, or nothing for response-based retries
    source
    HTTP.RedirectEventType
    RedirectEvent

    Trace event emitted when a redirect response is accepted and a follow-up request is about to be issued.

    Fields:

    • request: original request metadata that produced the redirect response
    • response: redirect response head
    • from_url: original absolute request URL
    • to_url: resolved redirect target URL
    • redirect_count: 1-based redirect count after accepting this redirect
    source
    HTTP.DoneEventType
    DoneEvent

    Trace event emitted when a high-level request call finishes, either with a final response or an exception.

    Fields:

    • response: final response, or nothing if the request failed before one was produced
    • err: terminal exception, or nothing when the request completed successfully
    • url: absolute request URL for the overall call
    source