Client API
Client Types and Operations
HTTP.Transport — Type
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.
HTTP.Client — Type
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 implementationcheck_redirect: optional callback deciding whether a redirect should be followedcookiejar: cookie jar implementation, ornothingto disable cookiesmax_redirects: maximum redirect hops before failingprefer_http2: whether secure requests should try HTTP/2 when availabledefault_headers: headers applied to every request issued through this client; per-callheadersare appended on top, and per-call values for the same name take precedencedefault_query: query parameters appended to every request URL; per-callqueryoverrides any keys it shares with the defaultdefault_basicauth: default basic-auth credentials applied unless the call passesbasicauthor an explicitAuthorizationheaderconnect_timeout,request_timeout,response_header_timeout,read_idle_timeout,write_idle_timeout: defaults applied to every request unless the call passes the matching keyword.0disables.
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.
HTTP.RetryBucket — Type
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.
HTTP.RequestRetryError — Type
RequestRetryError(err)Wrapper passed to retry_if for request-path failures. Inspect err.err to check the underlying transport or protocol exception.
HTTP.roundtrip! — Function
roundtrip!(transport, address, request; secure=false, server_name=nothing) -> ResponseExecute a single request through transport without the higher-level redirect, cookie, or retry orchestration provided by Client.
HTTP.request — Function
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)orusername => password; explicitAuthorizationheaders take precedence, and URLuserinfois only used as a fallback when neither is providedretry: overall toggle for high-level request retries; lower-level reused-connection transport retries still happen independentlyretries: maximum number of retry attempts after the initial request attemptretry_non_idempotent: allow automatic retries for methods likePOST/PATCH;PUTandDELETEare already treated as idempotentretry_if: optional callback(attempt, err, req, resp) -> Bool | nothing; request-path failures are passed asRequestRetryErrorso implementations can inspecterr.err, while response-based retry checks passerr = nothingandresp = response;trueforces a retry when the request body is replayable,falsesuppresses retry, andnothingdefers to built-in retry rulesrespect_retry_after: honor serverRetry-Afteron retryable429/503responsesretry_bucket:trueuses the request transport's defaultRetryBucket,falsedisables bucket coordination, and a customRetryBucketoverrides 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 carryingIdempotency-Key/X-Idempotency-Key status_exception: throwStatusErrorfor non-success responsesredirect: follow redirects throughdo!redirect_limit: maximum number of redirects to follow for this call;0disables redirect following while still returning the redirect responseredirect_method: override the method used for301/302redirects; pass:sameto preserve the original methodforwardheaders: 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 thebodykeyword; supported inputs include strings, byte vectors,IO,Dict/NamedTupleform fields,HTTP.Form, iterable chunks, and existingHTTP.AbstractBodyvalues proxy: explicit proxy override for this call; pass a proxy URL string, aProxyConfig, ornothingto force direct connectionscookies:trueto use the effective cookie jar,falseto disable cookie send/store for this call, or a dictionary of extra cookie name/value pairs to append to jar-derived cookiescookiejar: optional cookie jar override for this call; explicit clients default toclient.cookiejar, while implicit convenience calls default to the sharedHTTP.COOKIEJARquery: optional query string or key/value collection appended to the URLresponse_stream: optional sinkIOor byte buffer written with the final response bodydecompress:nothing/trueauto-decompress gzip and deflate responses,falseleaves wire bytes untouchedsse_callback: callback receiving(event)or(stream, event)for successful SSE responsestrace: optional callback receiving request lifecycle eventsverbose:falsedisables built-in logging;true/1prints high-level request lifecycle lines tostdout;2also prints request and response heads. When combined withtrace, verbose output is emitted before the user trace is called.client: optional explicitClient; otherwise a default or ephemeral client is createdconnect_timeout: connection establishment timeout in seconds, covering DNS, TCP connect, proxy CONNECT, TLS handshake, and HTTP/2 session setup in the high-level client pathsrequest_timeout: overall request deadline in secondsresponse_header_timeout: maximum time to wait for response headers after the request has been sentread_idle_timeout: maximum time between inbound read progress eventswrite_idle_timeout: maximum time between outbound write progress eventsexpect_continue_timeout: how long to wait for a100 Continueresponse before sending the request body anyway; pass0to disable the waitreadtimeout: deprecated alias forread_idle_timeoutrequire_ssl_verification: disable certificate verification only for testingprotocol::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(::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 ownUser-Agentheader.Accept-Encoding: gzip, deflate— disable by passingdecompress=falseor by setting your ownAccept-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.
Base.get — Function
get(headers, key, default) -> StringDict-style get on Headers. Returns the first value for key, or default if the header is absent.
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.
HTTP.head — Function
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.
HTTP.post — Function
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.
HTTP.put — Function
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.
HTTP.patch — Function
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.
HTTP.delete — Function
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.
HTTP.options — Function
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.
HTTP.open — Function
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 == 200If the response indicates failure and status_exception is left at its default of true, an HTTP.StatusError is thrown after f runs.
HTTP.@client — Macro
HTTP.@client request_middleware
HTTP.@client request_middleware stream_middlewareDefine 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 requestsopen(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)).
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.
HTTP.idle_connection_count — Function
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.
HTTP.isaborted — Function
isaborted(stream) -> BoolReturn true when the streamed response terminated in an aborted/error state that should not be reused as a keep-alive connection.
Request Trace Events
HTTP.RequestEvent — Type
RequestEventTrace event emitted immediately before a high-level request attempt is sent.
Fields:
request: request head/body metadata for the attempturl: absolute request URL for the attemptattempt: 1-based request attempt numberredirect_count: number of redirects already followed before this attemptprotocol::h1or:h2for the selected wire protocol
HTTP.ResponseHeadEvent — Type
ResponseHeadEventTrace 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 attempturl: absolute request URL for the attemptattempt: 1-based request attempt numberredirect_count: number of redirects followed before this response
HTTP.RetryEvent — Type
RetryEventTrace event emitted when the high-level request path schedules another attempt.
Fields:
request: request metadata that will be retriedurl: absolute request URL for the attempt being retriedattempt: current 1-based attempt numbernext_attempt: next 1-based attempt numberredirect_count: redirects already followed when the retry decision was madedelay_ns: delay before the next attempt in nanosecondsresponse: retry-triggering response, ornothingfor request-path failureserr: retry-triggering exception, ornothingfor response-based retries
HTTP.RedirectEvent — Type
RedirectEventTrace 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 responseresponse: redirect response headfrom_url: original absolute request URLto_url: resolved redirect target URLredirect_count: 1-based redirect count after accepting this redirect
HTTP.DoneEvent — Type
DoneEventTrace event emitted when a high-level request call finishes, either with a final response or an exception.
Fields:
response: final response, ornothingif the request failed before one was producederr: terminal exception, ornothingwhen the request completed successfullyurl: absolute request URL for the overall call