Repository navigation
feat(https-outcalls): adopt the 0.2 HttpRequest builder, add a flexible outcall example - #1485
Merged
Merged
Conversation
A committee of nodes each make the request and the canister receives their individual responses, instead of one the subnet reached consensus on, so reconciling them is the canister's job. This asks postman-echo.com for the current time, which changes faster than nodes could ever agree on it, and tallies the distinct answers. Notable for readers: the replication counts are derived from subnet_self_node_count, since total_requests must not exceed the subnet size; there is no transform, because nothing has to be made identical across nodes; and each response's status is checked on its own, because no node had to agree with any other. Rust only for now. Flexible outcalls need mops-ic 5.0.0, which is not published yet.
HttpRequest builder
lwshang
approved these changes
Sep 16, 2026
eichhorl
added a commit
to dfinity/developer-docs
that referenced
this pull request
Sep 17, 2026
## Summary Documents the two new HTTPS outcall features: `flexible_http_request` and pay-as-you-go pricing (version `2`). **Interface specification** - New `flexible_http_request` management canister method. A committee of nodes return their individual HTTP responses instead of the subnet reaching consensus on one. Takes an optional `replication` argument (`min_responses`, `max_responses`, `total_requests`), and returns either the responses or a structured error carrying a global error code and per-node resource reports. - New optional `pricing_version` field on `http_request` (`1` or `2`). Version `1` is now deprecated; version `2` prices the resources a call consumes rather than `max_response_bytes`. - New `ic0.cost_http_request_v2` and `ic0.subnet_self_node_count` System APIs. - Non-replicated outcalls are no longer described as experimental. - `public/references/ic.did` and the interface-spec changelog updated to match. **Concepts, guide and reference** - `concepts/https-outcalls.md`: the three outcall modes, and what each pricing version charges for. - `guides/backends/https-outcalls.mdx`: a mode comparison table, a flexible request section with code, and a cycle costs section covering both versions and the `with_expected_*` reservation setters. - `references/cycle-costs.md`: the version `2` formulas, plus a separate "What to attach" section. - `guides/security/https-outcalls.md` and `dos-prevention.md`: flexible mode's weaker integrity guarantee. **Pins** - `ic-cdk-management-canister` added to `upstream.json` as a second `dfinity/cdk-rs` entry, pinned at 0.2.0. `ic-cdk` bumped to 0.20.3. - `.sources/examples` repinned to `1a9a0249`, which carries the Rust outcall examples migrated to the 0.2 builder and the new `send_http_flexible` example (dfinity/examples#1485). ## Structural decisions - **`cycle-costs.md` separates what a call is charged from what to attach.** `ic0.cost_http_request_v2` deliberately quotes more than a call settles at: it floors the response size at `MAX_CANISTER_HTTP_REJECT_BYTES`, scales the fully-replicated consensus fee, and reserves for the most expensive result the call could still produce. Publishing the settle formula as the amount to attach would under-fund calls, so the two are documented separately. The charged formulas are validated against the upstream pricing unit tests. - **`ic-cdk-management-canister` gets its own watched entry** rather than riding on `ic-cdk`'s pin. It versions independently within the same repo, and the `name` field in `upstream.json` exists for this case (the recipes repo uses it for five entries). `scripts/check-upstream-releases.mjs` derives a distinct slug, issue and label from it. - **The Rust and Motoko tabs show different pricing versions.** The Rust `HttpRequest` builder always selects version `2`; Motoko's `Call.httpRequest` still attaches the version `1` cost. That is a packaging lag rather than a language difference, and the prose says so. The flexible request section is Rust only for the same reason. ## Verification - `npm run build` passes: 210 pages, no errors, with every `snippet=` region resolving at the new examples pin. - The pricing figures quoted in the guide were read from a probe canister calling the replica's own `ic0.cost_http_request_v2`, rather than computed from the published formulas. - Flexible outcalls confirmed live: the feature flag flipped to `Enabled` on 2026-09-02, and both replica versions currently running across all 42 mainnet subnets contain that commit. --------- Co-authored-by: Leo Eichhorn <leo.eichhorn@dfinity.org> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Two related changes to the HTTPS outcall examples.
1. Migrate to the 0.2 builder.
ic-cdk-management-canister0.2.0 removed the freehttp_requestin favour of anHttpRequestbuilder, which always uses pricing version 2 (pay-as-you-go). This migratessend_http_get,send_http_postanddaily_planner, bumps their crate pin to0.2, and rewrites the comments that only held under version 1.Each call also declares what it expects:
Unset expectations reserve the worst case: a 60-second round trip, and the full 5-billion-instruction query limit for a transform that only clears headers. Read from the replica's own
cost_http_request_v2on a 13-node subnet, that was 94% of the attached cycles:send_http_getsend_http_postdaily_plannerThe two byte expectations stay at their default. They share one per-node budget with delivery of the result, so a response that exceeds them fails the call after the request has already been made.
2. Add
send_http_flexible. A new example forflexible_http_request, where a committee of nodes each make the request and the canister receives their individual responses instead of one the subnet agreed on. It asks for the current time, which changes faster than nodes could agree on it, and tallies the distinct answers. The replication counts come fromsubnet_self_node_count(), becausetotal_requestsmust not exceed the subnet size. There is no transform, since nothing has to be made identical across nodes.Considerations
Enabledon 2026-09-02 (c14df8a5b42), and both replica versions currently running across all 42 mainnet subnets contain it.send_http_flexibleis Rust only, so it does not meet AGENTS.md's "ship both variants" for new examples: Motoko needs mops-ic 5.0.0, which is unpublished. AGENTS.md also asks for DX team agreement to maintain a new example. Happy to split it into its own PR.0.1.1don't call the removed functions, and^0.1.1still resolves for them.daily_plannerleavesmax_response_bytesunset, so it still reserves for delivering 2MB and stays above its version 1 cost.dfinity/developer-docsquotes three regions from the migrated examples. The markers are unchanged, but its.sources/examplespin needs bumping after merge. The guide's "Flexible request" section has no code yet, so the new snippet gets wired up in that same follow-up.Verification
cargo check --target wasm32-unknown-unknownclean on all four. All four deploy and call the live endpoints inghcr.io/dfinity/icp-dev-env-rust:v2.2.1:send_http_getPASS,send_http_postPASS,daily_planner6/6,send_http_flexible2/2.