Repository navigation
https-outcalls: add flexible outcalls and pricing version 2 (interface spec 0.68.0) #385
Copy link
Copy link
Closed
Labels
skill-improvementImprovement to an existing skillImprovement to an existing skill
Description
The https-outcalls skill predates interface specification 0.68.0 (2026-09-14), which added flexible outcalls and a second pricing mechanism. Flexible outcalls have been live on mainnet since 2026-09-02 (feature flag enabled; both replica versions across all 42 subnets carry the commit), so an agent following the skill today writes code that will not compile against the current Rust CDK and prices calls with a deprecated mechanism.
What changed upstream
- New management canister method
flexible_http_request: a committee of nodes return their individual HTTP responses instead of the subnet reaching consensus on one. Optionalreplicationargument (min_responses,max_responses,total_requests), and a result variant whoseerrarm carries aglobal_error(timeout,out_of_cycles,responses_too_large,too_many_rejects) plus per-node resource reports. Both arms arrive as a reply, not a reject. - New optional
pricing_versionfield onhttp_request:1("legacy", still the default, now deprecated) or2("pay-as-you-go"). Version2prices the resources a call actually consumes rather thanmax_response_bytes, and the attached cycles double as the per-node budget the call runs within. Flexible outcalls have nopricing_versionand are always priced with version2. - New System APIs
ic0.cost_http_request_v2(takes a record of expected resource usage) andic0.subnet_self_node_count.ic0.cost_http_requestis deprecated along with the version it prices. - Non-replicated mode (
is_replicated = false) is no longer experimental. ic-cdk-management-canister0.2.0 removed the free functionshttp_request,cost_http_requestandhttp_request_with_closure(breaking). Replacements are theHttpRequestandFlexibleHttpRequestbuilders, which always select pricing version2, pluswith_expected_roundtrip_time_ms,with_expected_raw_response_bytes,with_expected_transformed_response_bytesandwith_expected_transform_instructionsto narrow the reservation from the worst case.
What is stale in the skill today
Line numbers are from the currently published SKILL.md.
- The Rust implementation section does not compile against the current CDK.
Cargo.tomlpinsic-cdk = "0.19"(line 175) and the examples callic_cdk::management_canister::http_requestwith struct literals containingis_replicated: None(lines 227, 310). The function is gone inic-cdk-management-canister0.2.0, andic-management-canister-types0.10 added fields that break exhaustive struct literals. - Pitfall 2 and the "Cycle Cost Estimation" section present version 1 as the pricing model (lines 36, 331, 350, 352): the
ic0.cost_http_requestAPI, the49_140_000 + 5_200/request byte + 10_400/max_response_bytes byteformula, and the advice that "the way to lower the cost of an outcall is a tightermax_response_bytes". Under version2,max_response_bytesno longer sets the price; it bounds the response and, through the worst-case usage computed from it, the size of the reservation. - Pitfall 7 ("Omitting
max_response_bytes... charges cycles accordingly", ~20.85B cycles) is version 1 only. - No mode coverage. The skill describes replicated consensus only. Non-replicated mode appears just as
is_replicated = nullin code, and flexible mode is absent entirely, so an agent asked for a price feed will be steered into replicated mode, which is precisely the case where consensus fails. - The Motoko path diverges from Rust now.
Call.httpRequestfrom theicmops package still attaches the version1cost, so Motoko cannot reach version2or flexible mode through the wrapper yet. Settingpricing_version = 2on a request passed toCall.httpRequestwould attach the version1amount, far below what version2reserves, and the call would run within a budget too small to finish. That trap is worth a pitfall entry of its own.
Suggested additions
- A modes section: replicated, non-replicated, flexible, with what the canister receives in each and which risk each one trades away.
- A flexible outcall walkthrough: sizing the committee against
ic0.subnet_self_node_count, handling any count betweenmin_responsesandmax_responses(fewer than the maximum is a normal success), treating the responses as an unordered multiset that does not identify its nodes, the 2 MiB joint limit on the delivered responses (against 2 MB per individual response),PUT/DELETE/PATCHbeing allowed only whenmin_responses,max_responsesandtotal_requestsare all equal, and reconciling disagreement in canister code. - Pricing version 2: what it charges for,
ic0.cost_http_request_v2, thewith_expected_*reservation setters, and the fact that under-attaching beyond the base fee is accepted and shrinks the per-node limits rather than rejecting the call up front. - A new pitfall: the builders price through
ic0.cost_http_request_v2, so a canister built with them needs a replica that provides that System API.
References
- Interface specification changes and developer docs: feat: Flexible canister HTTP outcalls and pay-as-you-go pricing developer-docs#254
ic-cdk-management-canister0.2.0 changelog: https://github.com/dfinity/cdk-rs/blob/master/ic-cdk-management-canister/CHANGELOG.md- Working Rust example, including reconciliation: https://github.com/dfinity/examples/tree/master/rust/send_http_flexible
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
skill-improvementImprovement to an existing skillImprovement to an existing skill
Activity
marc0olo commentedon Sep 23, 2026
Done in #387: builder-based Rust examples on
ic-cdk0.20 /ic-cdk-management-canister0.2, both pricing versions (references/pricing-version-2.md), a modes comparison (replicated, non-replicated, flexible), a flexible outcall walkthrough (references/flexible-outcalls.md), and the Motoko version 1 only constraint with the mismatched-funding pitfall. The replica requirement forcost_http_request_v2is carried by theicp-cli >= 0.2.2compatibility floor.