# Non replicated HTTPS outcalls

**URL:** <https://forum.dfinity.org/t/non-replicated-https-outcalls/26627>\
**Category:** Developers\
**Created:** [January 13, 2024, 10:27pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627 "2024-01-13T22:27:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 13, 2024, 10:27pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/1 "2024-01-13T22:27:51Z")

</div>

Hello everyone 🙂

In case your canister needs to make non-replicated HTTPS requests to external APIs (both IPv4 and IPv6) you can now do so with a single inter-canister call. This reduces the cost of your outcalls by [two orders of magnitude](https://internetcomputer.org/docs/current/developer-docs/gas-cost#details-cost-of-compute-and-storage-transactions-on-the-internet-computer) and eliminates the need of [transformation functions](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-how-it-works#transformation-function) at the cost of some extra trust assumptions.

@ilbert and I just released a **proxy canister** which relays the HTTPS requests via an off-chain client. The client connects to the proxy using [IC WebSockets](https://forum.dfinity.org/t/ic-websocket-stable-release/23872).

A high level overview of the architecture is the following:

 ![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/2X/1/12e245fcbe24b4845c56252b7a99239bd9d1c736.jpeg)  
Your canister can simply call the `http_request` method on the proxy canister [`iustv-tiaaa-aaaao-a3aga-cai`](https://dashboard.internetcomputer.org/canister/iustv-tiaaa-aaaao-a3aga-cai) with your **request** and a **callback** method (optional) which is called back by the proxy once it receives the response.  
Upon receiving an inter-canister call with your **request** , the proxy canister relays it to the off-chain client via the IC WebSocket connection. The client makes a call to the HTTPS endpoint specified by your request.  
Upon receiving the response, it sends it to the proxy which makes an inter-canister call to the **callback** method of your canister.

This service can be used to make a non-replicated HTTPS outcall, thus enabling you to make POST **requests** without having to handle [idempotency](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-how-it-works#post-requests-must-be-idempotent). This also makes it super easy to make fire-and-forget HTTPS outcalls, simply do not specify the **callback**.

The off-chain client is currently controlled by us but we are planning to remove us as a single point of failure by deploying it via [IC Side Services](https://forum.dfinity.org/t/proposal-enable-canisters-to-pay-in-icp-for-external-services/24459), which we will be releasing soon.

The source code is available at: [GitHub - omnia-network/ic-http-proxy: Execute non-replicated HTTPS outcalls on the Internet Computer](https://github.com/omnia-network/ic-http-proxy).  
Getting started examples will also be available soon. For now consider this a work-in-progress and expect breaking changes. We are releasing it now to gather your feedback which will drive our development.

Let us know what you think about this!

---

<div class="post-metadata">

**Author:** ![Sormarler](https://avatars.discourse-cdn.com/v4/letter/s/c57346/32.png) [@Sormarler](https://forum.dfinity.org/u/Sormarler)\
**Post date:** [January 14, 2024, 2:40am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/2 "2024-01-14T02:40:23Z")

</div>

What would be the use case for this?

---

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 14, 2024, 10:44am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/3 "2024-01-14T10:44:24Z")

</div>

We developed this as we needed it ourselves to interact with other networks as described in [IC Side Services](https://forum.dfinity.org/t/proposal-enable-canisters-to-pay-in-icp-for-external-services/24459). We decided to release it as a standalone service to see if other devs find it useful.

A general use case is when you want to make a POST to an API that does not support idempotent requests. The alternative to using this service would be to deploy your own proxy between the IC and the API in order to de-duplicate the responses.

Also, there are use cases (like the “HTTP fire-and-forget”) in which it might make sense to trust an external service in exchange for a much cheaper and simpler way of sending requests.

I want to remark that this is not meant to substitute the IC-native HTTPS outcall feature as the trust assumptions are completely different. However, for the use cases mentioned above it might be a reasonable trade-off to make while the native feature improves.

---

<div class="post-metadata">

**Author:** ![h1teshtr1path1](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/h1teshtr1path1/32/24662_2.png) [@h1teshtr1path1](https://forum.dfinity.org/u/h1teshtr1path1)\
**Post date:** [January 14, 2024, 12:34pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/4 "2024-01-14T12:34:40Z")

</div>

Thanks to you for making this open source. Now we can remove proxy servers which were used in many cases to handle idempotency.

---

<div class="post-metadata">

**Author:** ![ilbert](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ilbert/32/8717_2.png) [@ilbert](https://forum.dfinity.org/u/ilbert)\
**Post date:** [January 14, 2024, 10:39pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/5 "2024-01-14T22:39:50Z")

</div>

You can find the first basic example in the [examples/rust/basic](https://github.com/omnia-network/ic-http-proxy/tree/main/examples/rust/basic) folder.

You can interact with the basic example’s backend cansiter from [its Candid UI](https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=ittvb-6qaaa-aaaao-a3agq-cai). Refer to the [Usage](https://github.com/omnia-network/ic-http-proxy/tree/main/examples/rust/basic#usage) section of the README for how to configure the parameters properly.

---

<div class="post-metadata">

**Author:** ![charlesm](https://avatars.discourse-cdn.com/v4/letter/c/87869e/32.png) [@charlesm](https://forum.dfinity.org/u/charlesm)\
**Post date:** [January 15, 2024, 5:44am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/6 "2024-01-15T05:44:43Z")

</div>

This is a great feature. I was trying to make HTTP outcalls to IPv4 addresses which isn’t supported. Or like you mentioned, when trying to make fire-and-forget calls to APIs that aren’t controlled by yourself. It’s wonderful to have this proxy server that allows for easy setup of HTTP outcalls in situations where data is just being sent out of the IC.

---

<div class="post-metadata">

**Author:** ![tiago89](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/tiago89/32/22332_2.png) [@tiago89](https://forum.dfinity.org/u/tiago89)\
**Post date:** [January 15, 2024, 11:34am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/7 "2024-01-15T11:34:42Z")

</div>

Really good, congrats for publishing this guys ❤ This is very much in need.

I have a few questions (since I didn’t have the opportunity to look deeper into the code).

I am assuming you will be paying the infrastructure and the proxy canister costs for now right? It’s free to use it (meaning, we only pay the first inter-canister call, to the proxy, right?). Thanks for this early invest, it’s totally understandable if later you start charging as it succeeds and cost structures become more clear.

How are we safety wise? Many APIs use OAuth2, and give back the refresh/access tokens.  
Let’s assume I am comfortable with the IC Canister/Node risk, what is the middle-man risk (assuming it’s an HTTPS Post call)?

Meaning, when is HTTPS applied (and body data encrypted), all the way from the proxy to the API Endpoint, or it decrypts on the websocket?

Thanks and keep this great work!! 💪

---

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 15, 2024, 1:08pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/8 "2024-01-15T13:08:12Z")

</div>

> [@tiago89](#):
>
> I am assuming you will be paying the infrastructure and the proxy canister costs for now right? It’s free to use it (meaning, we only pay the first inter-canister call, to the proxy, right?).

Yes for now we are paying for the infra and will do until we can sustain it.

> [@tiago89](#):
>
> Thanks for this early invest, it’s totally understandable if later you start charging as it succeeds and cost structures become more clear.

Offering it as a service is something that we are considering but best would be to enable developers to deploy the needed infrastructure via an orchestrator canister. This would basically give devs the best of both worlds: they control their own infrastructure without having to deploy and maintain it themselves.

> [@tiago89](#):
>
> How are we safety wise? Many APIs use OAuth2, and give back the refresh/access tokens.  
> Let’s assume I am comfortable with the IC Canister/Node risk, what is the middle-man risk (assuming it’s an HTTPS Post call)?

The requests are encrypted during all communications between the different components of the infrastructure (from canister to WS Gateway, to off-chain client, and to Web2 API). However, both the WS Gateway and the off-chain client (which we control) can read the requests. This is definitely not acceptable in the long run but for now it’s not that far from what node providers can do.

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [January 15, 2024, 2:26pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/9 "2024-01-15T14:26:30Z")

</div>

This is very cool and I can see a thousand use cases. I will make the following cautionary note:

WARNING: If you use outcalls(other than fire and forget) you may be abandoning the cryptographic guarantees and deterministic guarantees that most expect from ‘classic’ crypto dapps.

These may not be necessary for your canister, and if not, then carry on, but if they are, then just keep in mind there is a bunch you’ll need to consider and plan for if you want to keep those properties.

I’ve written in more detail here:

> [@The Double-Edged Sword of HTTP Outcalls in Internet Computer Smart Contracts](https://forum.dfinity.org/t/the-double-edged-sword-of-http-outcalls-in-internet-computer-smart-contracts/19196):
>
> TL;DR: HTTP outcalls in smart contracts have potential benefits, like event alerts and trusted data provision, but can lead to fragile, centralized systems. Weighing mitigation strategies against simpler, economic incentivization methods is crucial. The community should develop guidelines and best practices for HTTP outcalls, while exploring alternatives to ensure a robust, decentralized ecosystem on the Internet Computer platform. As we continue to build and improve the Internet Computer ecosy…

and here:

> [@Oracles. I’m suspicious. - re: coming http requests](https://forum.dfinity.org/t/oracles-i-m-suspicious-re-coming-http-requests/14360):
>
> Maybe I’m just a math nerd, but I like determinism. I like my contract inputs to be replayable and to end up with the same thing at the end of every run. Everyone is looking forward to outgoing http requests and all I see are foot guns. I’ll try to explain my position and hopefully, by the end you at least have a better idea of the kind of issues you are going to have if you try to pull data from the internet into your IC canister and what price you will pay to do so. TLDR: Oracles push data …

---

<div class="post-metadata">

**Author:** ![lastmjs](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/lastmjs/32/3406_2.png) [@lastmjs](https://forum.dfinity.org/u/lastmjs)\
**Post date:** [January 15, 2024, 3:26pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/10 "2024-01-15T15:26:43Z")

</div>

We should also push for the protocol itself to offer these kinds of outcalls, for example like composite queries. Imagine if a query or an update could make a query http outcall

---

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 15, 2024, 3:39pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/11 "2024-01-15T15:39:58Z")

</div>

> [@skilesare](#):
>
> WARNING: If you use outcalls(other than fire and forget) you may be abandoning the cryptographic guarantees and deterministic guarantees that most expect from ‘classic’ crypto dapps.
> 
> These may not be necessary for your canister, and if not, then carry on, but if they are, then just keep in mind there is a bunch you’ll need to consider and plan for if you want to keep those properties.

Yes, in particular, by using it you are trusting that we do not read/modify/block your requests/responses.

---

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 16, 2024, 10:20am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/12 "2024-01-16T10:20:41Z")

</div>

Yes, operating at the protocol level is the best way to have trustless HTTP outcalls. However, I find the current state of the native feature not so practical to use, that’s why we released this service.

Not sure whether Dfinity is planning to continue the work on native HTTP outcalls right now but it would be really much needed imo.

---

<div class="post-metadata">

**Author:** ![patnorris](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/patnorris/32/11764_2.png) [@patnorris](https://forum.dfinity.org/u/patnorris)\
**Post date:** [January 18, 2024, 3:35pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/13 "2024-01-18T15:35:19Z")

</div>

Interesting feature! I was looking into setting up a proxy server on the IC a few months back but that didn’t work because HTTP outcalls were too slow and expensive, so this could solve/improve the issues I had. Will the mid-/long-term plan be to integrate your work into the protocol, i.e. the developer could specify that just one node should make the outcall? Maybe even with the option to do this within one query call (for any use cases where no consensus might be needed)?

---

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 18, 2024, 4:19pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/14 "2024-01-18T16:19:55Z")

</div>

> [@patnorris](#):
>
> I was looking into setting up a proxy server on the IC a few months back but that didn’t work because HTTP outcalls were too slow and expensive, so this could solve/improve the issues I had

Which problem did you have exactly?

> [@patnorris](#):
>
> Will the mid-/long-term plan be to integrate your work into the protocol, i.e. the developer could specify that just one node should make the outcall?

This is not something to be integrated into the protocol, more like a workaround of the current limitations of the HTTP outcalls (with a big trade-off).

Improving the native HTTP outcalls would of course be amazing but we don’t have the resources to do it by ourselves now.  
What we instead want to do is to deploy the off-chain client on a separate network which an orchestrator canister controls. Eventually, we are not the ones controlling the orchestrator, the HTTP proxy and off-chain client so that devs don’t have to trust us when using this service.

For a little more context, check [this](https://forum.dfinity.org/t/proposal-enable-canisters-to-pay-in-icp-for-external-services/24459) out. We will publish a more detailed explanation soon!

---

<div class="post-metadata">

**Author:** ![patnorris](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/patnorris/32/11764_2.png) [@patnorris](https://forum.dfinity.org/u/patnorris)\
**Post date:** [January 19, 2024, 1:14pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/15 "2024-01-19T13:14:57Z")

</div>

Proxying every call through a canister that uses HTTP outcalls to the intended endpoint is too slow (and likely also too expensive, but I didn’t measure that exactly) for the client, i.e. UX. So your work could decrease the costs and potentially also the time in the mid-term (depending on future plans).

Alright, thanks, just wondered if maybe you coordinated/planned to coordinate this with someone who’s working on HTTP outcalls on the protocol level and thus could potentially create some synergies there.

---

<div class="post-metadata">

**Author:** ![q2333gh](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/q2333gh/32/36020_2.png) [@q2333gh](https://forum.dfinity.org/u/q2333gh)\
**Post date:** [January 22, 2024, 1:06pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/16 "2024-01-22T13:06:47Z")

</div>

What an excellent project you are building there!

1. I learned from Bing AI that `non-replicated` means making http calls without waiting for many nodes to agree (which takes about 2 seconds to do). So, making http calls on IC is very fast, right?  
Is Bing AI says right ?

2. I’m also curious if this project makes http calls easier. Is it like a web framework in some way (for example, in rust: something like Rocket web framework)?"

---

<div class="post-metadata">

**Author:** ![massimoalbarello](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/massimoalbarello/32/6041_2.png) [@massimoalbarello](https://forum.dfinity.org/u/massimoalbarello)\
**Post date:** [January 22, 2024, 2:24pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/17 "2024-01-22T14:24:10Z")

</div>

> [@q2333gh](#):
>
> I learned from Bing AI that `non-replicated` means making http calls without waiting for many nodes to agree (which takes about 2 seconds to do). So, making http calls on IC is very fast, right?

Not really, you have to make an inter-canister call to the proxy canister so you still have to go through consensus. I’m not sure whether there are any latency benefits. The benefits are mostly cost (inter-canister call is much cheaper than HTTP outcall) and simplicity (not having to deal with idempotency).

> [@q2333gh](#):
>
> I’m also curious if this project makes http calls easier. Is it like a web framework in some way (for example, in rust: something like Rocket web framework)?"

It makes it easier yes, but with a big trade-off.  
It’s not a framework, you simply use inter-canister calls to tell the proxy canister which requests to make and which handler to trigger when it receives the response. The rest is taken care by the proxy + off-chain client. So imagine it as a service more than a framework.

---

<div class="post-metadata">

**Author:** ![q2333gh](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/q2333gh/32/36020_2.png) [@q2333gh](https://forum.dfinity.org/u/q2333gh)\
**Post date:** [January 25, 2024, 7:22am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/18 "2024-01-25T07:22:03Z")

</div>

What proxy canister should i use in rust code ?

```rust
pub fn http_init(proxy_canister_id: Principal) {
  PROXY_CANISTER_ID.with(|id| {
    id.replace(proxy_canister_id);
  });
}

```

---

<div class="post-metadata">

**Author:** ![ilbert](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ilbert/32/8717_2.png) [@ilbert](https://forum.dfinity.org/u/ilbert)\
**Post date:** [January 25, 2024, 8:07am UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/19 "2024-01-25T08:07:22Z")

</div>

The proxy canister that we deployed on mainnet is: [`iustv-tiaaa-aaaao-a3aga-cai`](https://dashboard.internetcomputer.org/canister/iustv-tiaaa-aaaao-a3aga-cai). On this link you can also find its Candid declarations.

---

<div class="post-metadata">

**Author:** ![franrappazzini](https://avatars.discourse-cdn.com/v4/letter/f/e79b87/32.png) [@franrappazzini](https://forum.dfinity.org/u/franrappazzini)\
**Post date:** [August 30, 2024, 2:21pm UTC](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627/20 "2024-08-30T14:21:04Z")

</div>

hey @massimoalbarello!

I want to use the `proxy canister` [`iustv-tiaaa-aaaao-a3aga-cai`](https://dashboard.internetcomputer.org/canister/iustv-tiaaa-aaaao-a3aga-cai) but when I call it from my own canister I get the following error: `(variant {Err=variant {HttpOverWs=variant {NoProxiesConnected}}})`

should I to do anything else? is the project ([ic-http-proxy](https://github.com/omnia-network/ic-http-proxy)) yet working?

thank you!

[Next page](https://forum.dfinity.org/t/non-replicated-https-outcalls/26627.md?page=2)
