# httr2 httr2 (pronounced “hitter2”) is a comprehensive HTTP client that provides a modern, pipeable API for working with web APIs. It builds on top of [{curl}](https://jeroen.r-universe.dev/curl) to provide features like explicit request objects, built-in rate limiting & retry tooling, comprehensive OAuth support, and secure handling of secrets and credentials. ## Installation You can install httr2 from CRAN with: ``` r install.packages("httr2") ``` ## Usage To use httr2, start by creating a **request**: ``` r library(httr2) req <- request("https://r-project.org") req #> #> GET https://r-project.org #> Body: empty ``` You can tailor this request with the `req_` family of functions: ``` r # Add custom headers req |> req_headers("Accept" = "application/json") #> #> GET https://r-project.org #> Headers: #> * Accept: "application/json" #> Body: empty # Add a body, turning it into a POST req |> req_body_json(list(x = 1, y = 2)) #> #> POST https://r-project.org #> Body: JSON data # Modify the path in the url req |> req_url_path(path = "path/to/my/file") #> #> GET https://r-project.org/path/to/my/file #> Body: empty # Automatically retry if the request fails req |> req_retry(max_tries = 5) #> #> GET https://r-project.org #> Body: empty #> Policies: #> * retry_max_tries : 5 #> * retry_on_failure : FALSE #> * retry_failure_threshold: Inf #> * retry_failure_timeout : 30 #> * retry_realm : "r-project.org" # Change the HTTP method req |> req_method("PATCH") #> #> PATCH https://r-project.org #> Body: empty ``` And see exactly what httr2 will send to the server with [`req_dry_run()`](https://httr2.r-lib.org/reference/req_dry_run.md): ``` r req |> req_dry_run() #> GET / HTTP/1.1 #> accept: */* #> accept-encoding: deflate, gzip #> host: r-project.org #> user-agent: httr2/1.2.3.9000 r-curl/7.1.0 libcurl/8.14.1 ``` Use [`req_perform()`](https://httr2.r-lib.org/reference/req_perform.md) to perform the request, retrieving a **response**: ``` r resp <- req_perform(req) resp #> #> GET https://www.r-project.org/ #> Status: 200 OK #> Content-Type: text/html #> Body: In memory (6447 bytes) ``` The `resp_` functions help you extract various useful components of the response: ``` r resp |> resp_content_type() #> [1] "text/html" resp |> resp_status_desc() #> [1] "OK" resp |> resp_body_html() #> {html_document} #> #> [1] \n\n
\n ... ``` ## Major differences to httr - You can now create and modify a request without performing it. This means that there’s now a single function to perform the request and fetch the result: [`req_perform()`](https://httr2.r-lib.org/reference/req_perform.md). [`req_perform()`](https://httr2.r-lib.org/reference/req_perform.md) replaces [`httr::GET()`](https://httr.r-lib.org/reference/GET.html), [`httr::POST()`](https://httr.r-lib.org/reference/POST.html), [`httr::DELETE()`](https://httr.r-lib.org/reference/DELETE.html), and more. - HTTP errors are automatically converted into R errors. Use [`req_error()`](https://httr2.r-lib.org/reference/req_error.md) to override the defaults (which turn all 4xx and 5xx responses into errors) or to add additional details to the error message. - You can automatically retry if the request fails or encounters a transient HTTP error (e.g. a 429 rate limit request). [`req_retry()`](https://httr2.r-lib.org/reference/req_retry.md) defines the maximum number of retries, which errors are transient, and how long to wait between tries. - OAuth support has been totally overhauled to directly support many more flows and to make it much easier to both customise the built-in flows and to create your own. - You can manage secrets (often needed for testing) with [`secret_encrypt()`](https://httr2.r-lib.org/reference/secrets.md) and friends. You can obfuscate mildly confidential data with [`obfuscate()`](https://httr2.r-lib.org/reference/obfuscate.md), preventing it from being scraped from published code. - You can automatically cache all cacheable results with [`req_cache()`](https://httr2.r-lib.org/reference/req_cache.md). Relatively few API responses are cacheable, but when they are it typically makes a big difference. ## Acknowledgements httr2 wouldn’t be possible without [curl](https://jeroen.r-universe.dev//curl/), [openssl](https://jeroen.r-universe.dev/openssl/), [jsonlite](https://jeroen.r-universe.dev/jsonlite), and [jose](https://github.com/r-lib/jose/), which are all maintained by [Jeroen Ooms](https://github.com/jeroen). A big thanks also go to [Jenny Bryan](https://jennybryan.org) and [Craig Citro](https://www.craigcitro.org) who have given me much useful feedback on both the design of the internals and the user facing API. # Package index ## Requests ### Create and modify - [`request()`](https://httr2.r-lib.org/reference/request.md) : Create a new HTTP request - [`req_body_raw()`](https://httr2.r-lib.org/reference/req_body.md) [`req_body_file()`](https://httr2.r-lib.org/reference/req_body.md) [`req_body_json()`](https://httr2.r-lib.org/reference/req_body.md) [`req_body_json_modify()`](https://httr2.r-lib.org/reference/req_body.md) [`req_body_form()`](https://httr2.r-lib.org/reference/req_body.md) [`req_body_multipart()`](https://httr2.r-lib.org/reference/req_body.md) : Send data in request body - [`req_cookie_preserve()`](https://httr2.r-lib.org/reference/req_cookie_preserve.md) [`req_cookies_set()`](https://httr2.r-lib.org/reference/req_cookie_preserve.md) : Set and preserve cookies - [`req_headers()`](https://httr2.r-lib.org/reference/req_headers.md) [`req_headers_redacted()`](https://httr2.r-lib.org/reference/req_headers.md) : Modify request headers - [`req_method()`](https://httr2.r-lib.org/reference/req_method.md) : Set HTTP method in request - [`req_options()`](https://httr2.r-lib.org/reference/req_options.md) : Set arbitrary curl options in request - [`req_progress()`](https://httr2.r-lib.org/reference/req_progress.md) : Add a progress bar to long downloads or uploads - [`req_proxy()`](https://httr2.r-lib.org/reference/req_proxy.md) : Use a proxy for a request - [`req_template()`](https://httr2.r-lib.org/reference/req_template.md) : Set request method/path from a template - [`req_timeout()`](https://httr2.r-lib.org/reference/req_timeout.md) : Set time limit for a request - [`req_url()`](https://httr2.r-lib.org/reference/req_url.md) [`req_url_relative()`](https://httr2.r-lib.org/reference/req_url.md) [`req_url_query()`](https://httr2.r-lib.org/reference/req_url.md) [`req_url_path()`](https://httr2.r-lib.org/reference/req_url.md) [`req_url_path_append()`](https://httr2.r-lib.org/reference/req_url.md) : Modify request URL - [`req_user_agent()`](https://httr2.r-lib.org/reference/req_user_agent.md) : Set user-agent for a request ### Debugging/testing - [`last_response()`](https://httr2.r-lib.org/reference/last_response.md) [`last_request()`](https://httr2.r-lib.org/reference/last_response.md) [`last_request_json()`](https://httr2.r-lib.org/reference/last_response.md) [`last_response_json()`](https://httr2.r-lib.org/reference/last_response.md) : Retrieve most recent request/response - [`req_dry_run()`](https://httr2.r-lib.org/reference/req_dry_run.md) : Perform a dry run - [`req_verbose()`](https://httr2.r-lib.org/reference/req_verbose.md) : Show extra output when request is performed - [`with_verbosity()`](https://httr2.r-lib.org/reference/with_verbosity.md) [`local_verbosity()`](https://httr2.r-lib.org/reference/with_verbosity.md) : Temporarily set verbosity for all requests ### Authentication - [`req_auth_aws_v4()`](https://httr2.r-lib.org/reference/req_auth_aws_v4.md) : Sign a request with the AWS SigV4 signing protocol - [`req_auth_basic()`](https://httr2.r-lib.org/reference/req_auth_basic.md) : Authenticate request with HTTP basic authentication - [`req_auth_bearer_token()`](https://httr2.r-lib.org/reference/req_auth_bearer_token.md) : Authenticate request with bearer token - [`req_oauth_auth_code()`](https://httr2.r-lib.org/reference/req_oauth_auth_code.md) [`oauth_flow_auth_code()`](https://httr2.r-lib.org/reference/req_oauth_auth_code.md) : OAuth with authorization code - [`req_oauth_bearer_jwt()`](https://httr2.r-lib.org/reference/req_oauth_bearer_jwt.md) [`oauth_flow_bearer_jwt()`](https://httr2.r-lib.org/reference/req_oauth_bearer_jwt.md) : OAuth with a bearer JWT (JSON web token) - [`req_oauth_client_credentials()`](https://httr2.r-lib.org/reference/req_oauth_client_credentials.md) [`oauth_flow_client_credentials()`](https://httr2.r-lib.org/reference/req_oauth_client_credentials.md) : OAuth with client credentials - [`req_oauth_device()`](https://httr2.r-lib.org/reference/req_oauth_device.md) [`oauth_flow_device()`](https://httr2.r-lib.org/reference/req_oauth_device.md) : OAuth with device flow - [`req_oauth_password()`](https://httr2.r-lib.org/reference/req_oauth_password.md) [`oauth_flow_password()`](https://httr2.r-lib.org/reference/req_oauth_password.md) : OAuth with username and password - [`req_oauth_refresh()`](https://httr2.r-lib.org/reference/req_oauth_refresh.md) [`oauth_flow_refresh()`](https://httr2.r-lib.org/reference/req_oauth_refresh.md) : OAuth with a refresh token - [`req_oauth_token_exchange()`](https://httr2.r-lib.org/reference/req_oauth_token_exchange.md) [`oauth_flow_token_exchange()`](https://httr2.r-lib.org/reference/req_oauth_token_exchange.md) : OAuth token exchange ## Perform a request - [`req_perform()`](https://httr2.r-lib.org/reference/req_perform.md) : Perform a request to get a response - [`req_perform_stream()`](https://httr2.r-lib.org/reference/req_perform_stream.md) **\[deprecated\]** : Perform a request and handle data as it streams back - [`req_perform_connection()`](https://httr2.r-lib.org/reference/req_perform_connection.md) : Perform a request and return a streaming connection - [`req_perform_promise()`](https://httr2.r-lib.org/reference/req_perform_promise.md) **\[experimental\]** : Perform request asynchronously using the promises package ### Control the process These functions don’t modify the HTTP request that is sent to the server, but affect the overall process of [`req_perform()`](https://httr2.r-lib.org/reference/req_perform.md). - [`req_cache()`](https://httr2.r-lib.org/reference/req_cache.md) : Automatically cache requests - [`req_error()`](https://httr2.r-lib.org/reference/req_error.md) : Control handling of HTTP errors - [`req_throttle()`](https://httr2.r-lib.org/reference/req_throttle.md) : Rate limit a request by automatically adding a delay - [`req_retry()`](https://httr2.r-lib.org/reference/req_retry.md) : Automatically retry a request on failure ## Perform multiple requests - [`req_perform_iterative()`](https://httr2.r-lib.org/reference/req_perform_iterative.md) : Perform requests iteratively, generating new requests from previous responses - [`req_perform_parallel()`](https://httr2.r-lib.org/reference/req_perform_parallel.md) : Perform a list of requests in parallel - [`req_perform_sequential()`](https://httr2.r-lib.org/reference/req_perform_sequential.md) : Perform multiple requests in sequence - [`iterate_with_offset()`](https://httr2.r-lib.org/reference/iterate_with_offset.md) [`iterate_with_cursor()`](https://httr2.r-lib.org/reference/iterate_with_offset.md) [`iterate_with_link_url()`](https://httr2.r-lib.org/reference/iterate_with_offset.md) : Iteration helpers - [`resps_successes()`](https://httr2.r-lib.org/reference/resps_successes.md) [`resps_failures()`](https://httr2.r-lib.org/reference/resps_successes.md) [`resps_ok()`](https://httr2.r-lib.org/reference/resps_successes.md) [`resps_requests()`](https://httr2.r-lib.org/reference/resps_successes.md) [`resps_data()`](https://httr2.r-lib.org/reference/resps_successes.md) : Tools for working with lists of responses ## Handle the response - [`resp_body_raw()`](https://httr2.r-lib.org/reference/resp_body_raw.md) [`resp_has_body()`](https://httr2.r-lib.org/reference/resp_body_raw.md) [`resp_body_string()`](https://httr2.r-lib.org/reference/resp_body_raw.md) [`resp_body_json()`](https://httr2.r-lib.org/reference/resp_body_raw.md) [`resp_body_html()`](https://httr2.r-lib.org/reference/resp_body_raw.md) [`resp_body_xml()`](https://httr2.r-lib.org/reference/resp_body_raw.md) : Extract body from response - [`resp_check_content_type()`](https://httr2.r-lib.org/reference/resp_check_content_type.md) : Check the content type of a response - [`resp_content_type()`](https://httr2.r-lib.org/reference/resp_content_type.md) [`resp_encoding()`](https://httr2.r-lib.org/reference/resp_content_type.md) : Extract response content type and encoding - [`resp_date()`](https://httr2.r-lib.org/reference/resp_date.md) : Extract request date from response - [`resp_headers()`](https://httr2.r-lib.org/reference/resp_headers.md) [`resp_header()`](https://httr2.r-lib.org/reference/resp_headers.md) [`resp_header_exists()`](https://httr2.r-lib.org/reference/resp_headers.md) : Extract headers from a response - [`resp_link_url()`](https://httr2.r-lib.org/reference/resp_link_url.md) : Parse link URL from a response - [`resp_raw()`](https://httr2.r-lib.org/reference/resp_raw.md) : Show the raw response - [`resp_request()`](https://httr2.r-lib.org/reference/resp_request.md) : Find the request responsible for a response - [`resp_retry_after()`](https://httr2.r-lib.org/reference/resp_retry_after.md) : Extract wait time from a response - [`resp_status()`](https://httr2.r-lib.org/reference/resp_status.md) [`resp_status_desc()`](https://httr2.r-lib.org/reference/resp_status.md) [`resp_is_error()`](https://httr2.r-lib.org/reference/resp_status.md) [`resp_check_status()`](https://httr2.r-lib.org/reference/resp_status.md) : Extract HTTP status from response - [`resp_stream_raw()`](https://httr2.r-lib.org/reference/resp_stream_raw.md) [`resp_stream_lines()`](https://httr2.r-lib.org/reference/resp_stream_raw.md) [`resp_stream_sse()`](https://httr2.r-lib.org/reference/resp_stream_raw.md) [`resp_stream_aws()`](https://httr2.r-lib.org/reference/resp_stream_raw.md) [`close(`*``*`)`](https://httr2.r-lib.org/reference/resp_stream_raw.md) [`resp_stream_is_complete()`](https://httr2.r-lib.org/reference/resp_stream_raw.md) : Read a streaming body a chunk at a time - [`resp_timing()`](https://httr2.r-lib.org/reference/resp_timing.md) : Extract timing data - [`resp_url()`](https://httr2.r-lib.org/reference/resp_url.md) [`resp_url_path()`](https://httr2.r-lib.org/reference/resp_url.md) [`resp_url_query()`](https://httr2.r-lib.org/reference/resp_url.md) [`resp_url_queries()`](https://httr2.r-lib.org/reference/resp_url.md) : Get URL/components from the response ## URL manipulation - [`url_build()`](https://httr2.r-lib.org/reference/url_build.md) : Build a string from a URL object - [`url_modify()`](https://httr2.r-lib.org/reference/url_modify.md) [`url_modify_relative()`](https://httr2.r-lib.org/reference/url_modify.md) [`url_modify_query()`](https://httr2.r-lib.org/reference/url_modify.md) : Modify a URL - [`url_parse()`](https://httr2.r-lib.org/reference/url_parse.md) : Parse a URL into its component pieces - [`url_query_parse()`](https://httr2.r-lib.org/reference/url_query_parse.md) [`url_query_build()`](https://httr2.r-lib.org/reference/url_query_parse.md) : Parse query parameters and/or build a string ## Miscellaneous helpers - [`curl_translate()`](https://httr2.r-lib.org/reference/curl_translate.md) [`curl_help()`](https://httr2.r-lib.org/reference/curl_translate.md) : Translate a curl command to a httr2 request - [`httr2_translate()`](https://httr2.r-lib.org/reference/httr2_translate.md) : Translate a httr2 request to a curl command - [`is_online()`](https://httr2.r-lib.org/reference/is_online.md) : Is your computer currently online? ## OAuth These functions implement the low-level components of OAuth. - [`oauth_cache_clear()`](https://httr2.r-lib.org/reference/oauth_cache_clear.md) : Clear OAuth cache - [`oauth_cache_path()`](https://httr2.r-lib.org/reference/oauth_cache_path.md) : httr2 OAuth cache location - [`oauth_cache_prune()`](https://httr2.r-lib.org/reference/oauth_cache_prune.md) : Prune the OAuth token cache - [`oauth_client()`](https://httr2.r-lib.org/reference/oauth_client.md) : Create an OAuth client - [`oauth_client_req_auth()`](https://httr2.r-lib.org/reference/oauth_client_req_auth.md) [`oauth_client_req_auth_header()`](https://httr2.r-lib.org/reference/oauth_client_req_auth.md) [`oauth_client_req_auth_body()`](https://httr2.r-lib.org/reference/oauth_client_req_auth.md) [`oauth_client_req_auth_jwt_sig()`](https://httr2.r-lib.org/reference/oauth_client_req_auth.md) : OAuth client authentication - [`oauth_redirect_uri()`](https://httr2.r-lib.org/reference/oauth_redirect_uri.md) : Default redirect url for OAuth - [`oauth_server_metadata()`](https://httr2.r-lib.org/reference/oauth_server_metadata.md) : Discover OAuth server metadata - [`oauth_token()`](https://httr2.r-lib.org/reference/oauth_token.md) : Create an OAuth token ## Developer tooling These functions are useful when developing packges that use httr2. ### Keeping secrets - [`obfuscate()`](https://httr2.r-lib.org/reference/obfuscate.md) [`obfuscated()`](https://httr2.r-lib.org/reference/obfuscate.md) : Obfuscate mildly secret information - [`secret_make_key()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_encrypt()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_decrypt()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_write_rds()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_read_rds()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_decrypt_file()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_encrypt_file()`](https://httr2.r-lib.org/reference/secrets.md) [`secret_has_key()`](https://httr2.r-lib.org/reference/secrets.md) : Secret management ### Testing - [`response()`](https://httr2.r-lib.org/reference/response.md) [`response_json()`](https://httr2.r-lib.org/reference/response.md) : Create a HTTP response for testing ### Introspection and mocking - [`new_response()`](https://httr2.r-lib.org/reference/new_response.md) : Create a HTTP response - [`req_get_body_type()`](https://httr2.r-lib.org/reference/req_get_body_type.md) [`req_get_body()`](https://httr2.r-lib.org/reference/req_get_body_type.md) : Get request body - [`req_get_headers()`](https://httr2.r-lib.org/reference/req_get_headers.md) : Get request headers - [`req_get_method()`](https://httr2.r-lib.org/reference/req_get_method.md) : Get request method - [`req_get_url()`](https://httr2.r-lib.org/reference/req_get_url.md) : Get request URL - [`StreamingBody`](https://httr2.r-lib.org/reference/StreamingBody.md) : `StreamingBody` class - [`with_mocked_responses()`](https://httr2.r-lib.org/reference/with_mocked_responses.md) [`local_mocked_responses()`](https://httr2.r-lib.org/reference/with_mocked_responses.md) : Temporarily mock requests # Articles ### Using httr2 - [Wrapping APIs](https://httr2.r-lib.org/articles/wrapping-apis.md): - [OAuth](https://httr2.r-lib.org/articles/oauth.md):