How can I build a VoIP system in anvil?

Hello Friends,
I am new to anvil, but in a short time using it, I have seen how powerful it can be. I want to build a platform with many features. One of these features will be a VoIP system for local calling. I wish to know how I can get that done using anvil.
PS: I have never built a VoIP before.

Hi there,

Perhaps something can be done with a service like Twillio. Unless there is a python package you have in mind.

If Twillio or a similar service works, perhaps you could embed that service into an Anvil web app. There is an SMS example, so perhaps VoIP is possible. I’m really not sure.

Other may have a better sense of whether of not this is even possible on the Anvil platform, but as far as I know, there are no built in VoIP features. Very intriguing idea though.

Hi @alcampopiano,
Thanks for your quick reply, I’m looking into Twillio. I think it might be useful for what I have in mind. I will notify you of the progress made.

Yes, you can easily interface with Twilio using either the http api ( or, if you are on a paid plan, you can request Anvil install a library for you. A quick search suggests they have a helper library -

When you use Twilio in this way you are really just calling and responding to their API, and Anvil is perfectly suited to this. You send them messages using the http api linked above, and you create API endpoints to receive their callbacks (

You might also be interested in embedding a VoIP or videoconferencing widget into your app’s web pages, using a Custom HTML component. I swear I have seen an example of this on the forums somewhere, but a cursory search can’t find it…

Thanks a lot your help. I tried using the http api but it get the error.
HttpError: 0
This URL may be restricted by your web browser.

I do not understand the help. Please what can I fix this?

I’d need to see the code that is causing that.

Often it’s to do with missing CORS headers.

def sendButton_click(self, **event_args):
    """This method is called when the button is clicked"""
    number = 'My_number'
    auth = "AC701de517a488c647d9781fbe332XXX:fb3c79e7e21c94943fe17572fbXXX"
    resp = anvil.http.request(url="",
                              headers= { "Authentication": "Basic AC701de517a488c647d9781fbe3xxxxxx:fbxx79e7e21c94943fexxxx" ,
                                         "Content-Type" : "application/x-www-form-urlencoded"
                              mode = "cors",
                              body= "To="+number+"&From=+18068381&Body=" + str(self.text_area_1)

I have PM’d you to redact your details.

Ok, this is failing because CORS headers are not set.

But you are also making the call from the browser (in the form), which is a bad idea when you have to pass credentials.

Move the code to the server to avoid CORS issues but also to hide your credentials from the browser.

OK thank you, Let me try that.

Here’s a video conferencing app built in Anvil. It uses Jitsi.

Everybody using the app is on the same call - Jitsi uses a ‘room name’ to identify what call to join, and this app has it hard coded. You could easily add a TextBox to input the room name so people can join a call of their choice.

How it works

It imports Jitsi in Native Libraries:

<script src=""></script>

And it has a Custom HTML Form that embeds the Jitsi video call widget:

<div anvil-slot="default"></div>
<div id="jitsi"></div>

  function initJitsi(domain, options) {
    options.parentNode = this.find("#jitsi")[0]
    window.japi = new JitsiMeetExternalAPI(domain, options);

  #jitsi iframe {
    width: 100%;
    border: none;

And there’s a ‘join video chat’ button on that Form that runs the JavaScript function:

  def button_1_click(self, **event_args):
    """This method is called when the button is clicked"""
    self.call_js("initJitsi", "", {"roomName": "JitsiMeetAPIExample123", "height": 500})
    self.button_1.visible = False

And that’s literally all the code!


That’s ridiculously awesome.

1 Like

Its a great working and coding.

1 Like