Skip to content

httr2 (development version)

  • Fixed OAuth token cache pruning so that it actually matches the encrypted .rds.enc files written to disk; previously the pruning pattern only matched an unencrypted .rds file that was never created, so cached tokens were never automatically deleted regardless of age.
  • httr2 now requires rlang >= 1.3.0, which changes the hash used to name files cached by req_cache() and on-disk OAuth token caches (e.g. from req_oauth_auth_code(cache_disk = TRUE)). Existing cached files won’t match the new hash, so they’ll be silently ignored (triggering a normal cache miss/re-authentication) and cleaned up over time by the usual pruning rules; you can also delete them manually.
  • oauth_cache_path() now defaults to a standard R cache directory (via tools::R_user_dir()). Because this release also changes the hash used for cache filenames, existing OAuth tokens will generally not be reused and you may need to authenticate once after upgrading. New tokens are written to the new location, and obsolete tokens in both the old and new locations are removed by the usual pruning rules. httr2 no longer requires the rappdirs package (#800).
  • req_oauth_*() gains an expiry_margin argument to control how early cached OAuth tokens are treated as expired; the default margin increases from 5 to 30 seconds (@zacdav-db, #860).

httr2 1.2.3

CRAN release: 2026-06-23

  • Mocked and cached responses now include the originating request in resp$request, just like real responses (#841).
  • New httr2_translate() translates an httr2 request into the equivalent curl command (#795).
  • last_response_json() now works with content-types that end with +json, e.g. application/problem+json (@cgiachalis, #782).
  • oauth_*() token refresh now forwards token_params from the original flow, so extra token-endpoint parameters (e.g. a scope required on the token exchange) are sent on refresh as well as on the initial token request (@simonpcouch).
  • oauth_client() gains a metadata argument: pass the result of oauth_server_metadata() and the client carries all of the server’s endpoints, so the OAuth flows pick them up automatically instead of threading them into each call (#846).
  • oauth_flow_auth_code() now correctly uses the same redirect URI for both authorization and token requests when using the default localhost redirect URL (@pedrobtz, #829).
  • New oauth_server_metadata() discovers an OAuth/OpenID Connect issuer’s endpoints from its .well-known metadata document (#845).
  • req_auth_aws_v4() now correctly signs URLs containing encoded slashes (%2F) in path segments, such as ARNs in AWS Bedrock API paths (@thisisnic, #842).
  • req_body_form() now creates a valid empty request body when no parameters are provided (@arcresu, #836).
  • req_body_form() and req_url_query() no longer error with “C stack usage is too close to the limit” when given very long string values (#805).
  • req_cache() no longer errors when a request is first performed with path then later without it (#840).
  • req_error() is now applied to responses retrieved from the cache, so a custom is_error callback is respected on cache hits (#806).
  • req_oauth_bearer_jwt() now uses its claim as the basis for a separate client assertion when the client also authenticates with auth = "jwt_sig", so you no longer need to supply the claim twice. As a result, oauth_client(auth = "jwt_sig") no longer requires a claim in auth_params at creation time (#825).
  • req_oauth_device() gains a pkce argument to enable Proof Key for Code Exchange, matching oauth_flow_device() (#834).
  • req_throttle() can now enforce multiple rate limits at once: supply a vector to capacity (and fill_time_s) to create one token bucket per limit, and each request must satisfy all of them (#555).
  • resp_link_url() and iterate_with_link_url() no longer error on Link headers that contain a trailing comma (#804).
  • resp_stream_aws() now parses byte, short, and integer headers as signed integers, matching the AWS event-stream specification (previously they were incorrectly read as unsigned).
  • resp_stream_lines() no longer treats a bare carriage return (CR) as a line ending; only LF and CRLF terminate lines, which is what every modern streaming source produces.
  • resp_stream_lines() no longer warns when the stream ends without a final line terminator (which is routine when streaming), and its warn argument is (softly) deprecated.
  • resp_stream_lines(), resp_stream_sse(), and resp_stream_aws() now decode whole chunks at a time and hold the results in a queue, instead of rescanning and recopying the buffer for every line or event. This makes memory use and run time scale linearly rather than quadratically with the response size, so large streams use dramatically less memory and run much faster (e.g. reading a 1 MB response of short lines is now around 200x faster and allocates around 180x less memory) (#704).

httr2 1.2.2

CRAN release: 2025-12-08

  • httr2 will now emit OpenTelemetry traces for all requests when tracing is enabled. Requires the otelsdk package (@atheriel, #729).
  • req_throttle() no longer resets the token bucket when used repeatedly with the same host (#801) and never generates negative wait times (#820).
  • req_perform_connection() no longer errors with no applicable method for 'close' applied to an object of class "c('httr2_failure', 'httr2_error', 'rlang_error', 'error', 'condition')" (#817).
  • New resps_ok() returns a logical vector indicating which requests were successful (#807).
  • url_modify() refactored to better retain exact formatting of URL not modified components (#788, #794)

httr2 1.2.1

CRAN release: 2025-07-22

  • Colons in paths are no longer escaped.

httr2 1.2.0

CRAN release: 2025-07-13

Lifecycle changes

  • req_perform_stream() has been soft deprecated in favour of req_perform_connection().

  • Deprecated functions mutli_req_perform(), req_stream(), with_mock() and local_mock() have been removed.

  • Deprecated arguments req_perform_parallel(pool), req_oauth_auth_code(host_name, host_ip, port), and oauth_flow_auth_code(host_name, host_ip, port) have been removed.

New features

Minor improvements and bug fixes

httr2 1.1.2

CRAN release: 2025-03-26

httr2 1.1.1

CRAN release: 2025-03-08

New features

  • req_perform_parallel() lifts many of the previous restrictions. It supports simplified versions of req_throttle() and req_retry(), can refresh OAuth tokens, and checks the cache before/after each request. (#681).
  • Default verbosity can be controlled by the HTTR2_VERBOSITY environment variable (#687).
  • local_verbosity() matches the existing with_verbosity() and allows for local control of verbosity (#687).
  • req_dry_run() and req_verbose() display compressed correctly (#91, #656) and automatically prettify JSON bodies (#668). You can suppress prettification with options(httr2_pretty_json = FALSE) (#668).
  • req_throttle() implements a new “token bucket” algorithm that maintains average rate limits while allowing bursts of higher request rates.

Minor improvements and bug fixes

  • aws_v4_signature() correctly processes URLs containing query parameters (@jeffreyzuber, #645).
  • oauth_client() and oauth_token() implement improved print methods with bulleted lists, similar to other httr2 objects, and oauth_client() with custom auth functions no longer produces errors (#648).
  • req_dry_run() omits headers that would vary in tests and can prettify JSON output.
  • req_headers() automatically redacts Authorization headers (#649) and correctly implements case-insensitive modification of existing headers (#682).
  • req_headers_redacted() now supports dynamic dots (#647).
  • req_oauth_auth_code() no longer adds trailing “/” characters to properly formed redirect_uri values (@jonthegeek, #646).
  • req_perform_connection() produces more helpful error messages when requests fail at the networking level.
  • req_perform_parallel(pool) now is deprecated in favour of a new max_active argument (#681).
  • req_user_agent() memoizes the default user agent to improve performance, as computing version numbers is relatively slow (300 µs).
  • resp_link_url() once again respects the case insensitivity for header names (@DavidRLovell, #655).
  • resp_stream_sse() automatically retrieves the next event when the current event contains no data, and returns data as a single string (#650).
  • str() correctly redacts redacted headers (#682).

httr2 1.1.0

CRAN release: 2025-01-18

Lifecycle changes

New features

Bug fixes and minor improvements

httr2 1.0.7

CRAN release: 2024-11-26

httr2 1.0.6

CRAN release: 2024-11-04

httr2 1.0.5

CRAN release: 2024-09-26

httr2 1.0.4

CRAN release: 2024-09-13

httr2 1.0.3

CRAN release: 2024-08-22

httr2 1.0.2

CRAN release: 2024-07-16

httr2 1.0.1

CRAN release: 2024-04-01

httr2 1.0.0

CRAN release: 2023-11-14

Function lifecycle

Multiple requests

OAuth features

  • A new OAuth vignette gives many more details about how OAuth works and how to use it with httr2 (#234), and the OAuth docs have been overhauled to make it more clear that you should use req_oauth_*(), not oauth_*() (#330).

  • If you are using an OAuth token with a refresh token, and that refresh token has expired, then httr2 will now re-run the entire flow to get you a new token (#349).

  • New oauth_cache_path() returns the path that httr2 uses for caching OAuth tokens. Additionally, you can now change the cache location by setting the HTTR2_OAUTH_CACHE env var. This is now more obvious to the user, because httr2 now informs the user whenever a token is cached.

  • oauth_flow_auth_code() gains a redirect_uri argument rather than deriving this URL automatically from the host_name and port (#248). It uses this argument to automatically choose which strategy to use to get the auth code, either launching a temporary web server or, new, allowing you to manually enter the details with the help of a custom JS/HTML page hosted elsewhere, or by copying and pasting the URL you’re redirected to (@fh-mthomson, #326). The temporary web server now also respects the path component of redirect_uri, if the API needs a specific path (#149).

  • New oauth_token_cached() allows you to get an OAuth token while still taking advantage of httr2’s caching and auto-renewal features. For expert use only (#328).

Other new features

Minor improvements and bug fixes

  • The httr2 examples now only run on R 4.2 and later so that we can use the base pipe and lambda syntax (#345).

  • OAuth errors containing a url now correctly display that URL (instead of the string “uri”).

  • curl_translate() now uses the base pipe, and produces escapes with single quotes or raw strings in case double quotes can’t be used (@mgirlich, #264). It gains the argument simplify_headers that removes some common but unimportant headers, like Sec-Fetch-Dest or sec-ch-ua-mobile (@mgirlich, #256). It also parses the query components of the url (@mgirlich, #259) and works with multiline commands from the clipboard (@mgirlich, #254).

  • local_mocked_responses() and with_mocked_responses() now accept a list of responses which will be returned in sequence. They also now correctly trigger errors when the mocked response represents an HTTP failure (#252).

  • oauth_flow_refresh() now only warns, not errors, if the refresh_token changes, making it a little easier to use in manual workflows (#186).

  • obfuscated() values now display their original call when printed.

  • req_body_json() gains custom content type argument and respects custom content-type set in header (@mgirlich, #189).

  • req_cache() now combine the headers of the new response with the headers of the cached response. In particular, this fixes resp_body_json/xml/html() on cached responses (@mgirlich, #277).

  • req_perform() now throws error with class httr2_failure/httr2_error if the request fails, and that error now captures the curl error as the parent. If the request succeeds, but the response is an HTTP error, that error now also has super class httr2_error. This means that all errors thrown by httr2 now inherit from the httr2_error class. See new docs in ?req_error() for more details.

  • req_perform()’s progress bar can be suppressed by setting options(httr2_progress = FALSE) (#251). Progress bars displayed while waiting for some time to pass now tell you why they’re waiting (#206).

  • req_oauth_bearer_jwt() now includes the claim in the cache key (#192).

  • req_oauth_device() now takes a auth_url parameter making it usable (#331, @taerwin).

  • req_url_query() gains a .multi parameter that controls what happens when you supply multiple values in a vector. The default will continue to error but you can use .multi = "comma" to separate with commas, "pipe" to separate with |, and "explode" to generate one parameter for each value (e.g. ?a=1&a=2) (#350).

httr2 0.2.3

CRAN release: 2023-05-08

httr2 0.2.2

CRAN release: 2022-09-25

httr2 0.2.1

CRAN release: 2022-05-10

  • “Wrapping APIs” is now an article, not a vignette.

  • req_template() now appends the path instead of replacing it (@jchrom, #133)

httr2 0.2.0

CRAN release: 2022-04-28

New features

Minor improvements and bug fixes

httr2 0.1.1

CRAN release: 2021-09-28

  • Fix R CMD check failures on CRAN

  • Added a NEWS.md file to track changes to the package.