| [Specify another language for specific words](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#lang-tag) | Use this tag to set the natural language of the text. |
| \ | [Add a pause between paragraphs](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#p-tag) | Use this tag to represent a paragraph. |
| \ | [Use phonetic pronunciation](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#phoneme-tag) | Use this tag to set phonetic pronunciation for specific text. |
| \ | [Control volume, speaking rate, and pitch](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#prosody-tag) | Use this tag to modify the volume, speaking rate, and pitch of the tagged text. |
| \ | [Add a pause between sentences](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#s-tag) | Use this tag to represent a sentence. This adds a strong break before and after the tag. |
| \ | [Control how special types of words are spoken](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#say-as-tag) | Use this tag to describe how to interpret the text. |
| \ | [Pronounce acronyms and abbreviations](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#sub-tag) | Use this tag to pronounce the specified words or phrases as different words or phrases. |
| \ | [Improve pronunciation by specifying parts of speech](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html#w-tag) | Use this tag to customize the pronunciation of words by specifying the part of speech they are. |
**Note**: Plivo doesn’t support these Amazon Polly-specific tags in Plivo XML:
* \
* \
* \
* \
* \
## SSML voices
Plivo supports these Amazon Polly voices for use with Plivo XML:
| Language | Female | Male |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Australian English (en-AU) | [Polly.Nicole](https://d1.awsstatic.com/product-marketing/Polly/voices/nicole.8656c0be485fb3c43c29a7cc799960211fa224e5.mp3) | [Polly.Russell](https://d1.awsstatic.com/product-marketing/Polly/voices/russell.85286a07b33c9ee2bd97dd994294ccebb50a784d.mp3) |
| Brazilian Portuguese (pt-BR) | [Polly.Vitória](https://d1.awsstatic.com/product-marketing/Polly/voices/vitoria.dccdde767360bb45f5ef615d4ae93245e43a4320.mp3) | [Polly.Ricardo](https://d1.awsstatic.com/product-marketing/Polly/voices/ricardo.485ed1dff89ee3606e46ef0f84b14d73fcd42a6b.mp3) |
| Canadian French (fr-CA) | [Polly.Chantal](https://d1.awsstatic.com/product-marketing/Polly/voices/chantal.322a64f32393d0c6a5a291465f451cbcd681c295.mp3) | - |
| Danish (da-DK) | [Polly.Naja](https://d1.awsstatic.com/product-marketing/Polly/voices/naja.b704af10c1e90008689ef17863d949c7b3d229a5.mp3) | [Polly.Mads](https://d1.awsstatic.com/product-marketing/Polly/voices/mads.84fb272b1941303d0b744f267d5a7bbe940b34f4.mp3) |
| Dutch (nl-NL) | [Polly.Lotte](https://d1.awsstatic.com/product-marketing/Polly/voices/lotte.b60b7c845c0135c05852c837813038abe87a824a.mp3) | [Polly.Ruben](https://d1.awsstatic.com/product-marketing/Polly/voices/ruben.e8d339872f9d4aac2cf9c6844ab793f81550a015.mp3) |
| French (fr-FR) | [Polly.Lea](https://d1.awsstatic.com/product-marketing/Polly/voices/lea.23bfaf13f5727801c654d1e2f028496f39ba6f0d.mp3) | [Polly.Celine](https://d1.awsstatic.com/product-marketing/Polly/voices/celine.e6c15212622f6f5225f234d980a65e9a41201196.mp3) |
| | [Polly.Mathieu](https://d1.awsstatic.com/product-marketing/Polly/voices/mathieu.feedabefbaa9a94fe1bdeae8e503b49819f910c5.mp3) | - |
| German (de-DE) | [Polly.Vicki](https://d1.awsstatic.com/product-marketing/Polly/voices/vicki.cafbf81c1cb7f9c5c060b02ffda104a7f6ee6cb9.mp3) | [Polly.Hans](https://d1.awsstatic.com/product-marketing/Polly/voices/hans.c8171993a58a550ba31d7c7c9caadb4042d01609.mp3) |
| | [Polly.Marlene](https://d1.awsstatic.com/product-marketing/Polly/voices/marlene.39191e409bfc0031ea32c63aa8f6027e2110da96.mp3) | - |
| Hindi (hi-IN) | [Polly.Aditi](https://d1.awsstatic.com/product-marketing/Polly/voices/aditi_hindi.87e7512d4a1eb60235e8fc4edd08ab2071a8718c.mp3) | - |
| Icelandic (is-IS) | [Polly.Dora](https://d1.awsstatic.com/product-marketing/Polly/voices/dora.7579e97fbfe4a3d4ff00df48dd9c588b377f3308.mp3) | [Polly.Karl](https://d1.awsstatic.com/product-marketing/Polly/voices/karl.5ea12538bbd81ede68314aca4b6dbf7e73405be3.mp3) |
| Indian English (en-IN) | [Polly.Raveena](https://d1.awsstatic.com/product-marketing/Polly/voices/raveena.1819674fbbf0720fdf94018f1df918ade38ebf5a.mp3) | - |
| | [Polly.Aditi](https://d1.awsstatic.com/product-marketing/Polly/voices/aditi.09b7fbaf5620f9b49b6b759f6b2df58fdcbc5d3e.mp3) | - |
| Italian (it-IT) | [Polly.Carla](https://d1.awsstatic.com/product-marketing/Polly/voices/carla.a990b3137f13cb66ef3b9d80e1eba87e30855386.mp3) | [Polly.Giorgio](https://d1.awsstatic.com/product-marketing/Polly/voices/giorgio.74927aa24bee5d8eea0b09619e29379ed8053010.mp3) |
| Japanese (ja-JP) | [Polly.Mizuki](https://d1.awsstatic.com/product-marketing/Polly/voices/mizuki.ae1d119948ee76011e51299748db48c25943e82e.mp3) | [Polly.Takumi](https://d1.awsstatic.com/product-marketing/Polly/voices/takumi.b3728282feaaea563b23345fb9fb434d9b727c7c.mp3) |
| Korean (ko-KR) | [Polly.Seoyeon](https://d1.awsstatic.com/product-marketing/Polly/HelloKorean_Seoyeon.b0ae8ddfc55e602e3f0657afe112b8902282880a.wav) | - |
| Mandarin Chinese (cmn-CN) | [Polly.Zhiyu](https://d1.awsstatic.com/product-marketing/Polly/voices/Zhiyu-hi.9785e6f8b598d3e6bdcb5c2a9ec95859bfd1292d.mp3) | - |
| Norwegian (nb-NO) | [Polly.Liv](https://d1.awsstatic.com/product-marketing/Polly/voices/liv.b5a39b3792911ed1d8d35c6c6f327850aae05972.mp3) | - |
| Polish (pl-PL) | [Polly.Ewa](https://d1.awsstatic.com/product-marketing/Polly/voices/ewa.497d83b9f6c486ce14d0b78b9514591a18d4f1b8.mp3) | [Polly.Jacek](https://d1.awsstatic.com/product-marketing/Polly/voices/jacek.8851713e855fb82baaf76e1eb4e97fed97f65a36.mp3) |
| | [Polly.Maja](https://d1.awsstatic.com/product-marketing/Polly/voices/maja.c24bddf411c7c750c6aa621fc8fc4c009c0866f3.mp3) | [Polly.Jan](https://d1.awsstatic.com/product-marketing/Polly/voices/jan.9bb856fb6dfe128cc7033943d7009c19f0dddd73.mp3) |
| Portuguese - Iberic (pt-PT) | [Polly.Ines](https://d1.awsstatic.com/product-marketing/Polly/voices/ines.136466e69d98c766946a311d151b13a0b6e86dfa.mp3) | [Polly.Cristiano](https://d1.awsstatic.com/product-marketing/Polly/voices/cristiano.aec3b12945b55ae6990c6b78f534031fb3ee9b6a.mp3) |
| Romanian (ro-RO) | [Polly.Carmen](https://d1.awsstatic.com/product-marketing/Polly/voices/carmen.b732da15cb57ac7c873dd3d016193437cb8ea93c.mp3) | - |
| Russian (ru-RU) | [Polly.Tatyana](https://d1.awsstatic.com/product-marketing/Polly/voices/tatyana.1f33b6e72ad56ce6a22c577c5090fdc7ca6c8dd0.mp3) | [Polly.Maxim](https://d1.awsstatic.com/product-marketing/Polly/voices/maxim.30cd883f122322e8afd315a49b72efcca91130d2.mp3) |
| Spanish - Castilian (es-ES) | [Polly.Conchita](https://d1.awsstatic.com/product-marketing/Polly/voices/conchita.103a380cdb2471d794dbdc4808e18f4bcf52e299.mp3) | [Polly.Enrique](https://d1.awsstatic.com/product-marketing/Polly/voices/enrique.22473b31f265f8b050f91df18a8b36a89d19b70e.mp3) |
| Spanish - Mexican (es-MX) | [Polly.Mia](https://d1.awsstatic.com/product-marketing/Polly/voices/Mia.575350d0eeeafa39c121f756c4bfac6437c4e650.mp3) | - |
| US - Spanish (es-US) | [Polly.Penelope](https://d1.awsstatic.com/product-marketing/Polly/voices/penelope.7723493fdb9c6b7e1400efe02a5c1e7848310ba4.mp3) | [Polly.Miguel](https://d1.awsstatic.com/product-marketing/Polly/voices/miguel.91030339cc81f8df461e3ab7325168fa5fdc0035.mp3) |
| | [Polly.Lupe-Standard](https://d1.awsstatic.com/product-marketing/Polly/voices/Lupe%20\(Standard\).85d69fc3a36ee08455b352221435154afd19420c.mp3) | - |
| Swedish (sv-SE) | [Polly.Astrid](https://d1.awsstatic.com/product-marketing/Polly/voices/astrid.4c9e160e86557f9610fa718f1d871a0caf61e586.mp3) | - |
| Turkish (tr-TR) | [Polly.Filiz](https://d1.awsstatic.com/product-marketing/Polly/voices/filiz.15c85361bbac56743b00ebf345c2a7d54a3e99f8.mp3) | - |
| UK English (en-GB) | [Polly.Amy](https://d1.awsstatic.com/product-marketing/Polly/voices/amy.19b8f5cf54bce4bc1010b4234ec6e9ea1496e97f.mp3) | [Polly.Brian](https://d1.awsstatic.com/product-marketing/Polly/voices/brian.f5abc46f50f1042bac587d990dd05912daf09089.mp3) |
| | [Polly.Emma](https://d1.awsstatic.com/product-marketing/Polly/voices/emma.21bd3065d00d15f8f7df800436c0e52970953d36.mp3) | - |
| US English (en-US) | [Polly.Joanna](https://d1.awsstatic.com/product-marketing/Polly/voices/joanna.84722a684fbb16e766944ea6e34dd0042195571c.mp3) | [Polly.Matthew](https://d1.awsstatic.com/product-marketing/Polly/voices/matthew.b2a8b7d5b329742fc718c7a8d0efdad1c11fb25f.mp3) |
| | [Polly.Salli](https://d1.awsstatic.com/product-marketing/Polly/voices/salli.20a721cb6b8a5fbb016ab6d9ded37f9a91fe7a58.mp3) | [Polly.Justin](https://d1.awsstatic.com/product-marketing/Polly/voices/justin.acfadcd365d37a1ecc88fdb2a640f1a75f83bdf7.mp3) |
| | [Polly.Kendra](https://d1.awsstatic.com/product-marketing/Polly/voices/kendra.d768f43e12c08892d4495511e84e82f1b7195673.mp3) | [Polly.Joey](https://d1.awsstatic.com/product-marketing/Polly/voices/joey.3abd7f17e6dae6c9248cacd7eb0ec910c691c4f4.mp3) |
| | [Polly.Kimberly](https://d1.awsstatic.com/product-marketing/Polly/voices/kimberly.42e50dd5056c92a5fff41952d0c057a7f09adca3.mp3) | - |
| | [Polly.Ivy](https://d1.awsstatic.com/product-marketing/Polly/voices/ivy.70016451b3c186bcacba09acf5ee1b68c12db745.mp3) | - |
| Welsh (cy-GB) | [Polly.Gwyneth](https://d1.awsstatic.com/product-marketing/Polly/voices/gwyneth.be497813ff11614acbdac0fb6c334b94bce20b45.mp3) | - |
| Welsh English (en-GB-WLS) | - | [Polly.Geraint](https://d1.awsstatic.com/product-marketing/Polly/voices/geraint.4aa21b628bd99741c0275c77d8daa0ff7290265e.mp3) |
## Character limit
To ensure quick synthesis, Plivo caps the length of text that can be synthesized in one \ tag at 3,000 characters.
## Pricing
Support for SSML-based speech synthesis is currently in beta and free for all Plivo users. We expect to eventually charge for text-to-speech on the basis of the number of characters synthesized.
## SSML support in Plivo Server SDKs
SSML tags are supported in all of our [Server SDKs](/docs/sdk/server/).
## Example
This example use the [Joey](https://d1.awsstatic.com/product-marketing/Polly/voices/joey.3abd7f17e6dae6c9248cacd7eb0ec910c691c4f4.mp3) voice for US English (en-US). Use the \ tag to specify the voice for your text.
### say-as
The say-as tag describes how to interpret the text.
```py Python theme={null}
from flask import Flask, Response, request, url_for
from plivo import plivoxml
app = Flask(__name__)
@app.route("/ssml/", methods=["GET", "POST"])
def ssml():
element = plivoxml.ResponseElement()
response = (
element.add(
plivoxml.SpeakElement(content="The date is", voice="Polly.Joey", language="en-US")
.add_say_as("20200626", interpret_as="date")
)
.to_string(False)
)
print(response)
return Response(response, mimetype="text/xml")
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
```rb Ruby theme={null}
class PlivoController < ApplicationController
def ssml
response = Plivo::XML::Response.new
speak_elem = response.addSpeak('The date is', voice: 'Polly.Joey', language: 'en-US')
speak_elem.addSayAs('20200626', 'interpret-as' => 'date')
xml = Plivo::XML::PlivoXML.new(response)
puts xml.to_xml()
render xml: xml.to_xml
end
end
```
```js Node.js theme={null}
var plivo = require('plivo');
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.all('/ssml/', function (request, response) {
if (request.method == "GET") {
var r = new plivo.Response();
const speakElem = r.addSpeak('The date is', {
'voice': 'Polly.Joey',
'language': 'en-US'
});
speakElem.addSayAs('20200626', {
'interpret-as': 'date',
});
console.log(r.toXML());
response.set({
'Content-Type': 'text/xml'
});
response.end(r.toXML());
}
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
```php PHP theme={null}
addSpeak('The date is', ['language'=>"en-US", 'voice'=>"Polly.Joey"]);
$speak_elem->addSayAs('20200626', ['interpret-as'=>"date"]);
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
}
```
```java Java theme={null}
package com.example.SsmlHandler;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class SsmlApplication {
public static void main(String[] args) {
SpringApplication.run(SsmlHandlerApplication.class, args);
}
@RequestMapping(value = "/ssml/", produces = { "application/xml" }, method = { RequestMethod.GET, RequestMethod.POST })
public Response SsmlHandler() throws PlivoXmlException {
Response response = new Response().children(new Speak("The date is").
children(new SayAs("20200626", "date")));
System.out.println(response.toXmlString());
return response;
}
}
```
```go Go theme={null}
package main
import (
"net/http"
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
m := martini.Classic()
m.Any("/ssml/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak("The date is", "Polly.Joey", "en-US", 1).
AddSayAs("20200626", "date", ""),
},
}
return response.String()
})
m.Run()
}
```
```cs .NET theme={null}
using System.Collections.Generic;
using Plivo.XML;
using Microsoft.AspNetCore.Mvc;
namespace Voicemail.Controllers
{
public class SsmlController : Controller
{
// GET: //
public IActionResult Index()
{
var resp = new Response();
Speak speak_elem = new Speak("The date is", new Dictionary() {
{"voice","Polly.Joey"},
{"language","en-US"},
});
resp.Add(speak_elem);
speak_elem.AddSayAs("20200626", new Dictionary() {
{ "interpret-as", "date" }
});
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
The rendered XML document would be:
```xml theme={null}
The date is
20200626
```
### w
The w tag lets you customize the pronunciation of a word by specifying its part of speech.
```py Python theme={null}
from flask import Flask, Response, request, url_for
from plivo import plivoxml
app = Flask(__name__)
@app.route("/ssml/", methods=["GET", "POST"])
def ssml():
element = plivoxml.ResponseElement()
response = (
element.add(
plivoxml.SpeakElement(content="The word", voice="Polly.Joey", language="en-US")
.add_say_as("read", interpret_as="characters")
.add_s("may be interpreted as either the present simple form")
.add_w("read", role="amazon:VB")
.add_s("or the past participle form")
.add_w("read", role="amazon:VBD")
)
.to_string(False)
)
print(response)
return Response(response, mimetype="text/xml")
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
```rb Ruby theme={null}
class PlivoController < ApplicationController
def ssml
response = Plivo::XML::Response.new
speak_elem = response.addSpeak('The word', voice: 'Polly.Joey', language: 'en-US')
speak_elem.addSayAs('read', 'interpret-as' => 'characters')
speak_elem.addS('may be interpreted as either the present simple form')
speak_elem.addW('read', 'role' => 'amazon:VB')
speak_elem.addS('or the past participle form')
speak_elem.addW('read', 'role' => 'amazon:VBD')
xml = Plivo::XML::PlivoXML.new(response)
puts xml.to_xml()
render xml: xml.to_xml
end
end
```
```js Node.js theme={null}
var plivo = require('plivo');
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.all('/ssml/', function(request, response) {
if (request.method == "GET") {
var r = new plivo.Response();
const speakElem = r.addSpeak('The word', {
'voice': 'Polly.Joey',
'language': 'en-US'
});
speakElem.addSayAs('read', {
'interpret-as': 'characters'
});
speakElem.addS('may be interpreted as either the present simple form');
speakElem.addW('read', {
'role': 'amazon:VB'
});
speakElem.addS('or the past participle form');
speakElem.addW('read', {
'role': 'amazon:VBD'
});
console.log(r.toXML());
response.set({
'Content-Type': 'text/xml'
});
response.end(r.toXML());
}
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
```php PHP theme={null}
addSpeak('The word', ['language'=>"en-US", 'voice'=>"Polly.Joey"]);
$speak_elem->addSayAs('read', ['interpret-as'=>"characters"]);
$speak_elem->addS('may be interpreted as either the present simple form');
$speak_elem->addW('read', ['role'=>"amazon:VB"]);
$speak_elem->addS('or the past participle form');
$speak_elem->addW('read', ['role'=>"amazon:VBD"]);
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
}
```
```java Java theme={null}
package com.example.SsmlHandler;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class SsmlApplication {
public static void main(String[] args) {
SpringApplication.run(SsmlHandlerApplication.class, args);
}
@RequestMapping(value = "/ssml/", produces = { "application/xml" }, method = { RequestMethod.GET, RequestMethod.POST })
public Response Ssml() throws PlivoXmlException {
Response response = new Response().children(new Speak("The word","Polly.Joey","en-US",1)
.children(new SayAs("read", "characters"))
.addS("may be interpreted as either the present simple form")
.addW("read", "amazon:VB")
.addS("or the past participle form")
.addW("read", "amazon:VBD"));
System.out.println(response.toXmlString());
return response;
}
}
```
```go Go theme={null}
package main
import (
"net/http"
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
m := martini.Classic()
m.Any("/ssml/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak("The word", "Polly.Joey", "en-US", 1).
AddSayAs("read", "characters", "").
AddS("may be interpreted as either the present simple form").
AddW("read", "amazon:VB").
AddS("or the past participle form").
AddW("read", "amazon:VBD"),
},
}
return response.String()
})
m.Run()
}
```
```cs .NET theme={null}
using System.Collections.Generic;
using Plivo.XML;
using Microsoft.AspNetCore.Mvc;
namespace Voicemail.Controllers
{
public class SsmlController : Controller
{
// GET: //
public IActionResult Index()
{
var resp = new Response();
Speak speak_elem = new Speak("The word", new Dictionary() {
{"voice","Polly.Joey"},
{"language","en-US"},
});
resp.Add(speak_elem);
speak_elem.AddSayAs("read", new Dictionary() {
{ "interpret-as", "characters" }
});
speak_elem.AddS("may be interpreted as either the present simple form");
speak_elem.AddW("read", new Dictionary() {
{ "role", "amazon:VB" }
});
speak_elem.AddS("or the past participle form");
speak_elem.AddW("read", new Dictionary() {
{ "role", "amazon:VBD" }
});
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
The rendered XML document would be:
```xml theme={null}
The word
read
may be interpreted as either the present simple form
read
or the past participle form
read
```
### More examples
```xml theme={null}
I can speak in a
higher pitched voice
, or I can speak
in a lower pitched voice
I can speak
really slowly
, or I can speak
really fast
I can also speak
very loudly
, or I can speak very quietly.
```
# STIR/SHAKEN
Source: https://plivo.com/docs/voice/concepts/stir-shaken
Caller ID authentication and attestation levels for US voice calls
* **What:** US caller ID authentication framework with three attestation levels: Full (A), Partial (B), Gateway (C) to combat call spoofing
* **How:** Automatic. Plivo signs outbound calls and verifies inbound calls. Check `X-Plivo-Stir-Verification` header or CDR for status
* **Verified (A):** Only when using a Plivo DID owned by the calling account as caller ID
* **Limitation:** US calls only. Non-US and WebRTC/SIP calls show "Not Applicable". Plivo may stop signing if account violates fair use or receives traceback requests
## Introduction
Spam and robocalls have become an increasingly significant problem in the US, leading to consumers losing trust in businesses. STIR/SHAKEN is a set of protocols designed for businesses to gain back this trust by authenticating the businesses making calls and the caller ID used in them.
STIR/SHAKEN stands for the Secure Telephone Identity Revisited (STIR) and Signature-based Handling of Asserted Information Using toKENs (SHAKEN). Under STIR/SHAKEN, every voice call in the US is assigned an attestation — a stamp of legitimacy provided by the originating service provider, authenticating that the call originated from its network. Calls are then passed to the terminating service provider for verification. There are three levels of call attestations:
* Full attestation (A) — The service provider has authenticated its relationship with the customer making the call and the customer is authorized to use the calling number.
* Partial attestation (B) — The service provider has authenticated its relationship with the customer making the call, but cannot verify that the customer is authorized to use the calling number.
* Gateway attestation (C) — The service provider has authenticated that it has placed the call on its network, but has no relationship with the originator of the call (for example, a call received from an international gateway).
## Plivo STIR verification
For both outbound and inbound Voice API calls, Plivo will display the verification status of a call as a parameter called STIR Verification, which can have one of three values:
* **Verified** means the call is from a Verified caller who has authorized access to the customer’s caller ID, and hence should be treated with confidence. Verified is equivalent to attestation level A.
* **Not Verified** means that, for this call, either the caller is not Verified, or it’s uncertain whether they have access to the caller ID used, or both. Not Verified means the call received attestation level B or C.
* **Not Applicable** means STIR/SHAKEN doesn’t apply to this call, as would be the case if a call is not addressed to a US number or if it’s a cloud call (WebRTC or SIP).
The STIR Verification parameter will be added to:
* [Call detail records](/docs/voice/api/calls/#retrieve-all-calls) for all inbound and outbound calls.
* As part of the information sent to answer\_url, fallback\_url, and hangup\_url webhooks.
## For outbound calls
Plivo will sign outbound calls as Verified (attestation A) for calls that use a Plivo DID as caller ID. The DID used should be [rented](/docs/numbers/phone-numbers#buy-a-phone-number) by the same Plivo account that originates the outbound calls. All other outbound calls, assuming they are signed at all, are signed Not Verified (attestation B or C).
Note: We strongly encourage customers to use Plivo DIDs as caller ID to improve their STIR/SHAKEN verification levels.
As the regulatory ecosystem evolves, some of the rules governing the attestation level of an outbound call might be subject to change. For now, Plivo will be signing all outbound calls to the USA unless a customer violates the rules:
1. The calls breach the [Plivo Fair Usage Policy](https://www.plivo.com/legal/tos/).
2. The calls are identified as unsolicited robocalls.
3. Plivo gets a traceback request from the [Industry Traceback Group](https://www.ustelecom.org/the-industry-traceback-group-itg/) about calls made by the customer.
4. The calls have invalid caller IDs — for instance, if they don’t adhere to E.164 format or have too many digits.
In these scenarios, Plivo may stop signing all calls initiated by the customer. That could lead to lower answer rates, because calls won’t be marked as Verified. Worst case, they could be marked as spam by receiving networks.
Note: For outbound calls to North American toll-free numbers outside the USA, users might see Verified or Not Verified values when in fact these calls are not being signed and the value should be “Not Applicable.” This is because there are shared toll-free numbers, leading to possibility of mismatch.
### Plivo Console logs
In the SIP response, Plivo will send in a new header called **X-Plivo-Stir-Verification** whose value is one of the aforementioned three states. You can also see STIR verification values on the Voice > [Logs](https://cx.plivo.com/logs?tab=voice) page of the console as part of CDR.
## For inbound calls
Plivo will validate attestation of calls to Plivo DIDs and toll-free numbers in the US. The validated STIR/SHAKEN verification level will be passed as part of webhook requests to various URLs — answer\_url, fallback\_url, and hangup\_url. Verification levels will also be visible on the Plivo [console](https://cx.plivo.com/logs?tab=voice) and in [call detail records](/docs/voice/api/calls/#retrieve-a-call).
### Plivo Console Logs
As mentioned earlier, In the SIP response, Plivo will send in a new header called **X-Plivo-Stir-Verification** whose value is one of the aforementioned three states. You can also see STIR verification values on the Voice > [Logs](https://cx.plivo.com/logs?tab=voice) page of the console as part of CDR.
# Terminology
Source: https://plivo.com/docs/voice/concepts/terminology
Key terms and definitions for Plivo voice calling — legs, sessions, callbacks, and more
| | |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A leg | An A leg is the initial leg of a call. When someone dials your Plivo number, the inbound call connection between the caller and your Plivo number is the A leg. For more information about call legs and types of calls, refer to our [Voice Overview](/docs/voice/concepts/overview/#what-is-a-voice-call) page. |
| API | An application programming interface is a computing interface that defines interactions between multiple software intermediaries. |
| api\_id | A Plivo api\_id is a unique ID for each API request made. |
| B leg | The B leg represents the secondary leg of a call. For example, if an inbound call to your Plivo number is forwarded to another line, the forwarded leg is the B leg. For more information about call legs and types of calls, refer to our [Voice Overview](/docs/voice/concepts/overview/#what-is-a-voice-call) page. |
| Carrier | A telecom carrier is a company that’s authorized by regulatory agencies to operate a telecommunications system and provide mobile or landline connections to consumers and businesses. |
| CDR | A Call Detail Record contains all the details about and serves as the source of truth for that call. You can export CDRs from Voice > Logs > [Calls](https://cx.plivo.com/logs?tab=voice) on the Plivo console. |
| Client SDK | Plivo’s client software development kits contain wrapper classes that help you connect directly to the Plivo Voice Platform to make and receive calls using a Plivo endpoint or client. Plivo provides [Browser](/docs/sdk/client/browser/overview/) and mobile ([iOS](/docs/voice/client/androidios/overview) and [Android](/docs/voice/client/androidios/overview)) client SDKs that you can integrate with your web and mobile apps to enable voice calling. |
| DID | Direct Inward Dial numbers are virtual phone numbers that Plivo provides and on which you can receive calls. You can programmatically control calls coming in to these numbers by assigning a Plivo application to them using the Plivo console. For more information, refer to our [Receive Incoming Calls](/docs/voice/use-cases/receive-incoming-calls) guide. |
| DTMF | Dual-tone multi-frequency tones, also called Touch-Tone, are the tones produced when someone presses a telephone keypad. DTMF tones are collected from users and passed over a communications network to a destination for processing. DTMF inputs are useful for IVR systems and use cases that involve user-directed interaction. |
| Hardphone | A hardphone is a hardware-based IP phone from vendors such as Cisco, Polycom, Mitel, and Snom |
| IVR | Interactive voice response systems let phone systems route calls without operator intervention. They depend on users speaking or entering keypad presses to traverse a menu of choices. |
| PoP | A point of presence is an access point that connects communication networks. PoPs are often located near large Internet exchange points (IXP) to minimize latency and maximize available bandwidth. Plivo maintains seven PoPs strategically placed across four continents to ensure optimal voice quality. |
| PSTN | The public switched telephone network is the circuit-switched telephone network that has been in use since the 1800s. It comprises telephone lines, fiber optic cables, microwave transmission links, cellular networks, communications satellites, and undersea telephone cables, all interconnected by switching centers. It’s also referred to as POTS — plain old telephone service. By contrast, VoIP uses packet switching. |
| Routing | Routing, in telephony, is the process of selecting the priority carrier for a given destination prefix and country. |
| Sandbox number | Sandbox numbers are number that have been verified for use with Plivo. You must use a sandbox number to make a call or send a message if you have a Plivo trial account. |
| SDK | A software development kit is a package of prewritten code that developers can reuse to minimize the amount of unique code they need to develop themselves. |
| Server SDK | Plivo’s server software development kits help developers quickly integrate their code with Plivo APIs in their language of choice. They contains functions and methods that can be used to trigger API requests and generate XML to manage call flows and implementations. Plivo provides server SDKs for seven languages: [PHP](/docs/voice/quickstart/quickstart), [Python](/docs/voice/quickstart/quickstart), [Node.js](/docs/voice/quickstart/quickstart), [Java](/docs/voice/quickstart/quickstart), [.NET (C#)](/docs/voice/quickstart/quickstart), [Ruby](/docs/voice/quickstart/quickstart), and [Go](/docs/voice/quickstart/quickstart). |
| SIP | Session Initiation Protocol is a signaling protocol for controlling and signaling multimedia communication on VoIP networks. |
| SIP URI | A SIP URI (uniform resource identifier) is an address for a SIP-enabled device. SIP URIs are written in the format [user@domain.tld](mailto:user@domain.tld). |
| Softphone | A softphone is a software-based implementation of a SIP phone client. Examples: Zoiper, Bria, X-Lite |
| UUID | A universally unique identifier — a 128-bit label, calculated using standard formulas in such a way that the probability of having duplicate UUIDs is negligible. Plivo uses UUIDs to identify various entities, including individual calls, messages, and API requests. |
| VoIP | Voice over Internet Protocol, also called IP telephony, is a set of methods and technologies for the delivery of voice and multimedia communications over packet-switched IP networks such as the internet. |
| WebRTC | Web Real-Time Communication is a World Wide Web Consortium (W3C) specification that allows audio and video communication to work inside web pages and supports browser-to-browser applications for voice calling, video chat, and P2P file sharing without the need for plugins. |
| XML | Extensible Markup Language defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. Plivo uses XML documents to control communication flows. |
# UCC Management
Source: https://plivo.com/docs/voice/concepts/ucc-management
How Plivo handles Unsolicited Commercial Communication (UCC) complaints for Indian voice numbers, and what you need to do
* **What:** TRAI-mandated process for handling UCC complaints against your India voice numbers (landline and 160-series)
* **Where to act:** [UCC dashboard](https://cx.plivo.com/phone-numbers/ucc) under **Phone Numbers → UCC** — review complaints and upload opt-in proof
* **Daily emailer:** Plivo sends a daily summary of open complaints to your registered account email
* **Action required:** Submit opt-in proof within 5 business days of receiving a complaint, or your number's compliance ID is blocked for 15 days
* **Proof format:** Business logo, complainant's name and phone number, opt-in date (must be within last 6 months)
* **Escalation:** 5+ complaints in 10 days = immediate suspension. Second violation = TRAI blacklisting for 1 year across ALL Indian operators
* **Critical:** Do NOT call a complainant after they file. It's itself a violation
How Plivo handles Unsolicited Commercial Communication (UCC) complaints for Indian voice numbers, and what you need to do.
**Applies to:** India voice numbers (landline series, 160 series) · **Regulation:** TRAI TCCCPR (Second Amendment) Regulations, 2025
***
## Overview
If someone receives a commercial call they didn't opt in to, they can file a UCC complaint with their telecom provider. TRAI — India's telecom regulator — requires Plivo to investigate these complaints and take action when they are valid.
This page explains how the complaint process works, what you need to do when a complaint is filed against your calls, and what happens if you don't respond in time.
**TRAI Definition — UCC:** "Unsolicited Commercial Communication or UCC" means any commercial communication that is neither as per the consent nor the registered preferences of the recipient. Transactional and service voice calls are explicitly excluded — but only when made from the correct number series.
Source: TRAI TCCCPR (Second Amendment) Regulations, 2025 — Regulation 2(bw)
**Number series matter.** TRAI mandates specific number series for specific call types — landline series (e.g., 022, 080) for non-BFSI service and transactional calls, and 160 series for BFSI service and transactional calls. Using the wrong series is itself a violation — complaints arising from such calls are treated as UCC regardless of opt-in. See [India Calling Regulations](/docs/voice/concepts/india-calling#number-series-regulations) for the full breakdown of permitted uses per series.
***
## How Do I Track UCC Complaints?
Plivo surfaces UCC complaints in three ways: the **UCC dashboard** in the Plivo console, a **daily email summary** sent to your registered account email, and the **UCC API** for programmatic access.
### UCC Dashboard
The UCC dashboard lists every UCC complaint linked to your account and the action required for each.
**Open the dashboard:** Go to [Phone Numbers → UCC](https://cx.plivo.com/phone-numbers/ucc) in the Plivo console.
**Give compliance staff access.** Account owners and administrators can already view the UCC dashboard. To let a compliance team member access it without granting billing or configuration rights, invite them with the **Support** role. Go to [Team Setup → Users](https://cx.plivo.com/team-setup/users), click **Invite User**, enter their email, select the **Support** role, and click **Invite User**.
The dashboard shows one row per complaint with these columns:
| Column | What it shows |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **Plivo Reference** | Unique complaint ID assigned by Plivo (e.g., `PUCC-2026-990000051`) |
| **Call UUID** | Plivo Call UUID of the call that triggered the complaint — use it to look up the call in [Voice → Call Logs](https://cx.plivo.com/voice/logs) |
| **Date Of Call** | Date the call was placed |
| **From Number** | The Plivo number used to make the call |
| **Complainant Number** | The phone number that filed the complaint |
| **Date of Complaint** | Date Plivo received the complaint |
| **Deadline for Submission** | Last date to submit valid opt-in proof (5 business days after the complaint date) |
| **Status** | Complaint state — see below |
#### Status Values and Actions
| Status | Meaning | Action |
| ------------ | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Pending** | Awaiting opt-in proof | Click **Upload Proof** to submit your opt-in document |
| **Accepted** | Submitted proof was reviewed and accepted | No action required |
| **Rejected** | Submitted proof was reviewed and rejected | Hover the info icon to view the rejection reason, then click **Re-upload** with corrected proof — you must resubmit within the original 5-day window |
#### Filtering and Export
* **Search** by Plivo Reference or From Number using the search bar
* **Filter by status** using the **Status** filter — narrow to Pending, Accepted, or Rejected complaints
* **Export CSV** downloads the current filtered view for offline review or audit logs
### Daily Email Summary
Plivo sends a daily email summary of open UCC complaints to your registered account email and to any additional recipients [configured in your Plivo Console](https://cx.plivo.com/profile/details).
| Field | Value |
| ------------- | ------------------------------------------------------------------------------------------ |
| **Subject** | Summary of UCC complaints on your Plivo account |
| **When sent** | Daily, while you have open (Pending or Rejected) complaints |
| **CTA** | **Review and resolve** — opens the [UCC dashboard](https://cx.plivo.com/phone-numbers/ucc) |
The email breaks down your open complaints into the following buckets:
| Bucket | What it counts |
| --------------------------------------------- | ------------------------------------------------------------------------------------------- |
| **Total complaints that need your attention** | All open complaints (Pending + Rejected) |
| **New in last 24 hours** | Complaints raised in the last day — submit proof within 5 days |
| **Today's deadline** | Complaints whose 5-day proof window ends today — submit proof by end of day |
| **Proof rejected** | Complaints where your earlier proof was rejected — check the rejection reason and re-submit |
| **Overdue beyond 5 days** | Complaints past the deadline — at risk of compliance ID suspension, submit today |
| **Other open** | Open complaints not in the above buckets — submit proof before deadline |
Keep your notification list current. Not receiving an email notification does not exempt you from your compliance obligations or the consequences of missing the 5-day proof submission window. Configure additional recipients at [Profile Details](https://cx.plivo.com/profile/details).
### UCC API
You can also manage UCC complaints programmatically instead of through the console. The [UCC API](/docs/numbers/ucc) lets you list and retrieve complaints against your account, submit opt-in proof, and receive an event whenever a complaint is created or its status changes — so you can wire complaint handling into your own systems and never depend on someone watching an inbox.
***
## What Do I Need to Do When I Receive a Complaint?
You are required to take the following actions within **5 business days** of receiving the complaint notification from Plivo.
### 1. Submit Opt-In Proof
You must provide documented evidence that the complainant validly opted in to receive calls from your business.
Your proof must contain **all three** of the following:
| Required Element | Details |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **Business logo** | The logo or identity of the business entity that made the call, to verify the caller's identity on the DLT platform |
| **Date of opt-in** | The date the recipient explicitly opted in to receive calls. Must be within the last 6 months from the complaint date. |
| **Complainant's phone number** | The exact number of the person who filed the complaint, confirming the opt-in was obtained for that specific number |
**6-month opt-in validity window.** An opt-in acquired more than 6 months before the complaint date will not be accepted. Ensure your opt-in collection system records timestamps accurately.
#### If Your Proof Is Rejected
If the submitted proof is incomplete, expired, or does not meet Plivo's review criteria:
* Plivo sends you an email with the reason for rejection.
* You must resubmit valid proof within the same 5-day window.
* If no valid proof is submitted before the deadline, compliance action proceeds as described below.
### 2. Remove the Complainant from Your Calling List
Regardless of whether your proof is accepted or rejected, immediately remove the complainant's phone number from your outbound calling list.
**Do not call again.** Continuing to call a person who has filed a UCC complaint is itself a violation under TRAI regulations, irrespective of whether you hold valid opt-in documentation.
***
## What Happens If I Don't Submit Valid Proof?
TRAI prescribes a structured escalation framework, which Plivo is obligated to enforce as your OAP. Consequences are tied to your compliance ID, not your overall Plivo account.
**No compliance ID mapped to your number?** If a UCC complaint is received against a number that has no compliance ID mapped to it, the complaint will be counted against the billing entity — leading to compliance actions against your entire business, not just a single number.
| Scenario | Trigger | Consequence |
| ----------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Single complaint — no proof in 5 days** | 1 valid UCC complaint; proof not submitted within 5 business days | Compliance ID blocked for 15 days. Submitting valid proof during this window lifts the block. |
| **First violation** | 5 or more unique recipient complaints within any rolling 10-day window | Compliance ID suspended for 15 days. Submit valid proofs within 15 days — if accepted, violation is waived. If not, counts as 1st violation. |
| **Second violation** | A second instance of 5+ complaints in 10 days after 1st violation | TRAI blacklisting. All telecom resources barred for 1 year across all providers in India. No new services can be obtained from any operator. |
### Single Complaint — No Proof in 5 Days
If a valid UCC complaint is received and you fail to submit proof within 5 business days, Plivo blocks your compliance ID:
* All outgoing calls from your compliance ID are suspended.
* The block is in place for 15 days.
* You may submit valid proof during these 15 days to lift the block.
* If no valid proof is received within the 15-day window, the block may be made permanent pending further review.
### First Violation — 5 or More Complaints in 10 Days
As per TRAI Regulation 25(4)(f)(i), if Plivo receives complaints from 5 or more unique recipients within any rolling 10-day window, TRAI mandates immediate suspension. Plivo:
1. Suspends your compliance ID immediately upon detection.
2. Issues a formal notice giving you an opportunity to submit representations and proofs.
3. Reviews submitted proofs within 5 business days of receiving your representation.
* **If all proofs are valid:** the violation is waived — it does not count against your record.
* **If proofs are invalid or not submitted:** this counts as the 1st violation. Your compliance ID is barred for 15 days.
### Second Violation — TRAI Blacklisting
If a second instance of 5+ complaints within a 10-day window occurs after the first confirmed violation, TRAI mandates the following under Regulation 25(4)(f)(i)(B):
* All telecom resources — including PRI/SIP trunks — are disconnected by all Access Providers for 1 year.
* The sender is blacklisted on the DLT platform. No new telecom resources can be provisioned by any provider during this period.
* All devices used for making UCC may also be blocked across all Access Providers for 1 year.
**TRAI blacklisting applies across all operators in India.** A blacklisted business cannot obtain telecom services from any operator in India for the duration of the blacklisting period — not just Plivo.
***
## Right to Represent
You may file a representation with Plivo against any action taken at the first or second violation stage. Plivo is required to decide on the representation within 7 business days. You may also appeal to TRAI directly under Regulation 29 of the TCCCPR Regulations.
***
## Related
* [India Calling Regulations](/docs/voice/concepts/india-calling) — Number series rules and calling requirements
* [160-Series Numbers](/docs/voice/concepts/160-series-provisioning) — Setup guide for BFSI transactional and service voice numbers
* [UCC Dashboard](https://cx.plivo.com/phone-numbers/ucc) — Review complaints and upload opt-in proof
* [Profile Details](https://cx.plivo.com/profile/details) — Configure email recipients for compliance notifications
* [Plivo Support](https://support.plivo.com) — Get help with compliance questions
# Verified Caller ID
Source: https://plivo.com/docs/voice/concepts/verified-caller-id
Use your own phone numbers as outbound caller IDs after verification
* **What:** Verify ownership of your own phone numbers via OTP (SMS or voice call), then use them as outbound caller IDs
* **How:** Initiate verification via [API](/docs/voice/api/verified-caller-ids) or Console (**Voice > Verified Caller ID**), receive and confirm OTP
* **Limitation:** Primarily US only. Not reliably supported internationally due to local carrier restrictions
* **India:** Not supported. You must use a Plivo-rented Indian number as caller ID per local regulations
Plivo's Verified Caller ID feature allows customers to use their own numbers as outbound caller IDs after verification.
Simply register the number you wish to use for outbound calls with Verified Caller ID. Plivo will send a one-time password (OTP) to the designated number through your preferred channel—SMS or voice. Once successfully authenticated, your number will be added to the verified caller ID list and can be used as the caller ID for making outbound calls.
There are two ways to verify your number: through the [Plivo console](https://cx.plivo.com/phone-numbers?tab=caller-id) or using Plivo's REST APIs or SDKs.
**International Limitations**
Verified Caller ID is primarily designed for US compliance. Due to local regulations:
* **India:** Not applicable. Indian regulations require using Plivo-rented Indian numbers as caller ID.
* **Other countries:** May not work reliably due to carrier restrictions and local regulations.
**Recommendation:** For reliable caller ID display, use a [Plivo-rented phone number](/docs/numbers/phone-numbers#buy-a-phone-number) in the destination country.
***
## Why should you verify a caller ID?
The rise of call spoofing poses a significant challenge for businesses globally. This fraudulent practice uses technology to mimic calls from local numbers, reputable companies, government agencies, or genuine contacts.
Plivo's Verified Caller ID, designed to combat call spoofing, strengthens outbound call credibility by ensuring number verification before their utilization as the outbound caller ID.
## Verify your caller ID using Plivo’s APIs
Initiate the verification process using Plivo’s Verified Caller APIs/SDK according to the guides linked below. Plivo will initiate the OTP through the channel you select.
### Code
```py Python theme={null}
import plivo
client = plivo.RestClient('', '')
response = client.verify_callerids.initiate_verify(phone_number='',
alias='',
channel='call/sms',
subaccount='')
print(response)
```
```rb Ruby theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("", "")
begin
response = api.verify_caller_id.initiate(
phone_number="91XXXXXXXXXX", channel="sms", alias_ = "test",subaccount=""
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
```js Node.js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.verify.initiate('',{
channel : '',
alias : '',
subAccount : ''
}).then(function(response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
```php PHP theme={null}
","");
try {
$response = $client->verifyCallerId->initiate("+91XXXXXXXXX", [
"alias" => "test",
"subaccount" => "",
"channel" => "Call"
]);
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
```java Java theme={null}
package com.plivo.examples;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.verify.InitiateVerifyResponse;
import com.plivo.api.models.verify.Verify;
import java.io.IOException;
public class verificationCallerID {
public static void main(String[] args) {
Plivo.init("", "");
try {
InitiateVerifyResponse response = Verify.initiateVerify().phoneNumber("91XXXXXXXXXX").alias("test").channel("call").create();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
```Go Go theme={null}
package main
import (
"fmt"
"github.com/plivo/plivo-go/v7"
)
func main() {
client, err := plivo.NewClient("", "", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.VerifyCallerId.InitiateVerify(plivo.InitiateVerify{PhoneNumber: "", Alias: "", Channel : "", SubAccount: ""})
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
```
```cs .NET theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("","");
try
{
var response = api.VerifyCallerId.Initiate("", "", "","");
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
Console.WriteLine("Exception: " + e);
}
}
}
}
```
```sh Curl theme={null}
curl -i --user AUTH_ID:AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{"phone_number": "+12025551XXX","alias":"US Mainland"}' \
https://api.plivo.com/v1/Account/{auth_id}/VerifiedCallerId/
```
## Verify your one-time passcode (OTP) via API
As part of the caller ID verification process, you will need to confirm your phone number by receiving an OTP. Follow the guides linked below to verify your OTP using APIs and SDK. Once the OTP is confirmed, you can use the verified number as a caller ID.
### Code
```py Python theme={null}
import plivo
client = plivo.RestClient('', '')
response = client.verify_callerids.verify_caller_id(verification_uuid="68dea750-5a76-485d-8ac3-5cf5996ba2fb",otp="123456")
print(response)
```
```rb Ruby theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("", "")
begin
response = api.verify_caller_id.verify("", "")
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
```
```js Node.js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.verify.verify("","").then(function(response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
```php PHP theme={null}
","");
try {
$response = $client->verifyCallerId->verify("","");
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
```java Java theme={null}
package com.plivo.examples;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.verify.InitiateVerifyResponse;
import com.plivo.api.models.verify.Verify;
import java.io.IOException;
public class verificationCallerID {
try{
VerifyCallerIdResponse response = Verify.verifyCallerId("2dfd42e2-431d-4bf6-bc70-d3971ffae240").otp("277407").create();
System.out.println(response);
}catch(PlivoRestException | IOException e){
e.printStackTrace();
}
}
}
```
```go Go theme={null}
package main
import (
"fmt"
"github.com/plivo/plivo-go/v7"
)
func main() {
client, err := plivo.NewClient("", "", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.VerifyCallerId.VerifyCallerID("","123456")
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
```
```cs .NET theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("","");
try
{
var response = api.VerifyCallerId.Verify("", "");
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
Console.WriteLine("Exception: " + e);
}
}
}
}
```
```sh Curl theme={null}
curl -i --user AUTH_ID:AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{"otp": "7871"}' \
https://api.plivo.com/v1/Account/{auth_id}/VerifiedCallerId/Verification/f87836bd-f3c0-41bb-9498-125e6faaa4d4/
```
## Verify your caller ID using the Plivo console
You can verify your caller ID on the Plivo console by taking the following steps.
1. Log in to the Plivo console.
2. Go to Voice → Verified Caller ID.
3. Choose "Verify Your First Number."
4. Enter the alias name, the number requiring verification, and the verification method. If you're a reseller verifying for your client, select the sub-account.
5. After selecting "Request Verification Code," you'll receive the code via SMS or voice, depending on the method you selected.
6. Upon successful verification, your number will be added to the Verified Caller ID list. You can then use the verified number as a caller ID to place outbound calls.
# Voice Alerts (New)
Source: https://plivo.com/docs/voice/concepts/voice-alerts
Send automated voice notifications and alerts to phone numbers
* **What:** Automatic real-time monitoring of your voice traffic. Detects anomalies in CPS, callback failures, call patterns, and high-risk destinations
* **How:** No setup required. Alerts are sent automatically to your registered email
* **Alerts include:** Call queue delays (>2 min), callback failures (>5%), config errors, volume/spend spikes, robocall pattern detection, high-risk country surges
* **Note:** Queue delay alerts may indicate you need a higher CPS limit, available on an Enterprise plan. Ask **Buddy**, Plivo's in-console chat agent, in the [console](https://cx.plivo.com/home) to request one
Voice Alerts, developed by Plivo, is an active monitoring system that employs an advanced algorithm capable of detecting voice traffic anomalies in real-time. Voice Alerts swiftly identifies and resolves potential issues to maintain a reliable, efficient voice service for our users.
Voice Alerts leverages a sophisticated algorithm to detect anomalies in voice traffic, continuously monitoring various parameters to pinpoint deviations from expected norms. The system keeps a vigilant eye on multiple factors, including calls per second (CPS) utilization, errors in posting callbacks to customer callback servers, configuration errors that may result in call failures, and call patterns.
Upon detecting an anomaly, Voice Alerts promptly emails customers about the identified issue. This alert allows users to rectify the problem quickly.
## Alerts category
### Call dequeue delays
Long call queues are often caused by breaching the CPS limit. Voice Alerts diligently monitors the duration of calls in the queue. While a small number of queued calls may not significantly impact delays, a substantial accumulation could lead to delayed call dispatch and potentially affect the timely delivery of notifications to your customers.
To tackle this issue, Voice Alerts will automatically notify your registered email address if calls remain in the queue for over two minutes. If you consistently encounter prolonged queue times, you can request a higher CPS limit by asking **Buddy**, Plivo's in-console chat agent, in the [Plivo console](https://cx.plivo.com/home) to move to an Enterprise plan.
### Error in posting event callbacks
Plivo customers often depend on event callbacks to determine the call flow. Any issues in posting these callbacks could lead to call failures. Voice Alerts will monitor these failures and notify your registered email if we detect more than 5% of callback failures.
If you receive one of these emails, we advise checking the health of your callback server and address any issues you may have.
### Configuration errors
Configuration errors can lead to call failures. A configuration error could be as simple as an invalid XML returned in the response. Voice Alerts will monitor for these errors and raise an alert if we detect more than 5% of such failures.
If you receive this notification, we advise you to check the application logic from your end.
### Call pattern alerts
Call pattern alerts encompass a variety of parameters designed to detect unusual calling patterns associated with your account. They are intended to notify customers proactively of irregular activities and safeguard the overall ecosystem.
#### Call volume, call duration, and spend
Voice Alerts monitors the call volume, call duration and spending of your voice traffic on a country level. Compared to the previous usage, any usual spike in these parameters is alarming as this can also be an effect of some bad actors in the ecosystem inflating volume. Voice Alerts has an intelligent algorithm to map your current usage with historical data. Any abnormal deviation in the current traffic will alert you to review the call samples.
#### Calls to premium/shared cost numbers
Most businesses do not require placing calls to premium or shared-cost numbers. Any spike in calls to these destination numbers is a red flag. Voice Alerts proactively identifies such calls and notifies your registered email address.
#### Calls to repeated destinations or the same range of destination numbers
Multiple calls to repeated destinations and calls to the same range of destination numbers may be a sign of robocalling activity. Voice Alerts proactively identifies such calls and notifies your registered email address.
#### Short-duration and zero-duration calls
Short-duration calls are answered calls with a duration of less than or equal to six seconds. A spike in both short-duration and zero-duration calls indicates that either intended call recipient is rejecting the calls or that your call is being blocked by someone in the call flow chain. Investigating any abnormal spike in short-duration and zero-duration calls is necessary to maintain good stats. Voice Alerts compares your previous usage and will notify you if there is an abnormal spike.
#### High-risk countries
An abnormal spike in calls towards high-risk destinations can incur high costs, and should be cause for alarm. Voice Alerts will notify your registered email if there is a surge in calls to one or more high-risk countries listed below:
* Albania
* Belarus
* Bulgaria
* Cuba
* Ecuador
* Haiti
* Ivory Coast
* Papua New Guinea
* Samoa
* Latvia
* Somalia
* Gambia
* Zimbabwe
* Tunisia
* Guinea
* Liberia
* Solomon Islands
* Vanuatu
# Upgrade from SDK v4 to v4.8.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/active-sdk
Upgrade your Plivo SDK within the v4.x line — breaking changes guide
# Upgrade from Node SDK v4 to v4.8.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: Plivo Node SDK versions lower than 4.8.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **npm install plivo\@4.8.0** to upgrade to the active version of the SDK, or **npm install plivo\@latest** to upgrade to the latest version.
# Upgrade from Ruby SDK v4 to v4.9.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Ruby SDK versions lower than 4.9.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **gem install plivo -v 4.9.0** to upgrade to the active version of the SDK, or **gem update plivo** to upgrade to the latest version.
# Upgrade from Python SDK v4 to v4.9.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Python SDK versions lower than 4.9.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **pip install --upgrade plivo==4.9.0** to upgrade to the active version of the SDK, or **pip install --upgrade plivo** to upgrade to the latest version.
# Upgrade from PHP SDK v4 to v4.25.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo PHP SDK versions lower than 4.25.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **composer require plivo/plivo-php:4.25.0** to upgrade to the active version of the SDK, or **composer require plivo/plivo-php** to upgrade to the latest version.
# Upgrade from .NET SDK v4 to v4.10.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo .NET SDK versions lower than 4.10.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Use the command **Update-Package Plivo -Version 4.10.0** to upgrade to the active version of the SDK, or **Update-Package Plivo** to upgrade to the latest version.
## Breaking changes
If you are upgrading to versions higher than [v4.17.1](https://github.com/plivo/plivo-dotnet/releases/tag/v4.17.1), be aware of a breaking change with those versions:
[v5.0.0](https://github.com/plivo/plivo-dotnet/releases/tag/v5.0.0)
* **BREAKING:** Removed the total\_count parameter in metadata for list MDR response
# Upgrade from Java SDK v4 to v4.8.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Java SDK versions lower than 4.8.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Update the dependency in your project to compile **'com.plivo:plivo-java:4.8.0'** to upgrade to the active version of the SDK.
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Use the command **Update-Package Plivo -Version 4.10.0** to upgrade to the active version of the SDK, or upgrade to the latest version.
## Breaking Changes
If you are upgrading to versions higher than [v4.15.3](https://github.com/plivo/plivo-java/releases/tag/v4.15.3), be aware of a breaking change with those versions:
[v5.0.0](https://github.com/plivo/plivo-java/releases/tag/v5.0.0)
* **BREAKING:** Remove getTotalCount() method for list MDR
# Upgrade from Go SDK v4 to v4.8.0 or Latest Version
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Go SDK versions lower than v4.8.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Use the command go get github.com/plivo/plivo-go/v7\@v4.8.0 to upgrade to the active version of the SDK, or go get github.com/plivo/plivo-go/v7\@latest to upgrade to the latest version.
## Breaking changes
If you are upgrading to a version higher than [v4.9.1](https://github.com/plivo/plivo-go/releases/tag/v4.9.1), be aware of some breaking changes with those versions:
[v5.0.0](https://github.com/plivo/plivo-go/releases/tag/v5.0.0)
* **BREAKING:** Rename MultiPartyCall struct to PhloMultiPartyCall
[v6.0.0](https://github.com/plivo/plivo-go/releases/tag/v6.0.0)
* **BREAKING:** Update AddSpeak method signature: remove optional parameters
* Add methods to set SpeakElement attributes
[v7.0.0](https://github.com/plivo/plivo-go/releases/tag/v7.0.0)
* Remove the total\_count parameter in metadata for list MDR response
# Upgrade from .NET SDK v4 to v4.10.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/dotnet
Upgrade your .NET SDK to v4.10.0+ — steps and breaking changes
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo .NET SDK versions lower than 4.10.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Use the command **Update-Package Plivo -Version 4.10.0** to upgrade to the active version of the SDK, or **Update-Package Plivo** to upgrade to the latest version.
## Breaking changes
If you are upgrading to versions higher than [v4.17.1](https://github.com/plivo/plivo-dotnet/releases/tag/v4.17.1), be aware of a breaking change with those versions:
[v5.0.0](https://github.com/plivo/plivo-dotnet/releases/tag/v5.0.0)
* **BREAKING:** Removed the total\_count parameter in metadata for list MDR response
# Upgrade from Go SDK v4 to v4.8.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/go
Upgrade your Go SDK to v4.8.0+ — steps and breaking changes
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Go SDK versions lower than v4.8.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Use the command go get github.com/plivo/plivo-go/v7\@v4.8.0 to upgrade to the active version of the SDK, or go get github.com/plivo/plivo-go/v7\@latest to upgrade to the latest version.
## Breaking changes
If you are upgrading to a version higher than [v4.9.1](https://github.com/plivo/plivo-go/releases/tag/v4.9.1), be aware of some breaking changes with those versions:
[v5.0.0](https://github.com/plivo/plivo-go/releases/tag/v5.0.0)
* **BREAKING:** Rename MultiPartyCall struct to PhloMultiPartyCall
[v6.0.0](https://github.com/plivo/plivo-go/releases/tag/v6.0.0)
* **BREAKING:** Update AddSpeak method signature: remove optional parameters
* Add methods to set SpeakElement attributes
[v7.0.0](https://github.com/plivo/plivo-go/releases/tag/v7.0.0)
* Remove the total\_count parameter in metadata for list MDR response
# Upgrade from Java SDK v4 to v4.8.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/java
Upgrade your Java SDK to v4.8.0+ — steps and breaking changes
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Java SDK versions lower than 4.8.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Update the dependency in your project to compile **'com.plivo:plivo-java:4.8.0'** to upgrade to the active version of the SDK.
You can upgrade to the active SDK version without making any changes to your implementation if you’re not using any of the features or APIs mentioned in the breaking changes section below. Use the command **Update-Package Plivo -Version 4.10.0** to upgrade to the active version of the SDK, or upgrade to the latest version.
## Breaking Changes
If you are upgrading to versions higher than [v4.15.3](https://github.com/plivo/plivo-java/releases/tag/v4.15.3), be aware of a breaking change with those versions:
[v5.0.0](https://github.com/plivo/plivo-java/releases/tag/v5.0.0)
* **BREAKING:** Remove getTotalCount() method for list MDR
# Upgrade from PHP SDK v4 to v4.25.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/php
Upgrade your PHP SDK to v4.25.0+ — steps and breaking changes
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo PHP SDK versions lower than 4.25.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **composer require plivo/plivo-php:4.25.0** to upgrade to the active version of the SDK, or **composer require plivo/plivo-php** to upgrade to the latest version.
# Upgrade from Python SDK v4 to v4.9.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/python
Upgrade your Python SDK to v4.9.0+ — steps and breaking changes
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Python SDK versions lower than 4.9.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **pip install --upgrade plivo==4.9.0** to upgrade to the active version of the SDK, or **pip install --upgrade plivo** to upgrade to the latest version.
# Upgrade from Ruby SDK v4 to v4.9.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/active-sdk/ruby
Upgrade your Ruby SDK to v4.9.0+ — steps and breaking changes
## Introduction
This is a minor application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
**Deprecation notice:** Plivo Ruby SDK versions lower than 4.9.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Update the SDK
Use the command **gem install plivo -v 4.9.0** to upgrade to the active version of the SDK, or **gem update plivo** to upgrade to the latest version.
# Upgrade from .NET SDK Legacy to v4.10.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/legacy-to-active-sdk/dotnet
Migrate from legacy .NET SDK to v4.10.0+ — code changes required
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: Plivo .NET SDK legacy versions lower than v4.10.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### .NET version support
The Plivo .NET SDK supports .NET applications written in C# and Visual Basic that utilize the .NET Framework version 3.5 or higher or any .NET runtime supporting [.NET Standard](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) v1.4.
Use the command **Update-Package Plivo -Version 4.10.0** to upgrade to the active version of the SDK, or **Update-Package Plivo** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using RestSharp;
using Plivo.API;
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
```
### Initialize
```csharp Legacy theme={null}
RestAPI plivo = new RestAPI("","");
```
```csharp Latest theme={null}
var api = new PlivoApi("","");
```
### Access resources
```csharp Legacy theme={null}
IRestResponse resp = plivo.make_call(new Dictionary()
{params});
```
```csharp Latest theme={null}
var response = api.Call.Create(params);
```
### Make a call
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using RestSharp;
using Plivo.API;
namespace make_calls
{
class Program
{
static void Main(string[] args)
{
RestAPI plivo = new RestAPI("", "");
IRestResponse resp = plivo.make_call(new Dictionary()
{
{ "from", "2025551212" },
{ "to", "2025552323" },
{ "answer_url", "https://s3.amazonaws.com/static.plivo.com/answer.xml" },
{ "answer_method","GET"},
});
Console.Write(resp.Content);
Console.ReadLine();
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("", "");
try
{
var response = api.Call.Create(
to: new List { "+12025552323" },
from: "+12025551212",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/answer.xml"
);
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
### Dial XML
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {
{"dialMusic", "https://.com/dial_music/"}
});
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {
{"dialMusic", "https://.com/dial_music/"}
});
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
### Conference XML
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddConference("My room",
new Dictionary()
{
{"startConferenceOnEnter", "true"},
{"endConferenceOnExit", "true"},
{"waitSound", "https://.com/waitmusic/"}
});
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddConference("My room",
new Dictionary()
{
{"startConferenceOnEnter", "true"},
{"endConferenceOnExit", "true"},
{"waitSound", "https://.com/waitmusic/"}
});
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
### Record API
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using RestSharp;
using Plivo.API;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
string auth_id = "";
string auth_token = "";
RestAPI plivo = new RestAPI(auth_id, auth_token);
IRestResponse resp = plivo.record(new Dictionary()
{
{ "call_uuid", uuid } // ID of the call
});
Debug.WriteLine(resp.Content);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("","");
try
{
var response = api.Call.StartRecording(
callUuid:"10c94053-73b4-46fe-b74a-12159d1d3d60"
);
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
### Record XML
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddRecord(new Dictionary() {
{"action", "https://.com/get_recording/"},
{"startOnDialAnswer", "true"},
{"redirect", "false"}
});
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary()
{ });
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddRecord(new Dictionary() {
{"action", "https://.com/get_recording/"},
{"startOnDialAnswer", "true"},
{"redirect", "false"}
});
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary()
{ });
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
# Upgrade from Java Legacy to v4.8.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/legacy-to-active-sdk/java
Migrate from legacy Java SDK to v4.8.0+ — code changes required
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Java SDK legacy versions lower than v4.8.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Java version support
The Plivo Java SDK supports OpenJDK 8 and 11 and OracleJDK 8 and 11.
Use the command `Update-Package Plivo -Version 4.10.0` to upgrade to the active version of the SDK, or upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```java Legacy theme={null}
import com.plivo.helper.api.client.*;
import com.plivo.helper.xml.elements.Dial;
```
```java Latest theme={null}
import com.plivo.api.Plivo;
import com.plivo.api.xml.Dial;
```
### Initialize
```java Legacy theme={null}
RestAPI api = new RestAPI("","", "v1");
```
```java Latest theme={null}
Plivo.init("","");
```
### Accessing resources
```java Legacy theme={null}
Call resp = api.makeCall(parameters);
```
```java Latest theme={null}
CallCreateResponse response = Call.creator(parameters)
.create();
```
### Make a call
```java Legacy theme={null}
package com.plivo.test;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import com.plivo.helper.api.client.*;
import com.plivo.helper.api.response.call.Call;
import com.plivo.helper.exception.PlivoException;
public class App {
public static void main(String[] args) throws IllegalAccessException {
String auth_id = "";
String auth_token = "";
RestAPI api = new RestAPI(auth_id, auth_token, "v1");
LinkedHashMap parameters = new LinkedHashMap();
parameters.put("to","2025552323");
parameters.put("from","2025551212");
parameters.put("answer_url","https://s3.amazonaws.com/static.plivo.com/answer.xml");
parameters.put("answer_method","GET");
try {
Call resp = api.makeCall(parameters);
System.out.println(resp);
} catch (PlivoException e) {
System.out.println(e.getLocalizedMessage());
}
}
}
```
```java Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
package com.plivo.api.samples.call;
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class CallCreate {
public static void main(String [] args) {
Plivo.init("","");
try {
CallCreateResponse response = Call.creator("+12025551212", Collections.singletonList("+12025552323"), "https://s3.amazonaws.com/static.plivo.com/answer.xml")
.answerMethod("GET")
.create();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
### Dial XML
```java Legacy theme={null}
import java.io.IOException;
import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Number;
import com.plivo.helper.xml.elements.Dial;
import com.plivo.helper.xml.elements.PlivoResponse;
class CustomCallerTone {
public static void main(String[] args) throws PlivoXmlException {
PlivoResponse response = new PlivoResponse();
Dial dial = new Dial();
dial.setDialMusic("https://.com/dial_music/");
Number number = new Number("12025552323");
response.append(dial);
dial.append(number);
System.out.println(response.toXML());
resp.addHeader("Content-Type", "text/xml");
resp.getWriter().print(response.toXML());;
}
}
```
```java Latest theme={null}
package com.plivo.api.xml.samples.dial;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Response;
class CustomCallerTone {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Dial()
.dialMusic("https://.com/dial_music/")
.children(
new Number("12025552323")
)
);
System.out.println(response.toXmlString());
}
}
```
### Conference XML
```java Legacy theme={null}
import java.io.IOException;
import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Conference;
import com.plivo.helper.xml.elements.PlivoResponse;
class ModeratedConference {
public static void main(String[] args) throws PlivoException {
PlivoResponse response = new PlivoResponse();
Conference conference = new Conference("My Room");
conference.setEnterSound("");
conference.setStartConferenceOnEnter(true);
conference.setEndConferenceOnExit(true);
conference.setWaitSound("https://.com/music/");
response.append(conference);
System.out.println(response.toXML());
resp.addHeader("Content-Type", "text/xml");
resp.getWriter().print(response.toXML());;
}
}
```
```java Latest theme={null}
package com.plivo.api.xml.samples.conference;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Conference;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
class ModeratedConference {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Speak("You will now be placed into a demo conference"),
new Conference("demo")
.endConferenceOnExit(true)
.startConferenceOnEnter(false)
.waitSound("https://.com/waitmusic/")
);
System.out.println(response.toXmlString());
}
}
```
### Record API
```java Legacy theme={null}
package plivoexample;
import java.io.IOException;
import java.util.LinkedHashMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.plivo.helper.api.client.RestAPI;
import com.plivo.helper.api.response.response.Record;
import com.plivo.helper.exception.PlivoException;
class recordApiAction {
public static void main(String[] args) throws PlivoException {
String auth_id = "";
String auth_token = "";
RestAPI api = new RestAPI(auth_Id, auth_Token, "v1");
LinkedHashMap parameters = new LinkedHashMap();
parameters.put("call_uuid",call_uuid);
Record record = api.record(parameters);
System.out.println(record);
}
}
```
```java Latest theme={null}
package com.plivo.api.samples.call.record;
import java.io.IOException;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.actions.CallRecordCreateResponse;
class RecordCreate {
public static void main(String [] args) {
Plivo.init("","");
try {
CallRecordCreateResponse response = Call.recorder("eba53b9e-8fbd-45c1-9444-696d2172fbc8")
.record();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
### Record XML
```java Legacy theme={null}
import java.io.IOException;
import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Record;
import com.plivo.helper.xml.elements.Dial;
import com.plivo.helper.xml.elements.Number;
import com.plivo.helper.xml.elements.PlivoResponse;
class recordSession {
public static void main(String[] args) throws PlivoException {
response.append(record);
response.append(dial);
dial.append(number);
System.out.println(response.toXML());
resp.addHeader("Content-Type", "text/xml");
resp.getWriter().print(response.toXML());;
}
}
```
```java Latest theme={null}
package com.plivo.api.xml.samples.record;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Record;
import com.plivo.api.xml.Response;
class RecordACompleteCallSession {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Record("https://.com/get_recording/")
.redirect(false)
.startOnDialAnswer(true),
new Dial()
.children(
new Number("12025552323")
)
);
System.out.println(response.toXmlString());
}
}
```
# Upgrade from Legacy to v4.8.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/legacy-to-active-sdk/legacy-to-active-sdk
Migrate from legacy SDK to v4.x — major upgrade steps and changes
# Upgrade from Node.js Legacy to v4.8.0 or Latest Version
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Node SDK legacy versions lower than v4.8.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Node.js version support
The 4.x version of the Plivo SDK is compatible with Node.js versions 5.5 and higher.
Use the command **npm install plivo\@4.8.0** to upgrade to the active version of the SDK, or **npm install plivo\@latest** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```js Legacy theme={null}
var plivo = require('plivo');
```
```js Latest theme={null}
var plivo = require('plivo');
```
### Initialize
```js Legacy theme={null}
var p = plivo.RestAPI({
authId: '',
authToken: ''
});
```
```js Latest theme={null}
var client = new plivo.Client("","");
```
### Access resources
```js Legacy theme={null}
p.make_call(params, function (status, response) {
console.log('Status: ', status);
console.log('API Response:\n', response);
});
```
```js Latest theme={null}
client.calls.create(params).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
```
### Make a call
```js Legacy theme={null}
var plivo = require('plivo');
var p = plivo.RestAPI({
authId: '',
authToken: ''
});
var params = {
'to': '2025552323',
'from' : '2025551212',
'answer_url' : "https://s3.amazonaws.com/static.plivo.com/answer.xml",
'answer_method' : "GET"
};
p.make_call(params, function (status, response) {
console.log('Status: ', status);
console.log('API Response:\n', response);
});
```
```js Latest theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.create(
"+12025551212", // from
"+12025552323", // to
"https://s3.amazonaws.com/static.plivo.com/answer.xml",
{
answerMethod: "GET",
},
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
### Dial XML
```js Legacy theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'dialMusic': "https://.com/dial_music/"
};
var dial = response.addDial(params);
var first_number = "12025551212";
dial.addNumber(first_number);
console.log(response.toXML());
```
```js Latest theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'dialMusic': "https://.com/dial_music/"
};
var dial = response.addDial(params);
var first_number = "12025551212";
dial.addNumber(first_number);
console.log(response.toXML());
```
### Conference XML
```js Legacy theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'startConferenceOnEnter': "false",
'waitSound': "https://.com/waitMusic/"
};
var conference_name = "My Room";
response.addConference(conference_name, params);
console.log(response.toXML());
```
```js Latest theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'startConferenceOnEnter': "false",
'waitSound': "https://.com/waitMusic/"
};
var conference_name = "My Room";
response.addConference(conference_name, params);
console.log(response.toXML());
```
### Record API
```js Legacy theme={null}
var plivo = require('plivo');
var p = plivo.RestAPI({
"authId": "",
"authToken": ""
});
var params = {'call_uuid':call_uuid};
var response = p.record(params);
console.log(response);
```
```js Latest theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.record(
"eba53b9e-8fbd-45c1-9444-696d2172fbc8", // call uuid
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
### Record XML
```js Legacy theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'action': "https://.com/get_recording/",
'startOnDialAnswer': "true",
'redirect': "false"
};
response.addRecord(params);
var dial = response.addDial();
var number = "12025552323";
dial.addNumber(number);
console.log(response.toXML());
```
```js Latest theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'action': "https://.com/get_recording/",
'startOnDialAnswer': "true",
'redirect': "false"
};
response.addRecord(params);
var dial = response.addDial();
var number = "12025552323";
dial.addNumber(number);
console.log(response.toXML());
```
# Upgrade from Ruby Legacy to v4.9.0 or Latest Version
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Ruby SDK legacy versions lower than v4.9.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Ruby version support
The Plivo Ruby SDK supports Ruby 2.0 and above.
Use the command **gem install plivo -v 4.9.0** to upgrade to the active version of the SDK, or **gem update plivo** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Importing the SDK
```ruby Legacy theme={null}
require 'plivo'
```
```ruby Latest theme={null}
require 'plivo'
```
### Initialize
```ruby Legacy theme={null}
p = RestAPI.new("","")
```
```ruby Latest theme={null}
api = RestClient.new("","")
```
### Access Resources
```ruby Legacy theme={null}
response = p.make_call(params)
```
```ruby Latest theme={null}
response = api.calls.create(params)
```
### Make a call
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
AUTH_ID = ""
AUTH_TOKEN = ""
p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
params = {
'to' => '12025552323',
'from' => '12025551212',
'answer_url' => 'https://s3.amazonaws.com/static.plivo.com/answer.xml',
'answer_method' => 'GET'
}
response = p.make_call(params)
print response
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'+12025551212',
['+12025552323'],
'https://s3.amazonaws.com/static.plivo.com/answer.xml'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
### Dial XML
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
response = Response.new()
params = {
'dialMusic' => "https://.com/dial_music/"
}
dial = response.addDial(params)
first_number = "12025552323"
dial.addNumber(first_number)
puts response.to_xml()
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
'dialMusic' => "https://.com/dial_music/"
}
dial = response.addDial(params)
first_number = "12025552323"
dial.addNumber(first_number)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
### Conference XML
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
response = Response.new()
params = {
'startConferenceOnEnter' => "false",
'waitSound' => "https://.com/waitmusic/"
}
conference_name = "My Room"
response.addConference(conference_name, params)
puts response.to_xml()
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
'startConferenceOnEnter' => "false",
'waitSound' => "https://.com/waitmusic/"
}
conference_name = "My Room"
response.addConference(conference_name, params)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
### Record API
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
AUTH_ID = ""
AUTH_TOKEN = ""
p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
params = {'call_uuid' => call_uuid}
response = p.record(params)
print response
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.record(
'eba53b9e-8fbd-45c1-9444-696d2172fbc8'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
### Record XML
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
response = Response.new()
params = {
'action' => "https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
}
response.addRecord(params)
dial = response.addDial()
number = "12025552323"
dial.addNumber(number)
puts response.to_xml()
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
action: 'https://.com/get_recording/',
startOnDialAnswer: 'true',
redirect: 'false'
}
response.addRecord(params)
dial = response.addDial()
number = '12025552323'
dial.addNumber(number)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
# Upgrade from Python SDK Legacy to v4.9.0 or Latest Version
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Python SDK legacy versions lower than v4.9.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Python version support
Version 4.x of the Python SDK requires at least Python version 2.7. It will work with later versions, including Python 3.x versions.
Use the command **pip install --upgrade plivo==4.9.0** to upgrade to the active version of the SDK, or **pip install --upgrade plivo** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Importing the SDK
```py Legacy theme={null}
import plivo, plivoxml
```
```py Latest theme={null}
import plivo
from plivo import plivoxml
```
### Initializing
```py Legacy theme={null}
p = plivo.RestAPI('','')
```
```py Latest theme={null}
client = plivo.RestClient('','')
```
### Accessing resources
```py Legacy theme={null}
response = p.make_call(params)
```
```py Latest theme={null}
response = client.calls.create(params)
```
### Making a call
```py Legacy theme={null}
import plivo, plivoxml
p = plivo.RestAPI('','')
params = {
'to': '',
'from' : '',
'answer_url' : 'https://s3.amazonaws.com/static.plivo.com/answer.xml',
'answer_method' : "GET",
}
response = p.make_call(params)
print str(response)
```
```py Latest theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from_='',
to_='',
answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml',
answer_method='GET', )
print(response)
```
### Dial XML
```py Legacy theme={null}
from flask import Flask, Response, request
import plivoxml
app=Flask(__name__)
@app.route('/dial/caller_tone/', methods=['GET','POST'])
def caller_tone():
response = plivoxml.Response()
params = {
'dialMusic' : "https://.com/dial_music/"
}
Dial = response.addDial(**params)
number = ""
Dial.addNumber(number)
return Response(str(response), mimetype='text/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
```py Latest theme={null}
from flask import Flask, Response, request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/dial/caller_tone/', methods=['GET', 'POST'])
def caller_tone():
response = plivoxml.ResponseElement()
response.add(plivoxml.DialElement(dial_music='https://.com/dial_music/').add(
plivoxml.NumberElement('')))
print(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
### Conference XML
```py Legacy theme={null}
from flask import Flask, Response, request
import plivoxml
app=Flask(__name__)
@app.route('/conference/moderated/', methods=['GET','POST'])
def moderated_conference():
response = plivoxml.Response()
params = {
'startConferenceOnEnter' : "false",
'endConferenceOnExit' : "true",
'waitSound' : "https://.com/waitmusic/"
}
conference_name = "My Room"
response.addConference(conference_name, **params)
return Response(str(response), mimetype='text/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
```py Latest theme={null}
from flask import Flask, Response, request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/conference/moderated/', methods=['GET', 'POST'])
def moderated_conference():
response = plivoxml.ResponseElement()
response.add(
plivoxml.ConferenceElement(
'My Room',
start_conference_on_enter=False,
wait_sound='https://.com/waitmusic/'))
return(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
### Record API
```py Legacy theme={null}
import plivo
p = plivo.RestAPI(auth_id, auth_token)
params = {'call_uuid' : call_uuid}
response = p.record(params)
print str(response)
```
```py Latest theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.record(
call_uuid='3a2e4c90-dcee-4931-8a59-f123ab507e60', )
print(response)
```
### Record XML
```py Legacy theme={null}
from flask import Flask, Response, request
import plivoxml
app=Flask(__name__)
@app.route('/record/session/', methods=['GET','POST'])
def session():
response = plivoxml.Response()
params = {
'startOnDialAnswer' : "true",
'action' : "https://.com/get_recording/",
'redirect' : "false"
}
response.addRecord(**params)
dial = response.addDial()
dial.addNumber("")
return Response(str(response), mimetype='text/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
```py Latest theme={null}
from flask import Flask, Response, request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/record/session/', methods=['GET', 'POST'])
def session():
response = plivoxml.ResponseElement()
response.add(
plivoxml.RecordElement(
action='https://.com/get_recording/',
start_on_dial_answer=True,
redirect=False))
response.add(plivoxml.DialElement().add(plivoxml.NumberElement('')))
return(response.to_string())
```
# Upgrade from PHP SDK Legacy to v4.25.0 or Latest Version
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo PHP SDK legacy versions lower than 4.25.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### PHP version support
The 4.x version of the Plivo SDK is compatible with PHP versions 7.3 and higher.
Use the command **composer require plivo/plivo-php:4.25.0** to upgrade to the active version of the SDK, or **composer require plivo/plivo-php** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```php Legacy theme={null}
### Initialize
```php Legacy theme={null}
$p = new RestAPI($auth_id, $auth_token);
```
```php Latest theme={null}
$client = new RestClient("","");
```
### Access resources
```php Legacy theme={null}
$response = $p->make_call($params);
```
```php Latest theme={null}
$response = $client->calls->create($params);
```
### Make a call
```php Legacy theme={null}
";
$auth_token = "";
$p = new RestAPI($auth_id, $auth_token);
$params = array(
'to' => '2025552323',
'from' => '2025551212',
'answer_url' => "https://s3.amazonaws.com/static.plivo.com/answer.xml",
'answer_method' => "GET"
);
$response = $p->make_call($params);
print_r ($response);
```
```php Latest theme={null}
","");
try {
$response = $client->calls->create(
'+12025551212',
['+12025552323'],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',
);
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
### Dial XML
```php Legacy theme={null}
"https://.com/dial_music/"
);
$dial = $response->addDial($params);
$number = "12025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
```php Latest theme={null}
"https://.com/dial_music/"
);
$dial = $response->addDial($params);
$number = "12025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
### Conference XML
```php Legacy theme={null}
"false",
'waitSound' => "https://.com/waitmusic/"
);
$conference_name = "My Room";
$response->addConference($conference_name, $params);
Header('Content-type: text/xml');
echo($response->toXML());
```
```php Latest theme={null}
"false",
'waitSound' => "https://.com/waitmusic/"
);
$conference_name = "My Room";
$response->addConference($conference_name, $params);
Header('Content-type: text/xml');
echo($response->toXML());
```
### Record API
```php Legacy theme={null}
";
$auth_token = "";
$p = new RestAPI($auth_id, $auth_token);
$params = array('call_uuid' => $uuid);
$response = $p->record($params);
print("URL : {$response['response']['url']}");
```
```php Latest theme={null}
","");
try {
$response = $client->calls->startRecording(
'eba53b9e-8fbd-45c1-9444-696d2172fbc8'
);
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
### Record XML
```php Legacy theme={null}
"https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
);
$response->addRecord($params);
$dial = $response->addDial();
$number = "2025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
```php Latest theme={null}
"https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
);
$response->addRecord($params);
$dial = $response->addDial();
$number = "2025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
# Upgrade from .NET SDK Legacy to v4.10.0 or Latest Version
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: Plivo .NET SDK legacy versions lower than v4.10.0 are being deprecated on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### .NET version support
The Plivo .NET SDK supports .NET applications written in C# and Visual Basic that utilize the .NET Framework version 3.5 or higher or any .NET runtime supporting [.NET Standard](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) v1.4.
Use the command **Update-Package Plivo -Version 4.10.0** to upgrade to the active version of the SDK, or **Update-Package Plivo** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using RestSharp;
using Plivo.API;
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
```
### Initialize
```csharp Legacy theme={null}
RestAPI plivo = new RestAPI("","");
```
```csharp Latest theme={null}
var api = new PlivoApi("","");
```
### Access resources
```csharp Legacy theme={null}
IRestResponse resp = plivo.make_call(new Dictionary()
{params});
```
```csharp Latest theme={null}
var response = api.Call.Create(params);
```
### Make a call
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using RestSharp;
using Plivo.API;
namespace make_calls
{
class Program
{
static void Main(string[] args)
{
RestAPI plivo = new RestAPI("", "");
IRestResponse resp = plivo.make_call(new Dictionary()
{
{ "from", "2025551212" },
{ "to", "2025552323" },
{ "answer_url", "https://s3.amazonaws.com/static.plivo.com/answer.xml" },
{ "answer_method","GET"},
});
Console.Write(resp.Content);
Console.ReadLine();
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("", "");
try
{
var response = api.Call.Create(
to: new List { "+12025552323" },
from: "+12025551212",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/answer.xml"
);
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
### Dial XML
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {
{"dialMusic", "https://.com/dial_music/"}
});
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {
{"dialMusic", "https://.com/dial_music/"}
});
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
### Conference XML
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddConference("My room",
new Dictionary()
{
{"startConferenceOnEnter", "true"},
{"endConferenceOnExit", "true"},
{"waitSound", "https://.com/waitmusic/"}
});
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddConference("My room",
new Dictionary()
{
{"startConferenceOnEnter", "true"},
{"endConferenceOnExit", "true"},
{"waitSound", "https://.com/waitmusic/"}
});
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
### Record API
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using RestSharp;
using Plivo.API;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
string auth_id = "";
string auth_token = "";
RestAPI plivo = new RestAPI(auth_id, auth_token);
IRestResponse resp = plivo.record(new Dictionary()
{
{ "call_uuid", uuid } // ID of the call
});
Debug.WriteLine(resp.Content);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("","");
try
{
var response = api.Call.StartRecording(
callUuid:"10c94053-73b4-46fe-b74a-12159d1d3d60"
);
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
### Record XML
```csharp Legacy theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddRecord(new Dictionary() {
{"action", "https://.com/get_recording/"},
{"startOnDialAnswer", "true"},
{"redirect", "false"}
});
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary()
{ });
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
```csharp Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo
{
class MainClass
{
public static void Main(string[] args)
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddRecord(new Dictionary() {
{"action", "https://.com/get_recording/"},
{"startOnDialAnswer", "true"},
{"redirect", "false"}
});
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary()
{ });
dial.AddNumber("12025552323",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
# Upgrade from Java Legacy to v4.8.0 or Latest Version
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Java SDK legacy versions lower than v4.8.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Java version support
The Plivo Java SDK supports OpenJDK 8 and 11 and OracleJDK 8 and 11.
Use the command `Update-Package Plivo -Version 4.10.0` to upgrade to the active version of the SDK, or upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```java Legacy theme={null}
import com.plivo.helper.api.client.*;
import com.plivo.helper.xml.elements.Dial;
```
```java Latest theme={null}
import com.plivo.api.Plivo;
import com.plivo.api.xml.Dial;
```
### Initialize
```java Legacy theme={null}
RestAPI api = new RestAPI("","", "v1");
```
```java Latest theme={null}
Plivo.init("","");
```
### Accessing resources
```java Legacy theme={null}
Call resp = api.makeCall(parameters);
```
```java Latest theme={null}
CallCreateResponse response = Call.creator(parameters)
.create();
```
### Make a call
```java Legacy theme={null}
package com.plivo.test;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import com.plivo.helper.api.client.*;
import com.plivo.helper.api.response.call.Call;
import com.plivo.helper.exception.PlivoException;
public class App {
public static void main(String[] args) throws IllegalAccessException {
String auth_id = "";
String auth_token = "";
RestAPI api = new RestAPI(auth_id, auth_token, "v1");
LinkedHashMap parameters = new LinkedHashMap();
parameters.put("to","2025552323");
parameters.put("from","2025551212");
parameters.put("answer_url","https://s3.amazonaws.com/static.plivo.com/answer.xml");
parameters.put("answer_method","GET");
try {
Call resp = api.makeCall(parameters);
System.out.println(resp);
} catch (PlivoException e) {
System.out.println(e.getLocalizedMessage());
}
}
}
```
```java Latest theme={null}
using System;
using System.Collections.Generic;
using Plivo;
package com.plivo.api.samples.call;
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class CallCreate {
public static void main(String [] args) {
Plivo.init("","");
try {
CallCreateResponse response = Call.creator("+12025551212", Collections.singletonList("+12025552323"), "https://s3.amazonaws.com/static.plivo.com/answer.xml")
.answerMethod("GET")
.create();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
### Dial XML
```java Legacy theme={null}
import java.io.IOException;
import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Number;
import com.plivo.helper.xml.elements.Dial;
import com.plivo.helper.xml.elements.PlivoResponse;
class CustomCallerTone {
public static void main(String[] args) throws PlivoXmlException {
PlivoResponse response = new PlivoResponse();
Dial dial = new Dial();
dial.setDialMusic("https://.com/dial_music/");
Number number = new Number("12025552323");
response.append(dial);
dial.append(number);
System.out.println(response.toXML());
resp.addHeader("Content-Type", "text/xml");
resp.getWriter().print(response.toXML());;
}
}
```
```java Latest theme={null}
package com.plivo.api.xml.samples.dial;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Response;
class CustomCallerTone {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Dial()
.dialMusic("https://.com/dial_music/")
.children(
new Number("12025552323")
)
);
System.out.println(response.toXmlString());
}
}
```
### Conference XML
```java Legacy theme={null}
import java.io.IOException;
import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Conference;
import com.plivo.helper.xml.elements.PlivoResponse;
class ModeratedConference {
public static void main(String[] args) throws PlivoException {
PlivoResponse response = new PlivoResponse();
Conference conference = new Conference("My Room");
conference.setEnterSound("");
conference.setStartConferenceOnEnter(true);
conference.setEndConferenceOnExit(true);
conference.setWaitSound("https://.com/music/");
response.append(conference);
System.out.println(response.toXML());
resp.addHeader("Content-Type", "text/xml");
resp.getWriter().print(response.toXML());;
}
}
```
```java Latest theme={null}
package com.plivo.api.xml.samples.conference;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Conference;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
class ModeratedConference {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Speak("You will now be placed into a demo conference"),
new Conference("demo")
.endConferenceOnExit(true)
.startConferenceOnEnter(false)
.waitSound("https://.com/waitmusic/")
);
System.out.println(response.toXmlString());
}
}
```
### Record API
```java Legacy theme={null}
package plivoexample;
import java.io.IOException;
import java.util.LinkedHashMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.plivo.helper.api.client.RestAPI;
import com.plivo.helper.api.response.response.Record;
import com.plivo.helper.exception.PlivoException;
class recordApiAction {
public static void main(String[] args) throws PlivoException {
String auth_id = "";
String auth_token = "";
RestAPI api = new RestAPI(auth_Id, auth_Token, "v1");
LinkedHashMap parameters = new LinkedHashMap();
parameters.put("call_uuid",call_uuid);
Record record = api.record(parameters);
System.out.println(record);
}
}
```
```java Latest theme={null}
package com.plivo.api.samples.call.record;
import java.io.IOException;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.actions.CallRecordCreateResponse;
class RecordCreate {
public static void main(String [] args) {
Plivo.init("","");
try {
CallRecordCreateResponse response = Call.recorder("eba53b9e-8fbd-45c1-9444-696d2172fbc8")
.record();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
### Record XML
```java Legacy theme={null}
import java.io.IOException;
import com.plivo.helper.exception.PlivoException;
import com.plivo.helper.xml.elements.Record;
import com.plivo.helper.xml.elements.Dial;
import com.plivo.helper.xml.elements.Number;
import com.plivo.helper.xml.elements.PlivoResponse;
class recordSession {
public static void main(String[] args) throws PlivoException {
response.append(record);
response.append(dial);
dial.append(number);
System.out.println(response.toXML());
resp.addHeader("Content-Type", "text/xml");
resp.getWriter().print(response.toXML());;
}
}
```
```java Latest theme={null}
package com.plivo.api.xml.samples.record;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Record;
import com.plivo.api.xml.Response;
class RecordACompleteCallSession {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Record("https://.com/get_recording/")
.redirect(false)
.startOnDialAnswer(true),
new Dial()
.children(
new Number("12025552323")
)
);
System.out.println(response.toXmlString());
}
}
```
# Upgrade from PHP SDK Legacy to v4.25.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/legacy-to-active-sdk/php
Migrate from legacy PHP SDK to v4.25.0+ — code changes required
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo PHP SDK legacy versions lower than 4.25.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### PHP version support
The 4.x version of the Plivo SDK is compatible with PHP versions 7.3 and higher.
Use the command **composer require plivo/plivo-php:4.25.0** to upgrade to the active version of the SDK, or **composer require plivo/plivo-php** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Import the SDK
```php Legacy theme={null}
### Initialize
```php Legacy theme={null}
$p = new RestAPI($auth_id, $auth_token);
```
```php Latest theme={null}
$client = new RestClient("","");
```
### Access resources
```php Legacy theme={null}
$response = $p->make_call($params);
```
```php Latest theme={null}
$response = $client->calls->create($params);
```
### Make a call
```php Legacy theme={null}
";
$auth_token = "";
$p = new RestAPI($auth_id, $auth_token);
$params = array(
'to' => '2025552323',
'from' => '2025551212',
'answer_url' => "https://s3.amazonaws.com/static.plivo.com/answer.xml",
'answer_method' => "GET"
);
$response = $p->make_call($params);
print_r ($response);
```
```php Latest theme={null}
","");
try {
$response = $client->calls->create(
'+12025551212',
['+12025552323'],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',
);
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
### Dial XML
```php Legacy theme={null}
"https://.com/dial_music/"
);
$dial = $response->addDial($params);
$number = "12025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
```php Latest theme={null}
"https://.com/dial_music/"
);
$dial = $response->addDial($params);
$number = "12025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
### Conference XML
```php Legacy theme={null}
"false",
'waitSound' => "https://.com/waitmusic/"
);
$conference_name = "My Room";
$response->addConference($conference_name, $params);
Header('Content-type: text/xml');
echo($response->toXML());
```
```php Latest theme={null}
"false",
'waitSound' => "https://.com/waitmusic/"
);
$conference_name = "My Room";
$response->addConference($conference_name, $params);
Header('Content-type: text/xml');
echo($response->toXML());
```
### Record API
```php Legacy theme={null}
";
$auth_token = "";
$p = new RestAPI($auth_id, $auth_token);
$params = array('call_uuid' => $uuid);
$response = $p->record($params);
print("URL : {$response['response']['url']}");
```
```php Latest theme={null}
","");
try {
$response = $client->calls->startRecording(
'eba53b9e-8fbd-45c1-9444-696d2172fbc8'
);
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
### Record XML
```php Legacy theme={null}
"https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
);
$response->addRecord($params);
$dial = $response->addDial();
$number = "2025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
```php Latest theme={null}
"https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
);
$response->addRecord($params);
$dial = $response->addDial();
$number = "2025552323";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo($response->toXML());
```
# Upgrade from Python SDK Legacy to v4.9.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/legacy-to-active-sdk/python
Migrate from legacy Python SDK to v4.9.0+ — code changes required
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Python SDK legacy versions lower than v4.9.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Python version support
Version 4.x of the Python SDK requires at least Python version 2.7. It will work with later versions, including Python 3.x versions.
Use the command **pip install --upgrade plivo==4.9.0** to upgrade to the active version of the SDK, or **pip install --upgrade plivo** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Importing the SDK
```py Legacy theme={null}
import plivo, plivoxml
```
```py Latest theme={null}
import plivo
from plivo import plivoxml
```
### Initializing
```py Legacy theme={null}
p = plivo.RestAPI('','')
```
```py Latest theme={null}
client = plivo.RestClient('','')
```
### Accessing resources
```py Legacy theme={null}
response = p.make_call(params)
```
```py Latest theme={null}
response = client.calls.create(params)
```
### Making a call
```py Legacy theme={null}
import plivo, plivoxml
p = plivo.RestAPI('','')
params = {
'to': '',
'from' : '',
'answer_url' : 'https://s3.amazonaws.com/static.plivo.com/answer.xml',
'answer_method' : "GET",
}
response = p.make_call(params)
print str(response)
```
```py Latest theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from_='',
to_='',
answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml',
answer_method='GET', )
print(response)
```
### Dial XML
```py Legacy theme={null}
from flask import Flask, Response, request
import plivoxml
app=Flask(__name__)
@app.route('/dial/caller_tone/', methods=['GET','POST'])
def caller_tone():
response = plivoxml.Response()
params = {
'dialMusic' : "https://.com/dial_music/"
}
Dial = response.addDial(**params)
number = ""
Dial.addNumber(number)
return Response(str(response), mimetype='text/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
```py Latest theme={null}
from flask import Flask, Response, request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/dial/caller_tone/', methods=['GET', 'POST'])
def caller_tone():
response = plivoxml.ResponseElement()
response.add(plivoxml.DialElement(dial_music='https://.com/dial_music/').add(
plivoxml.NumberElement('')))
print(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
### Conference XML
```py Legacy theme={null}
from flask import Flask, Response, request
import plivoxml
app=Flask(__name__)
@app.route('/conference/moderated/', methods=['GET','POST'])
def moderated_conference():
response = plivoxml.Response()
params = {
'startConferenceOnEnter' : "false",
'endConferenceOnExit' : "true",
'waitSound' : "https://.com/waitmusic/"
}
conference_name = "My Room"
response.addConference(conference_name, **params)
return Response(str(response), mimetype='text/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
```py Latest theme={null}
from flask import Flask, Response, request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/conference/moderated/', methods=['GET', 'POST'])
def moderated_conference():
response = plivoxml.ResponseElement()
response.add(
plivoxml.ConferenceElement(
'My Room',
start_conference_on_enter=False,
wait_sound='https://.com/waitmusic/'))
return(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
### Record API
```py Legacy theme={null}
import plivo
p = plivo.RestAPI(auth_id, auth_token)
params = {'call_uuid' : call_uuid}
response = p.record(params)
print str(response)
```
```py Latest theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.record(
call_uuid='3a2e4c90-dcee-4931-8a59-f123ab507e60', )
print(response)
```
### Record XML
```py Legacy theme={null}
from flask import Flask, Response, request
import plivoxml
app=Flask(__name__)
@app.route('/record/session/', methods=['GET','POST'])
def session():
response = plivoxml.Response()
params = {
'startOnDialAnswer' : "true",
'action' : "https://.com/get_recording/",
'redirect' : "false"
}
response.addRecord(**params)
dial = response.addDial()
dial.addNumber("")
return Response(str(response), mimetype='text/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
```py Latest theme={null}
from flask import Flask, Response, request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/record/session/', methods=['GET', 'POST'])
def session():
response = plivoxml.ResponseElement()
response.add(
plivoxml.RecordElement(
action='https://.com/get_recording/',
start_on_dial_answer=True,
redirect=False))
response.add(plivoxml.DialElement().add(plivoxml.NumberElement('')))
return(response.to_string())
```
# Upgrade from Ruby Legacy to v4.9.0 or Latest Version
Source: https://plivo.com/docs/voice/migrate/sdk/legacy-to-active-sdk/ruby
Migrate from legacy Ruby SDK to v4.9.0+ — code changes required
## Introduction
This is a major application update. Plivo recommends you always use the latest or an active version of our SDKs for guaranteed security, stability, and uptime. The active SDK versions are designed to handle intermittent and regional failures of API requests. In addition, they offer a host of security features, such as protection against DoS attacks and bot detection for suspicious user agents.
Deprecation notice: We’re deprecating Plivo Ruby SDK legacy versions lower than v4.9.0 on January 31, 2022. If you use a deprecated version of our SDK after that date, your API requests and voice calls may fail intermittently. Plivo will no longer provide bug fixes to these versions, and our support team may ask you to upgrade before debugging issues.
## Migrate your applications
### Ruby version support
The Plivo Ruby SDK supports Ruby 2.0 and above.
Use the command **gem install plivo -v 4.9.0** to upgrade to the active version of the SDK, or **gem update plivo** to upgrade to the latest version.
After you upgrade to the latest version of the SDK, you should check every program that depends on it and make changes to the syntax for several kinds of operations. Here are examples of how coding differs between the deprecated legacy version of the SDK and the latest active versions.
### Importing the SDK
```ruby Legacy theme={null}
require 'plivo'
```
```ruby Latest theme={null}
require 'plivo'
```
### Initialize
```ruby Legacy theme={null}
p = RestAPI.new("","")
```
```ruby Latest theme={null}
api = RestClient.new("","")
```
### Access Resources
```ruby Legacy theme={null}
response = p.make_call(params)
```
```ruby Latest theme={null}
response = api.calls.create(params)
```
### Make a call
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
AUTH_ID = ""
AUTH_TOKEN = ""
p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
params = {
'to' => '12025552323',
'from' => '12025551212',
'answer_url' => 'https://s3.amazonaws.com/static.plivo.com/answer.xml',
'answer_method' => 'GET'
}
response = p.make_call(params)
print response
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'+12025551212',
['+12025552323'],
'https://s3.amazonaws.com/static.plivo.com/answer.xml'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
### Dial XML
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
response = Response.new()
params = {
'dialMusic' => "https://.com/dial_music/"
}
dial = response.addDial(params)
first_number = "12025552323"
dial.addNumber(first_number)
puts response.to_xml()
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
'dialMusic' => "https://.com/dial_music/"
}
dial = response.addDial(params)
first_number = "12025552323"
dial.addNumber(first_number)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
### Conference XML
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
response = Response.new()
params = {
'startConferenceOnEnter' => "false",
'waitSound' => "https://.com/waitmusic/"
}
conference_name = "My Room"
response.addConference(conference_name, params)
puts response.to_xml()
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
'startConferenceOnEnter' => "false",
'waitSound' => "https://.com/waitmusic/"
}
conference_name = "My Room"
response.addConference(conference_name, params)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
### Record API
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
AUTH_ID = ""
AUTH_TOKEN = ""
p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
params = {'call_uuid' => call_uuid}
response = p.record(params)
print response
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.record(
'eba53b9e-8fbd-45c1-9444-696d2172fbc8'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
### Record XML
```ruby Legacy theme={null}
require 'rubygems'
require 'plivo'
include Plivo
response = Response.new()
params = {
'action' => "https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
}
response.addRecord(params)
dial = response.addDial()
number = "12025552323"
dial.addNumber(number)
puts response.to_xml()
```
```ruby Latest theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
action: 'https://.com/get_recording/',
startOnDialAnswer: 'true',
redirect: 'false'
}
response.addRecord(params)
dial = response.addDial()
number = '12025552323'
dial.addNumber(number)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
# Technical Guide: Migrating from Twilio to Plivo
Source: https://plivo.com/docs/voice/migrate/twilio
Migrate your voice app from Twilio to Plivo — API comparison guide
## Introduction
Migrating from Twilio to Plivo is a painless process. The two companies’ API structures, implementation mechanisms, XML structure, SMS message processing, and voice call processing are similar. We wrote this technical comparison between Twilio and Plivo APIs so that you can scope the code changes for a seamless migration.
## Understanding the differences between Twilio and Plivo development
Most of the APIs and features that are available on Twilio are also available on Plivo, and the implementation mechanism is easier as the steps involved are almost identical. This table gives a side-by-side comparison of the two companies’ features and APIs. An added advantage with Plivo is that not only can you code using the familiar API/XML coding method, you can also implement your use cases using (Plivo High Level Objects), a visual workflow builder that lets you create workflows by dragging and dropping components onto a canvas — no coding required.
| **Features and APIs** | **Twilio** | **Plivo** | **Similarities** | **Implementation Interface** |
| ------------------------------------------------------------------------------------------------- | ---------- | --------- | ----------------------------------------- | -------------------------------------------------------- |
| [Voice API](/docs/voice/): Make phone calls | ✅ | ✅ | Request and response variables’ structure | API
PHLO
|
| [Programmatically manage call flows](/docs/voice/concepts/overview#controlling-calls-programmatically) | Twiml | Plivo XML | XML element and its attributes structure | XML
PHLO
|
| [Geo Permissions](/docs/voice/concepts/geo-permissions/) | ✅ | ✅ | Feature parity | Console |
| [Number Lookup API](/docs/lookup/) | ✅ | ✅ | API Parity | API |
| [Phone number management](/docs/numbers/api-overview) | ✅ | ✅ | Feature parity | API
Console
|
| [Call Insights](/docs/voice/call-insights/) | ✅ | ✅ | Feature parity | Console |
| [Validating Requests](/docs/voice/concepts/signature-validation) | ✅ | ✅ | Feature parity | API
XML
|
| Subaccounts | ✅ | ✅ | Feature parity | API |
| [Speech recognition](/docs/voice/use-cases/receive-input#detect-speech-input) | ✅ | ✅ | Feature parity | XML |
| [SSML](/docs/voice/concepts/ssml/) (Speech Synthesis Markup Language) | ✅ | ✅ | Feature parity | XML
PHLO
|
| [Browser](/docs/sdk/client/browser/overview)SDKs | ✅ | ✅ | Feature parity | [Browser](/docs/sdk/client/browser/overview) |
| [Transcription](/docs/voice/xml/record) | ✅ | ✅ | Feature parity | API
XML
PHLO
|
| [Custom SIP Headers](/docs/voice/use-cases/pass-custom-headers) | ✅ | ✅ | Feature parity | API
XML
PHLO
Browser SDK
Mobile SDKs |
| [HTTP callbacks](/docs/voice/concepts/callbacks/) | ✅ | ✅ | Feature parity | API
XML
PHLO
|
## Create a Plivo account
Start by [signing up for a free trial account](https://cx.plivo.com/signup) that you can use to experiment with and learn about our services. The free trial account comes with free credits, and you can [add more](https://cx.plivo.com/billing/payment-methods) as you go along. You can also [add a phone number](https://cx.plivo.com/phone-numbers) to your account, or [port a number from Twilio to Plivo](/docs/numbers/number-porting/), to start testing the full range of our voice and SMS features. See our [Account Management FAQ](/docs/faq/account/account-management) for details on the signup process.
## Migrate your voice application
To migrate an existing application from Twilio to Plivo using APIs, follow the [Voice API quickstart](/docs/voice/quickstart/quickstart), which covers all seven languages Plivo provides SDKs for: PHP, Node.js, C# (.NET), Java, Python, Ruby, and Go. For another alternative that lets you evaluate Plivo’s voice APIs and their request and response structure, use our [Postman collection](/docs/faq/developer-tools/postman).
### How to make an outbound call
Let’s take a look at the process of refactoring the code to migrate your app from Twilio to Plivo to set up a simple Python application to make an outbound call by changing just a few lines of code.
```py Twilio theme={null}
import os
from twilio.rest import Client
account_sid = os.environ[""]
auth_token = os.environ[""]
client = Client(account_sid, auth_token)
call = client.calls.create(
to='+14155551212',
from_='+14165553434',
url='https://demo.twilio.com/docs/voice.xml'
)
print(call)
```
```py Plivo theme={null}
import os, plivo
auth_id = os.environ[""]
auth_token = os.environ[""]
client = plivo.RestClient(auth_id, auth_token)
call = client.calls.create(
to_='+14155551212',
from_='+14165553434',
answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml',
)
print(call)
```
Replace the authentication placeholders with authentication credentials from the Twilio or [Plivo console](https://cx.plivo.com/home).
Alternatively, you can implement the same functionality using one of our [PHLO templates](https://cx.plivo.com/agents). To make an outbound call, you can create a PHLO like this:
### How to receive an incoming call
You can migrate an application for receiving and handling an incoming call from Twilio to Plivo just as seamlessly, as in this example:
```py Twilio theme={null}
from flask import Flask
from twilio.twiml.voice_response import VoiceResponse
app = Flask(__name__)
@app.route("/receive_call", methods=['GET', 'POST'])
def receive_call():
"""Respond to incoming phone calls with a 'Hello world' message"""
# Start our TwiML response
resp = VoiceResponse()
# Read a message aloud to the caller
resp.say("Hello, world!", voice='alice')
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
```
```py Plivo theme={null}
from flask import Flask, request, make_response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/receive_call', methods=['GET','POST'])
def receive_call():
# Generate a Speak XML element with the details of the text to play on the call
response = (plivoxml.ResponseElement()
.add(plivoxml.SpeakElement('Hello, world!')))
return(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
Here again you can implement the same functionality using one of our [PHLO templates](https://cx.plivo.com/agents):
### How to forward an incoming call
You can migrate an application for forwarding an incoming call from Twilio to Plivo as in this example:
```py Twilio theme={null}
from flask import Flask
from twilio.twiml.voice_response import Dial, VoiceResponse, Say
app = Flask(__name__)
@app.route("/forward_call", methods=['GET', 'POST'])
def forwardcall():
"""Forward incoming phone call to connect the caller to another party"""
# Start our TwiML response
response = VoiceResponse()
# Dial verb to forward the call
response.dial('202-555-1234')
response.say('Goodbye')
return str(response)
if __name__ == "__main__":
app.run(debug=True)
```
```py Plivo theme={null}
from flask import Flask, request, make_response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/receive_call', methods=['GET','POST'])
def receive_call():
# Generate a Speak XML element with the details of the text to play on the call
response = (plivoxml.ResponseElement()
.add(plivoxml.SpeakElement('Hello, world!')))
return(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
Here again you can implement the same functionality using one of our [PHLO templates](https://cx.plivo.com/agents):
For more information about migrating your voice applications to Plivo, check out our [detailed use case guides](/docs/voice/use-cases/make-outbound-calls), available for all seven programming languages and PHLO.
### More use cases
You can migrate applications that serve other use cases too:
* [Phone system IVR — Touch-Tone/DTMF-based virtual assistant](/docs/voice/use-cases/ivr#node)
* [Voice-controlled virtual assistant](/docs/voice/use-cases/receive-input#detect-speech-input)
* [Number masking](/docs/voice/use-cases/number-masking)
* [Supervisor coaching](/docs/voice/use-cases/supervisor-coaching)
* [PINless conference](/docs/voice/use-cases/call-conference#node)
* [Conference with PIN](/docs/voice/use-cases/conference-with-pin#node)
* [Voicemail](/docs/voice/use-cases/voicemail#node)
* [Voice alerts broadcasting](/docs/voice/use-cases/voice-broadcasting#node)
* [Voice survey](/docs/voice/use-cases/voice-survey#node)
* [Dial status reporting](/docs/voice/use-cases/dial-status-reporting#node)
* [Screen incoming calls](/docs/voice/use-cases/screen-incoming-calls#node)
* [Record a call](/docs/voice/use-cases/screen-incoming-calls#node)
## Port your existing numbers from Twilio to Plivo
If you want to continue using your phone numbers from Twilio, you can port the numbers to Plivo without having any downtime on your services for your customers. Phone number porting must be requested by a phone number’s owner. Here’s an overview of the process for porting a phone number to Plivo:
1. Phone number’s owner submits porting request with documentation.
2. Plivo verifies the porting request.
3. Plivo submits porting request to the gaining carrier.
4. The gaining carrier submits porting request to the losing carrier.
5. The losing carrier responds with an approval or a rejection.
6. Plivo notifies phone number owner of Firm Order Commitment or porting date.
You can check our [number porting guide](/docs/numbers/number-porting/) to initiate the process.
## Rent new phone numbers for your migrated app
You can rent new phone numbers on the Plivo platform for your migrated applications as well. Plivo provides a self-serve [console](https://cx.plivo.com/phone-numbers) to rent new numbers and to manage them. You can also use the [Phone Numbers API](/docs/numbers/api-overview) for number management. Our [Phone Numbers quickstart guide](/docs/numbers/phone-numbers) provides more information.
# Voice API Quickstart
Source: https://plivo.com/docs/voice/quickstart/quickstart
Make your first outbound call and handle incoming calls with Plivo's Voice API
Get started with Plivo Voice in minutes. This guide walks you through making your first outbound call and receiving incoming calls.
## Prerequisites
Before you begin:
1. [Sign up for a Plivo account](https://cx.plivo.com/signup) (free trial includes credits)
2. Note your **Auth ID** and **Auth Token** from the [console dashboard](https://cx.plivo.com/home)
3. [Rent a phone number](https://cx.plivo.com/phone-numbers) for receiving calls
***
## Install the SDK
```bash theme={null}
pip install plivo
```
For web framework support, also install Flask:
```bash theme={null}
pip install flask
```
```bash theme={null}
npm install plivo
```
For web server support, also install Express:
```bash theme={null}
npm install express
```
```bash theme={null}
gem install plivo sinatra
```
```bash theme={null}
composer require plivo/plivo-php
```
Add to your `pom.xml`:
```xml theme={null}
com.plivo
plivo-java
5.9.0
```
```bash theme={null}
dotnet add package Plivo
```
```bash theme={null}
go get github.com/plivo/plivo-go/v7
```
***
## Make an Outbound Call
Create a call from your Plivo number to any phone number. When the call is answered, Plivo fetches XML instructions from your `answer_url`.
```python theme={null}
import plivo
client = plivo.RestClient('', '')
response = client.calls.create(
from_='+14151234567', # Your Plivo number
to_='+14157654321', # Destination number
answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml',
answer_method='GET'
)
print(response)
```
```javascript theme={null}
const plivo = require('plivo');
const client = new plivo.Client('', '');
client.calls.create(
'+14151234567', // from
'+14157654321', // to
'https://s3.amazonaws.com/static.plivo.com/answer.xml', // answer_url
{ answerMethod: 'GET' }
).then(console.log);
```
```ruby theme={null}
require 'plivo'
api = Plivo::RestClient.new('', '')
response = api.calls.create(
'+14151234567', # from
['+14157654321'], # to
'https://s3.amazonaws.com/static.plivo.com/answer.xml', # answer_url
'GET' # answer_method
)
puts response
```
```php theme={null}
', '');
$response = $client->calls->create(
'+14151234567', // from
['+14157654321'], // to
'https://s3.amazonaws.com/static.plivo.com/answer.xml', // answer_url
['answerMethod' => 'GET']
);
print_r($response);
```
```java theme={null}
import com.plivo.api.Plivo;
import com.plivo.api.models.call.Call;
public class MakeCall {
public static void main(String[] args) {
Plivo.init("", "");
Call.creator("+14151234567", "+14157654321",
"https://s3.amazonaws.com/static.plivo.com/answer.xml")
.answerMethod("GET")
.create();
}
}
```
```csharp theme={null}
using Plivo;
var api = new PlivoApi("", "");
var response = api.Call.Create(
from: "+14151234567",
to: new[] { "+14157654321" },
answerUrl: "https://s3.amazonaws.com/static.plivo.com/answer.xml",
answerMethod: "GET"
);
Console.WriteLine(response);
```
```go theme={null}
package main
import "github.com/plivo/plivo-go/v7"
func main() {
client, _ := plivo.NewClient("", "", &plivo.ClientOptions{})
client.Calls.Create(plivo.CallCreateParams{
From: "+14151234567",
To: "+14157654321",
AnswerURL: "https://s3.amazonaws.com/static.plivo.com/answer.xml",
AnswerMethod: "GET",
})
}
```
```bash theme={null}
curl -i --user AUTH_ID:AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"from": "+14151234567",
"to": "+14157654321",
"answer_url": "https://s3.amazonaws.com/static.plivo.com/answer.xml",
"answer_method": "GET"
}' \
https://api.plivo.com/v1/Account/{auth_id}/Call/
```
The sample `answer.xml` file plays a message:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
Replace this URL with your own server endpoint to control call behavior dynamically.
***
## Receive an Incoming Call
Set up a web server to handle incoming calls. When someone calls your Plivo number, Plivo sends a request to your Answer URL and executes the XML instructions you return.
```python theme={null}
from flask import Flask, Response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/answer/', methods=['GET', 'POST'])
def answer_call():
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Hello! Thanks for calling.'))
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
```
Run: `python app.py`
```javascript theme={null}
const express = require('express');
const plivo = require('plivo');
const app = express();
app.all('/answer/', (req, res) => {
const response = plivo.Response();
response.addSpeak('Hello! Thanks for calling.');
res.set('Content-Type', 'application/xml');
res.send(response.toXML());
});
app.listen(5000, () => console.log('Server running on port 5000'));
```
Run: `node app.js`
```ruby theme={null}
require 'sinatra'
require 'plivo'
get '/answer/' do
response = Plivo::XML::Response.new
response.addSpeak('Hello! Thanks for calling.')
content_type 'application/xml'
response.to_xml
end
```
Run: `ruby app.rb`
```php theme={null}
addSpeak('Hello! Thanks for calling.');
header('Content-Type: application/xml');
echo $response->toXML();
```
```java theme={null}
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
import static spark.Spark.*;
public class ReceiveCall {
public static void main(String[] args) {
get("/answer/", (req, res) -> {
res.type("application/xml");
return new Response()
.children(new Speak("Hello! Thanks for calling."))
.toXmlString();
});
}
}
```
```csharp theme={null}
using Microsoft.AspNetCore.Mvc;
using Plivo.XML;
[ApiController]
[Route("[controller]")]
public class AnswerController : ControllerBase
{
[HttpGet]
[HttpPost]
public ContentResult Answer()
{
var response = new Response();
response.AddSpeak("Hello! Thanks for calling.");
return Content(response.ToString(), "application/xml");
}
}
```
```go theme={null}
package main
import (
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
http.HandleFunc("/answer/", func(w http.ResponseWriter, r *http.Request) {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).SetContents("Hello! Thanks for calling."),
},
}
w.Header().Set("Content-Type", "application/xml")
w.Write([]byte(response.String()))
})
http.ListenAndServe(":5000", nil)
}
```
Run: `go run main.go`
### Expose Your Server
Use [ngrok](https://ngrok.com) to expose your local server to the internet:
```bash theme={null}
ngrok http 5000
```
Copy the HTTPS forwarding URL (e.g., `https://abc123.ngrok.io`).
### Configure Your Number
1. Go to [Voice Applications](https://cx.plivo.com/xml-applications) in the Plivo console
2. Click **Add New Application**
3. Set the **Answer URL** to your ngrok URL + `/answer/` (e.g., `https://abc123.ngrok.io/answer/`)
4. Save the application
5. Go to [Active Numbers](https://cx.plivo.com/home)
6. Select your number and assign your application
Now call your Plivo number to hear the greeting!
***
## Forward a Call
Dial another number when receiving an incoming call.
```python theme={null}
from flask import Flask, Response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/forward/', methods=['GET', 'POST'])
def forward_call():
response = plivoxml.ResponseElement()
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14157654321'))
response.add(dial)
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
```
```javascript theme={null}
const express = require('express');
const plivo = require('plivo');
const app = express();
app.all('/forward/', (req, res) => {
const response = plivo.Response();
const dial = response.addDial();
dial.addNumber('+14157654321');
res.set('Content-Type', 'application/xml');
res.send(response.toXML());
});
app.listen(5000);
```
```ruby theme={null}
require 'sinatra'
require 'plivo'
get '/forward/' do
response = Plivo::XML::Response.new
dial = response.addDial()
dial.addNumber('+14157654321')
content_type 'application/xml'
response.to_xml
end
```
```php theme={null}
addDial();
$dial->addNumber('+14157654321');
header('Content-Type: application/xml');
echo $response->toXML();
```
Example XML to return:
```xml theme={null}
+14157654321
```
***
## Next Steps
Complete API documentation for managing calls
All XML elements for call control
Common voice application patterns
Handle call events in real-time
### Framework-Specific Guides
For detailed setup with specific frameworks:
| Language | Frameworks |
| -------- | --------------------------------------------------------------------------------------------------------------------------- |
| Python | [Flask](/docs/voice/quickstart/quickstart), [Django](/docs/voice/quickstart/quickstart), [FastAPI](/docs/voice/quickstart/quickstart) |
| Node.js | [Express](/docs/voice/quickstart/quickstart), [NestJS](/docs/voice/quickstart/quickstart), [Serverless](/docs/voice/quickstart/quickstart) |
| Ruby | [Sinatra](/docs/voice/quickstart/quickstart), [Rails](/docs/voice/quickstart/quickstart) |
| PHP | [PHP Server](/docs/voice/quickstart/quickstart) |
| Java | [Spring](/docs/voice/quickstart/quickstart), [Spark](/docs/voice/quickstart/quickstart) |
| .NET | [ASP.NET Core](/docs/voice/quickstart/quickstart), [.NET Framework](/docs/voice/quickstart/quickstart) |
| Go | [Standard Library](/docs/voice/quickstart/quickstart), [Martini](/docs/voice/quickstart/quickstart) |
### Environment Variables
Store credentials securely using environment variables:
```bash theme={null}
export PLIVO_AUTH_ID=your_auth_id
export PLIVO_AUTH_TOKEN=your_auth_token
```
All Plivo SDKs automatically read these variables when you initialize the client without arguments:
```python theme={null}
# Python
client = plivo.RestClient() # Reads from environment
```
```javascript theme={null}
// Node.js
const client = new plivo.Client(); // Reads from environment
```
# Browser SDK Guides
Source: https://plivo.com/docs/voice/sdk/browser/guides
Implementation guides for Click-to-Call, troubleshooting, and changelog for the Plivo Browser SDK.
## Click to Call
Click-to-call enables your website users to engage with your support and sales teams on the website itself. Sometimes they want to speak to someone via their handset but initiate the call online or talk to someone directly from the website. You can implement this click to call use case using Plivo's Browser SDK.
### How it works
The [Plivo Browser SDK](/docs/voice/sdk/browser/reference/) lets you make and receive calls using Plivo applications directly from any web browser.
User enters their phone number in the settings. When a call is placed, the user's handset is called first, then the call is connected to the destination number.
### Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don't have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). Click to call requires JavaScript; we recommend using Node.js. If this is your first time triggering a PHLO with Node.js, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
### Create a PHLO to handle call logic
To create a PHLO, visit the [PHLO](https://cx.plivo.com/agents) page of the Plivo console. If this is your first PHLO, the PHLO page will be empty.
* Click **Create New PHLO**.
* In the **Choose your use case** pop-up, click **Build my own**. The PHLO canvas will appear with the **Start** node.
The Start node is the starting point of any PHLO. It lets you trigger a PHLO to start upon one of three actions: incoming SMS message, incoming call, or API request.
* Click the **Start** node to open the Configuration tab, and then enter the information to retrieve from the HTTP Request payload — in this case key names are `destinationNumber` and `phoneMeNumber`. The values will remain blank as we will receive them when the request is made by the browser.
* Validate the configuration by clicking **Validate**. Do the same for each node as you go along.
* From the list of components on the left side, drag and drop the **Initiate Call** component onto the canvas. This adds an Initiate Call node onto the canvas. When a component is placed on the canvas it becomes a node.
* Draw a line to connect the **Start** node's **API Request** trigger state to the **Initiate Call** node.
* In the Configuration tab of the **Initiate Call** node, give the node a name. To enter values for the **From** and **To** fields, enter two curly brackets to view all available variables, and choose the appropriate ones.
* From the list of components on the left side, drag and drop the **Call Forward** component onto the canvas. Draw a line to connect the **Answered** trigger state of the **Initiate Call** node with the **Call Forward** node.
* Configure the **Call Forward** node to initiate call forward to another user. To enter values for the **From** and **To** fields, enter two curly brackets to view all available variables, and choose the appropriate ones.
* After you complete and validate the node configurations, give the PHLO a name by clicking in the upper left, then click **Save**.
Your complete PHLO should look like this:
### Set up the demo application
Download the demo application from GitHub and follow the setup instructions in the README:
Complete demo application with Browser SDK and PHLO integration
### Assign the PHLO to a Plivo number
Once you've created and configured your PHLO, assign it to a Plivo number.
* On the [Numbers](https://cx.plivo.com/phone-numbers) page of the console, under **Your Numbers**, click the phone number you want to use for the PHLO.
* In the **Number Configuration** box, select **PHLO** from the **Application Type** drop-down.
* From the **PHLO Name** drop-down, select the PHLO you want to use with the phone number, then click **Update Number**.
### Test
After setting up the demo application, you should see your basic server application running at `http://localhost:8080/`. Set up ngrok to expose your local server to the internet. Now make a call from your browser-based application to test it.
If you're using a Plivo Trial account, you can make calls only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console's [Sandbox Numbers](https://cx.plivo.com/home) page.
***
## Changelog
We document all notable release changes to the Browser SDK on this page. We base the format on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Release Process
We release all changes to beta first before updating to a stable release at least two weeks later, and we update all changes on this page. All past releases are URI accessible from links below and immutable, unless explicitly stated.
#### Version [v2.2.20](https://cdn.plivo.com/sdk/browser/v2.2.20/plivo.min.js) Aug 25, 2025
For detailed release notes, see the [GitHub releases page](https://github.com/plivo/Plivo-Browser-SDK-v2/releases/tag/2.2.20).
#### Version [v2.2.19](https://cdn.plivo.com/sdk/browser/v2.2.19/plivo.min.js) Jul 14, 2025
For detailed release notes, see the [GitHub releases page](https://github.com/plivo/Plivo-Browser-SDK-v2/releases/tag/2.2.19).
#### Version [v2.2.19-rc.1](https://cdn.plivo.com/sdk/browser/v2.2.19-rc.1/plivo.min.js) Mar 28, 2025
**Feature:**
* **Added**: Added a mechanism to check if the input and output devices are same/different based on the device group id and device label name for better debugging.
**Bug Fixes:**
* **Fixed**: Incorrect I/O device data sent to call-insights when input device is changed during idle state.
* **Fixed**: Output Audio playing through the built-in speakers even when the default output device is changed.
#### Version [v2.2.18](https://cdn.plivo.com/sdk/browser/v2.2.18/plivo.min.js) Mar 12, 2025
**Feature:**
* **Added**: Introduced a mechanism to fetch the noise reduction model (script) from the local file system instead of Plivo CDN:
* The file path can be provided using the **noiseReductionFilePath** flag during initialization
* If no file path is provided, the SDK will fetch the model from Plivo CDN by default
**Bug Fixes:**
* **Fixed**: Added logging to verify whether the device change event is trusted.
* **Fixed**: Updated the URL for fetching the RNNoise processor.js file.
* **Fixed**: Create and send a copy of the connectionInfo object in the onConnectionChange event.
#### Version [v2.2.17](https://cdn.plivo.com/sdk/browser/v2.2.17/plivo.min.js) Jan 23, 2025
**Bug Fixes:**
* **Fixed**: Remote Audio Fails to Play Through the Default Device After Bluetooth Disconnection.
#### Version [v2.2.16](https://cdn.plivo.com/sdk/browser/v2.2.16/plivo.min.js) Jan 16, 2025
**Feature:**
* **Added**: Added support for JSON Web Token (JWT) login with new methods: **loginWithAccessToken** and **loginWithAccessTokenGenerator**.
#### Version [v2.2.15](https://cdn.plivo.com/sdk/browser/v2.2.15/plivo.min.js) Oct 03, 2024
**Feature:**
* **Added**: A new event named **CALL\_STATS\_DUMP** has been introduced, which sends complete dump of getStats() API to call insights.
**Bug Fixes:**
* **Fixed**: Invalid state error: 8 on calling the logout directly after call is ended.
#### Version [v2.2.14](https://cdn.plivo.com/sdk/browser/v2.2.14/plivo.min.js) Sep 19, 2024
**Feature:**
* **Added**: A new event named **onCallConnected** has been introduced, which is triggered when the PSTN callee starts ringing.
**Note:** The event is not applicable for MPC and Conference based calls.
#### Version [v2.2.13](https://cdn.plivo.com/sdk/browser/v2.2.13/plivo.min.js) Aug 22, 2024
**Bug Fixes:**
* **Fixed**: Removed unnecessary dependency.
#### Version [v2.2.12](https://cdn.plivo.com/sdk/browser/v2.2.12/plivo.min.js) Jul 24, 2024
**Bug Fixes:**
* **Fixed**: Renamed **DOMError** to **DOMException** in the underlying JsSIP library to support latest Typescript versions.
#### Version [v2.2.11](https://cdn.plivo.com/sdk/browser/v2.2.11/plivo.min.js) Jun 07, 2024
**Bug Fixes:**
* **Fixed**: Enhanced call handling functionality to support multiple executions of the **call()** method.
#### Version [v2.2.10](https://cdn.plivo.com/sdk/browser/v2.2.10/plivo.min.js) May 22, 2024
**Bug Fixes:**
* **Fixed**: Improved error handling by emitting "LoginFailed" event upon unsuccessful creation of User Agent (UA).
* **Fixed**: Added a check to prevent sending DTMF signals when there is no internet connection.
* **Fixed**: Enhanced WebSocket connection optimization and improved fallback mechanisms.
* **Fixed**: Streamlined the process for reconnecting active calls during network changes.
* **Fixed**: Improved SDK reconnection logic to prevent redundant WebSocket connections.
* **Fixed**: Implemented a fix for the graceful disconnection of calls when a network switch occurs while the call is in the ring state.
* **Fixed**: Implemented an internet access check prior to registration.
* **Fixed**: Limited the Logout() function to execute only during active sessions.
**Features:**
* **Added**: Enhanced the callinfo object by introducing new attributes: Reason, Protocol, ErrorCode, and Originator.
* **Added**: Implemented Plivo STUN Servers to enhance reliability via the 'usePlivoStunServer' flag.
* **Added**: The reason for disconnection/connection is now published with the onConnectionChange event.
* **Added**: Introduced helper methods (isRegistered, isConnecting, and isConnected) for checking the client connection status.
* **Added**: Introduced a new event 'remoteAudioStatus' that signifies the reception status of audio packets from the remote caller.
* **Added**: Introduced a noise suppression feature to enhance audio quality by eliminating unwanted background noise during active calls.
* **Added**: onMediaPermission event will be triggered when media permission is revoked.
* **Added**: Users will receive a mediaMetric event when speaking while the SDK is muted.
#### Version [v2.2.9](https://cdn.plivo.com/sdk/browser/v2.2.9/plivo.min.js) Sep 29, 2023
**Features:**
* **Added**: A new **useDefaultAudioDevice** flag for using the system's default audio device.
**Bug Fixes:**
* **Fixed**: Removed support for the getStats API, as it is no longer available in Chrome versions 117 and beyond.
* **Fixed**: Removed the predetectOWA functionality.
* **Fixed**: Issue on audio input/output device mismatch on windows platform.
#### Version [v2.2.8](https://cdn.plivo.com/sdk/browser/v2.2.8/plivo.min.js) Sep 12, 2023
**Features:**
* **Added**: A **refreshRegistrationTimer** flag for user-configurable periodic re-registration by the SDK.
* **Added**: An **onDtmfReceived** event triggered when the SDK receives DTMF tones.
* **Added**: Enhanced remote debugging with the collection and transmission of logs to Plivo servers.
* **Added**: Plivo STUN servers to ensure stable connections.
* **Added**: A **CALL\_RINGING** event signaling the initiation of incoming/outgoing call ringing to Plivo.
**Bug Fixes:**
* **Fixed**: Corrected the handling of stir-verification in incoming call headers.
* **Fixed**: Fixed audio level discrepancies that occurred when changing input/output devices.
* **Fixed**: Removed DOMError to support latest Typescript versions.
* **Fixed**: Restored functionality for incoming calls with PCMU codec.
* **Fixed**: Prevented SDK from logging out when re-registration timed out.
* **Fixed**: Reduced the time for firing the onConnectionChange event with a disconnected state to within 10 seconds.
For older releases in the V2.1 series, see the [GitHub releases page](https://github.com/plivo/Plivo-Browser-SDK-v2/releases).
For releases in the V2.0 series, see the [GitHub releases page](https://github.com/plivo/Plivo-Browser-SDK-v2/releases).
# JWT Authentication
Source: https://plivo.com/docs/voice/sdk/browser/jwt-authentication
Generate JWT access tokens for the Plivo Browser SDK to authenticate browser sessions without exposing endpoint credentials.
## Introduction
The Plivo Browser SDK supports two authentication methods for registering SIP endpoints:
1. **Username/Password**: `client.login(username, password)`
2. **JWT Access Token**: `client.loginWithAccessToken(jwt)` *(recommended, added in v2.2.16)*
JWT tokens are short-lived, server-signed tokens that authenticate a browser session against a Plivo SIP endpoint without exposing endpoint credentials to the client. This makes JWT the recommended approach for production applications.
JWT authentication requires `plivo-browser-sdk` v2.2.16 or later. Earlier versions only support username/password authentication.
## How it works
```mermaid theme={null}
sequenceDiagram
participant B as Browser
participant S as Your Server
participant P as Plivo
B->>S: (1) Request token
S->>P: (2) POST /JWT/Token/
P-->>S: (3) Returns signed JWT
S-->>B: (4) Return JWT
B->>P: (5) loginWithAccessToken()
P-->>B: (6) SIP REGISTER (WebRTC)
```
1. Your browser app requests a JWT from your backend server.
2. Your server calls the Plivo REST API to generate a signed token.
3. Plivo returns a signed JWT.
4. Your server passes the JWT to the browser.
5. The Browser SDK uses the JWT to register with Plivo via `loginWithAccessToken()`.
6. Plivo validates the token and completes SIP registration over WebRTC.
JWTs **must** be generated server-side via the Plivo REST API. Locally-signed JWTs (using libraries like `jsonwebtoken`) are rejected by Plivo's SIP infrastructure, even if signed with your `auth_token`.
## Prerequisites
Before generating JWT tokens, you need:
* A Plivo account with `auth_id` and `auth_token` ([sign up](https://cx.plivo.com/signup))
* A [Plivo Application](/docs/account/api/application/) that defines your answer and hangup webhook URLs
* A [Plivo Endpoint](/docs/voice/api/endpoints/) linked to the application
* `plivo-browser-sdk` v2.2.16+ installed in your frontend
If you don't have an application and endpoint yet, see [Setting up an application and endpoint](#setting-up-an-application-and-endpoint) below.
## Generating a JWT token
Use the Plivo REST API to generate a signed JWT for a specific endpoint.
### API endpoint
```
POST https://api.plivo.com/v1/Account/{auth_id}/JWT/Token/
```
### Authentication
Use HTTP Basic Auth with your Plivo `auth_id` and `auth_token`.
### Request body
| Field | Type | Required | Description |
| ----- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `iss` | string | Yes | Your Plivo `auth_id`. |
| `sub` | string | Yes | The subject identifier for the token. |
| `nbf` | number | Yes | Not Before timestamp (Unix seconds). The token is invalid before this time. |
| `exp` | number | Yes | Expiration timestamp (Unix seconds). The token is invalid after this time. Maximum allowed validity is 24 hours. |
| `per` | object | Yes | Permissions object. See [Permissions](#permissions). |
| `app` | string | No | Plivo Application ID. Associates the session with a specific application for call routing. |
### Permissions
The `per` object controls what the authenticated endpoint can do:
```json theme={null}
{
"voice": {
"incoming_allow": true,
"outgoing_allow": true
}
}
```
| Field | Type | Description |
| ---------------- | ------- | ----------------------------------------------- |
| `incoming_allow` | boolean | Whether the endpoint can receive inbound calls. |
| `outgoing_allow` | boolean | Whether the endpoint can make outbound calls. |
### Response
A successful request returns a JSON object containing the signed JWT:
```json theme={null}
{
"api_id": "2c09a7fc-1234-11ee-b979-0242ac110002",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6InBsaXZvO3Y9MSJ9..."
}
```
The returned JWT has the following structure:
| Part | Details |
| ------------- | -------------------------------------------------------------------------- |
| **Header** | `{ "alg": "HS256", "typ": "JWT", "cty": "plivo;v=1" }` |
| **Payload** | Contains `iss`, `sub`, `nbf`, `exp`, `per`, `app`, plus Plivo-added fields |
| **Signature** | HMAC-SHA256, signed by Plivo (not your `auth_token`) |
The `cty: "plivo;v=1"` header is added automatically by the Plivo REST API when generating tokens. Plivo's server validates this field during SIP registration.
### Server-side examples
```javascript theme={null}
// Express.js route handler
app.post("/api/plivo-token", async (req, res) => {
const authId = process.env.PLIVO_AUTH_ID;
const authToken = process.env.PLIVO_AUTH_TOKEN;
const now = Math.floor(Date.now() / 1000);
const response = await fetch(
`https://api.plivo.com/v1/Account/${authId}/JWT/Token/`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Basic ${Buffer.from(`${authId}:${authToken}`).toString("base64")}`,
},
body: JSON.stringify({
iss: authId,
sub: "myendpoint", // endpoint username
nbf: now,
exp: now + 300, // 5 minutes
per: {
voice: {
incoming_allow: true,
outgoing_allow: true,
},
},
app: "77241325312960404", // application ID
}),
}
);
if (!response.ok) {
return res.status(500).json({ error: "Failed to generate token" });
}
const data = await response.json();
res.json({ token: data.token });
});
```
```python theme={null}
import os
import time
import base64
import requests
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/api/plivo-token", methods=["POST"])
def get_plivo_token():
auth_id = os.environ["PLIVO_AUTH_ID"]
auth_token = os.environ["PLIVO_AUTH_TOKEN"]
now = int(time.time())
credentials = base64.b64encode(
f"{auth_id}:{auth_token}".encode()
).decode()
response = requests.post(
f"https://api.plivo.com/v1/Account/{auth_id}/JWT/Token/",
headers={
"Content-Type": "application/json",
"Authorization": f"Basic {credentials}",
},
json={
"iss": auth_id,
"sub": "myendpoint", # endpoint username
"nbf": now,
"exp": now + 300, # 5 minutes
"per": {
"voice": {
"incoming_allow": True,
"outgoing_allow": True,
}
},
"app": "77241325312960404", # application ID
},
)
if not response.ok:
return jsonify({"error": "Failed to generate token"}), 500
data = response.json()
return jsonify({"token": data["token"]})
```
```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/{auth_id}/JWT/Token/" \
-H "Content-Type: application/json" \
-u ':' \
-d '{
"iss": "{auth_id}",
"sub": "myendpoint",
"nbf": 1700000000,
"exp": 1700000300,
"per": {
"voice": {
"incoming_allow": true,
"outgoing_allow": true
}
},
"app": "77241325312960404"
}'
```
## Browser SDK integration
### Login with a JWT
After fetching a JWT from your server, use `loginWithAccessToken()` to register with Plivo:
```javascript theme={null}
import Plivo from "plivo-browser-sdk";
// Initialize the SDK
const plivoBrowserSdk = new window.Plivo({
debug: "INFO",
permOnClick: true,
enableTracking: true,
});
// Set up event handlers
plivoBrowserSdk.client.on("onLogin", () => {
console.log("Registered with Plivo successfully");
// Ready to make or receive calls
});
plivoBrowserSdk.client.on("onLoginFailed", (errorCode) => {
const errorMessage = plivoBrowserSdk.client.getErrorStringByErrorCodes(errorCode);
console.error("Login failed:", errorCode, errorMessage);
});
// Fetch JWT from your server
const response = await fetch("/api/plivo-token", { method: "POST" });
const { token } = await response.json();
// Register using JWT
plivoBrowserSdk.client.loginWithAccessToken(token);
```
### Making a call after login
Once registered, you can make outbound calls:
```javascript theme={null}
plivoBrowserSdk.client.on("onCallAnswered", (callInfo) => {
console.log("Call connected:", callInfo);
});
plivoBrowserSdk.client.on("onCallTerminated", (hangupInfo, callInfo) => {
console.log("Call ended:", hangupInfo);
});
// Call a phone number
plivoBrowserSdk.client.call("+14155551234");
// Or call with custom SIP headers
plivoBrowserSdk.client.call("+14155551234", {
"X-PH-SessionId": "session-abc-123",
});
```
### Refreshing tokens
JWT tokens are short-lived. If you need to re-register (for example, after a network disconnect), fetch a new token and call `loginWithAccessToken()` again:
```javascript theme={null}
plivoBrowserSdk.client.on("onConnectionChange", async (info) => {
if (info.state === "connected") {
// WebSocket reconnected - re-register with a fresh token
const response = await fetch("/api/plivo-token", { method: "POST" });
const { token } = await response.json();
plivoBrowserSdk.client.loginWithAccessToken(token);
}
});
```
## Setting up an application and endpoint
If you don't already have a Plivo Application and Endpoint, create them before generating JWT tokens.
### Create an application
A Plivo Application defines the webhook URLs that Plivo calls when a browser-initiated call connects.
```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/{auth_id}/Application/" \
-H "Content-Type: application/json" \
-u ':' \
-d '{
"app_name": "my-browser-app",
"answer_url": "https://your-server.com/answer",
"answer_method": "POST",
"hangup_url": "https://your-server.com/hangup",
"hangup_method": "POST"
}'
```
```python theme={null}
import plivo
client = plivo.RestClient("", "")
response = client.applications.create(
app_name="my-browser-app",
answer_url="https://your-server.com/answer",
answer_method="POST",
hangup_url="https://your-server.com/hangup",
hangup_method="POST",
)
print(response) # includes app_id
```
```javascript theme={null}
const plivo = require("plivo");
const client = new plivo.Client("", "");
client.applications
.create("my-browser-app", {
answerUrl: "https://your-server.com/answer",
answerMethod: "POST",
hangupUrl: "https://your-server.com/hangup",
hangupMethod: "POST",
})
.then((response) => console.log(response));
// response includes appId
```
The response includes an `app_id`. Save this for creating endpoints and generating JWT tokens.
For more details, see the [Application API reference](/docs/account/api/application/).
### Create an endpoint
A Plivo Endpoint is a SIP identity that the Browser SDK registers as. Each endpoint must be linked to an application.
```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/{auth_id}/Endpoint/" \
-H "Content-Type: application/json" \
-u ':' \
-d '{
"username": "myendpoint",
"password": "a-strong-random-password",
"alias": "my-browser-endpoint",
"app_id": "77241325312960404"
}'
```
```python theme={null}
import plivo
client = plivo.RestClient("", "")
response = client.endpoints.create(
username="myendpoint",
password="a-strong-random-password",
alias="my-browser-endpoint",
app_id="77241325312960404",
)
print(response) # includes endpoint_id and username
```
```javascript theme={null}
const plivo = require("plivo");
const client = new plivo.Client("", "");
client.endpoints
.create("myendpoint", "a-strong-random-password", "my-browser-endpoint", "77241325312960404")
.then((response) => console.log(response));
// response includes endpointId and username
```
**Endpoint constraints:**
* `username`: Alphanumeric characters only, 1-25 characters, must start with an alphabetic character.
* `alias`: Letters, numbers, hyphens, and underscores only.
* `password`: At least 5 characters. Only used at creation time; the Browser SDK authenticates via JWT, not the endpoint password.
The endpoint username from the response is the value you pass as `sub` when generating JWT tokens. For more details, see the [Endpoint API reference](/docs/voice/api/endpoints/).
## Error codes
When JWT authentication fails, the `onLoginFailed` event returns a numeric error code. Use `getErrorStringByErrorCodes()` to get a human-readable message.
| Error Code | Error Name | Description |
| ---------- | ------------------------------------- | -------------------------------------------------------------------------------------- |
| 10001 | `INVALID_ACCESS_TOKEN` | The access token is invalid. |
| 10002 | `INVALID_ACCESS_TOKEN_HEADER` | The access token header is invalid. |
| 10003 | `INVALID_ACCESS_TOKEN_ISSUER` | The token issuer (`iss`) is invalid. |
| 10004 | `INVALID_ACCESS_TOKEN_SUBJECT` | The token subject (`sub`) is invalid. |
| 10005 | `ACCESS_TOKEN_NOT_VALID_YET` | The current time is before the token's `nbf` timestamp. |
| 10006 | `ACCESS_TOKEN_EXPIRED` | The token's `exp` timestamp has passed. Generate a new token. |
| 10007 | `INVALID_ACCESS_TOKEN_SIGNATURE` | The token signature is invalid. Ensure the token was generated via the Plivo REST API. |
| 10008 | `INVALID_ACCESS_TOKEN_GRANTS` | The `per` permissions object is missing or invalid. |
| 10009 | `EXPIRATION_EXCEEDS_MAX_ALLOWED_TIME` | The token expiration exceeds the maximum allowed duration. |
| 10010 | `MAX_ALLOWED_LOGIN_REACHED` | The maximum number of concurrent logins has been reached. |
### Handling errors in code
```javascript theme={null}
plivoBrowserSdk.client.on("onLoginFailed", (errorCode) => {
const errorMessage = plivoBrowserSdk.client.getErrorStringByErrorCodes(errorCode);
console.error(`Login failed [${errorCode}]: ${errorMessage}`);
// Handle specific cases
if (errorCode === 10006) {
// Token expired - fetch a fresh one and retry
refreshAndRelogin();
}
});
```
## Best practices
1. **Keep tokens short-lived.** A validity of 5 minutes is recommended. The Browser SDK maintains the SIP registration after login; re-authentication is only needed when the session disconnects.
2. **Match the endpoint to the application.** Each endpoint is linked to a specific application via `app_id`. The `app` field in the JWT should reference the same application the endpoint is registered to, otherwise call routing may behave unexpectedly.
3. **Never expose credentials to the browser.** Your `auth_id` and `auth_token` should only be used server-side. The browser should only receive the signed JWT.
4. **One endpoint per concurrent session.** While Plivo allows multiple simultaneous registrations for the same endpoint, this is only reliable for outbound-only use cases. For inbound call routing, use a unique endpoint per browser session.
# Plivo Browser SDK
Source: https://plivo.com/docs/voice/sdk/browser/overview
Build voice applications in web browsers using the Plivo Browser SDK with WebRTC support.
## Introduction
The Plivo Browser SDK lets you make and receive calls using Plivo applications directly from any web browser. Using our SDK, you can create applications such as:
1. **Call Center** — Build efficient call center workflow by allowing your agents to make and receive calls via their browsers. Control call flow in your app using our API.
2. **Click to Call** — When adding click to call for your CRM app, Plivo runs seamlessly in the background to allow your users to interact via audio communication.
3. **Web-Based Help Desk** — Create great service experiences and workflows. Sales and support agents can access customer info while making calls directly from their web browsers.
4. **Web Conferencing** — Build rich conference experiences with Plivo's out-of-the-box features, including unique call flows, recording calls, and branded conference greetings.
## How does it work?
1. From a browser, a Plivo endpoint initiates an internet call to Plivo's voice platform.
2. The platform notifies your application server about the call.
3. Plivo handles the call based on XML documents returned by the application server. In this case, a Dial XML element connects the call with the phone number specified in the XML document.
4. Plivo initiates a call to the phone number specified in the Dial XML element.
5. Once the call is answered, the two parties are connected and can talk to each other.
To learn more about managing the call flows and types of call flows, refer to our [Voice Overview guide](/docs/voice/concepts/overview/).
## Supported browsers
This table shows the browsers supported by the Plivo Browser SDK.
**Chrome and Firefox:** We support the most recent and previous 10 versions.
**Safari:** We support the most recent and previous five versions.
| | Chrome | Firefox | Safari | Chromium |
| ------- | ---------------------------- | ---------------------------- | ---------------------------- | ---------------------------- |
| macOS | | | | |
| Windows | | | \*\* | |
| Linux | | | \*\* | \*\*\* |
| IOS | \* | \* | | \* |
| Android | | | \*\* | |
\* Unlike Safari for iOS, Chrome and Firefox for iOS do not have access to WebRTC APIs.
\*\* Safari for Windows and Linux are not supported.
\*\*\* Edge for Linux is not supported.
**Note**: On mobile browsers, Browser SDK functionality may be compromised due to limitations imposed by browsers. These limitations include inability to maintain call connectivity if the browser moves to the background, inability to receive incoming call notifications in case the browser was in background, and inability to handle GSM call interruptions. As a result, we highly recommend that you evaluate our mobile SDKs ([iOS](/docs/voice/client/androidios/overview), [Android](/docs/voice/client/androidios/overview)) while creating mobile voice apps for better user experience.
For mobile applications, we recommend using our native [iOS](/docs/voice/client/androidios/overview) and [Android](/docs/voice/client/androidios/overview) SDKs. See our [SDK FAQ](/docs/voice/sdk/browser/overview) for more details on browser limitations.
The Browser SDK codebase is [publicly available on GitHub](https://github.com/plivo/Plivo-Browser-SDK-v2).
Browser SDK supports TypeScript (version 4.0.3 and higher).
Try out the demo — [get started with examples](https://github.com/plivo/plivo-browser-sdk2-examples/tree/master).
## Installation
### Download using NPM (recommended)
You can include the [Plivo-Browser-SDK](https://www.npmjs.com/package/plivo-browser-sdk) NPM package as a dependency in your project. Use the below command:
```sh theme={null}
npm install plivo-browser-sdk --save
```
Also, you can include the latest Plivo-Browser-SDK Beta NPM package using the below command:
```sh theme={null}
npm install plivo-browser-sdk@beta
```
After installation, import the SDK in your application:
```javascript theme={null}
// ES Module
import Plivo from 'plivo-browser-sdk'
// CommonJS
const Plivo = require('plivo-browser-sdk');
```
### Include using CDN link (not recommended)
You can include the plivo javascript file as shown below directly on your webpage
```sh theme={null}
```
**Note**: We do not recommend this approach because any recent changes to our SDK will be applied to your production apps automatically without going through your build process and could lead to unexpected behavior for your customers.
To mitigate this risk, every new release is first pushed to this beta CDN link before being merged to the master: ``
Alternatively, you can include a specific release in your app by using it's specific CDN link. We continue to make our past releases URI accessible and immutable, unless explicitly stated. You can find the latest links on the [Changelog section](/docs/voice/sdk/browser/guides/#changelog).
## Quick Start
### Initializing the plivoBrowserSdk Object
The plivoBrowserSdk object needs to be initialized.
```js theme={null}
var options = {
"debug":"DEBUG",
"permOnClick":true,
"enableTracking":true,
"closeProtection":true,
"maxAverageBitrate":48000
};
var plivoBrowserSdk = new window.Plivo(options);
```
For more explanation on options see the [Configuration Parameters](#configuration-parameters) section.
### Event registration
Pass function references to the events produced from the SDK. This is where your UI manipulation should handle the call flows.
```js theme={null}
plivoBrowserSdk.client.on('onWebrtcNotSupported', onWebrtcNotSupported);
plivoBrowserSdk.client.on('onLogin', onLogin);
plivoBrowserSdk.client.on('onLogout', onLogout);
plivoBrowserSdk.client.on('onLoginFailed', onLoginFailed);
plivoBrowserSdk.client.on('onCallRemoteRinging', onCallRemoteRinging);
plivoBrowserSdk.client.on('onCallConnected', onCallConnected);
plivoBrowserSdk.client.on('onIncomingCallCanceled', onIncomingCallCanceled);
plivoBrowserSdk.client.on('onCallFailed', onCallFailed);
plivoBrowserSdk.client.on('onCallAnswered', onCallAnswered);
plivoBrowserSdk.client.on('onMediaConnected', onMediaConnected);
plivoBrowserSdk.client.on('onCallTerminated', onCallTerminated);
plivoBrowserSdk.client.on('onCalling', onCalling);
plivoBrowserSdk.client.on('onIncomingCall', onIncomingCall);
plivoBrowserSdk.client.on('onMediaPermission', onMediaPermission);
plivoBrowserSdk.client.on('mediaMetrics',mediaMetrics);
plivoBrowserSdk.client.on('onConnectionChange',onConnectionChange);
plivoBrowserSdk.client.on('onDtmfReceived',onDtmfReceived);
plivoBrowserSdk.client.on('remoteAudioStatus', remoteAudioStatus);
plivoBrowserSdk.client.on('onNoiseReductionReady', onNoiseReductionReady);
plivoBrowserSdk.client.on('onWebSocketConnected', onWebSocketConnected);
```
### Registering using your Plivo endpoint
Register using your Plivo endpoint credentials
```js theme={null}
var username = 'johndoe12345';
var password = '';
plivoBrowserSdk.client.login(username, password);
```
### Making a call
Making a call to any number/SIP endpoint. The application attached to the registered endpoint should have an answer URL that will return the correct `` element.
```js theme={null}
var dest = "jane1234@phone.plivo.com";
var extraHeaders = {'X-PH-Test1': 'test1', 'X-PH-Test2': 'test2'};
plivoBrowserSdk.client.call(dest, extraHeaders);
```
### Accepting a call
This is how an incoming call should be answered when an `onIncomingCall` event is received.
```js theme={null}
plivoBrowserSdk.client.answer(callUUID)
```
***callUUID*** is passed in the `onIncomingCall` event callback, as we describe in the [Reference documentation](/docs/voice/sdk/browser/reference/).
### Sending DTMF
This snippet sends a DTMF tone when in a phone call.
```js theme={null}
plivoBrowserSdk.client.sendDtmf("1");
```
## Configuration Parameters
| Attribute | Description | Allowed Values | Default Value |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| `debug` | Enable debug message in JS log | OFF, ERROR, WARN, INFO, DEBUG, ALL | INFO |
| `permOnClick` | Set to true if you want to ask for mic permission just before call connection. Otherwise it will be asked only on page load. | true/false | false |
| dtmfOptions | This parameter can be used to select between "inband" and/or "outband" DTMF. | \{sendDtmfType: \["inband"] } / \{sendDtmfType: \["outband"] } / \{sendDtmfType: \["inband","outband"] } | \{sendDtmfType: \["inband","outband"]} |
| `audioConstraints` | Audio constraints object that will be passed to webRTC getUserMedia(). | Audio constraints values are browser specific.
Refer: [MediaTrackConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints) | |
| `enableTracking` | Set to true if you want to get mediaMetrics events and enable call quality tracking. | true/false | true |
**Note**: `enableTracking` will be deprecated as part of the next major update. Please use `use enableQualityTracking` instead.
| Attribute | Description | Allowed Values | Default Value |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------- |
| `enableQualityTracking` | This parameter can be used to enable and disable two functionalities:
**mediaMetrics events** enables the Client device to display local call issues such as broken audio to the user.
**Call quality tracking** enables Plivo to capture and display call quality data in Call Insights.
When set to `all` both MediaMetrics events and call quality tracking is enabled.
When set to `remoteonly` only call quality tracking is enabled.
When set to `localonly` only MediaMetrics events are enabled.
When set to `none` both MediaMetrics events and call quality tracking are disabled. | all, remoteonly, localonly, none | all |
**Note**: If `enableQualityTracking` is configured with a nondefault value, it overrides any configuration of `enableTracking`.
| Attribute | Description | Allowed Values | Default Value |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------- |
| `closeProtection` | Set to `true` to get a dialog prompt while closing the app when the call is in progress (ringing state or answered state). | true, false | false |
| `dscp` | Set to true to enable QoS in voice traffic. Differentiated Services field in the packet headers for all WebRTC traffic. **Note**: dscp is supported only in Chrome. | true, false | true |
| `allowMultipleIncomingCalls` | When set to `true` there can be multiple calls ringing at the same time.
1. The onIncomingCall event will be fired for every incoming call.
2. When an incoming call is accepted, other ringing calls (if any) will be either rejected or ignored depending on the option passed to answer function automatically.
3. When an incoming call is rejected or ignored, other ringing calls (if any) will continue ringing.
There can only be one active answered call at any given moment.
1. When an incoming call is accepted, the in-progress answered call will be disconnected automatically.
2. When an incoming call is rejected or ignored, the in-progress answered call will continue without any interruption.
When set to `false` incoming calls are silently rejected if the endpoint is engaged in an active call or if another call is ringing. | true, false | false |
| `clientRegion` | Initialization options to set and route calls to specific MediaServer POPs | \["usa\_west", "usa\_east", "australia", "europe", "asia", "south\_america", "south\_asia"] | - |
**Note**: If `clientRegion` is not defined, the nearest Plivo data center (PoP) will be picked based on the Browser SDK client registered IP address.
| Attribute | Description | Allowed Values | Default Value |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------------- |
| `enableNoiseReduction` | Reduces background noise during ongoing calls. | true, false | false |
| `usePlivoStunServers` | Indicates that Plivo will strive to establish the connection with two parallel STUN servers, and the connection will be established promptly upon receiving a response from either server. | true, false | false |
| `useDefaultAudioDevice` | Determines whether the system's default input/output devices are utilized following the addition or removal of an audio device. If not, the recently added device will be utilized for both input and output. | true, false | false |
| `stopAutoRegisterOnConnect` | When set to true, the login() method will only establish a connection to the Plivo servers but will not register the SDK. To complete the registration process, you will need to manually invoke the register() method. | true, false | false |
| `captureSDKCrashOnly` | When set to true, the SDK will only capture and sync crashes related to the SDK code, avoiding App side errors being pushed to Plivo servers. | true, false | false |
| `maxAverageBitrate` | Used to control your application's bandwidth consumption for calls.
A higher maxAverageBitrate value may result in more bandwidth consumption, but also better audio quality.
Lowering the maxAverageBitrate impacts call quality, as audio is compressed to a greater extent to reduce bandwidth consumption.
This parameter only applies to calls using the Opus codec. See RFC-7587 section 7.1 for more info. | 8000 - 48000 | 48000 |
| `registrationRefreshTimer` | A parameter where we allow users to set the value for refreshing the registration of the SDK. | 100 - 86400 seconds | 120 seconds |
## Best Practices for Call Quality
VoIP call quality is influenced by several factors, including device software and hardware and the network a device is connected to. Here we explore the key factors that influence call quality on Browser SDK calls, and offers recommendations for improving call quality.
### Network Characteristics
The network the device runs on has a big influence on call quality thanks to factors such as jitter and latency.
#### Jitter and Latency
VoIP calls involve the transmission of a continuous train of voice data packets. If the network is congested, some of the first packets sent may reach a recipient later than other packets. This out-of-order receipt of packets, known as jitter, can result in the audio sounding jumbled or robotic. Jitter is measured in milliseconds of delay, and jitter values higher than 30 milliseconds on WebRTC calls can lead to poor audio quality. High network congestion can also lead to packet loss, resulting in chunks of audio never reaching the intended recipient.
Latency, in the context of VoIP calls, is the spoken-to-heard delay in the transmission of audio. The major contributing factor to VoIP latency is the delay incurred in the transmission of voice packets from origin to destination. When this network latency is more than 300 milliseconds of round-trip time, call participants can experience audio lag.
### Recommendations
To minimize network and device issues and improve call quality, Plivo recommends:
* Using a high-bandwidth fiber connection from a reputed internet provider. Dedicated business internet connections generally come with guaranteed SLAs on bandwidth and latency.
* Using a physical Ethernet connection instead of Wi-Fi when possible.
* If using Wi-Fi, limiting the number of devices connected on the same channel.
* Using high-quality Wi-Fi routers built for enterprises or real-time gaming. Look for routers that come with advanced QoS features.
* Auditing your network firewall and NAT settings to check for transmission delays due to improper configuration.
* Avoiding large data transfers on the Wi-Fi network during calls.
* Limiting bandwidth per connected device to ensure an even allocation of total available bandwidth.
* Avoiding calls over cellular data connections (4G and older) as they are not optimized for low-latency traffic.
* Setting the Differentiated Service Code Point (dscp) parameter of Plivo Browser SDK to "true." *DSCP for WebRTC is supported by Chrome only. It informs network routers to prioritize voice packets over other network packets. Corresponding QoS configurations in the router may be also required.*
* Setting Plivo Media Server region selection in auto mode of the Browser SDK. This ensures that calls get routed through the closest geographic PoP based on the device's IP address.
* Ensuring uplink and downlink bandwidth availability of at least 50Kbps for voice transmission.
* If operating in a low-bandwidth environment, capping the bandwidth to be consumed on the call using the maxAverageBitrate configuration parameter of the Browser SDK.
* Gracefully handling poor call quality experiences in real time by consuming MediaMetrics call quality events emitted by the Browser SDK during the call.
* Submitting call quality feedback to Plivo programmatically from the Browser SDK or through the [Feedback API](/docs/voice/api/calls#call-conversion). Your feedback lets Plivo optimize its network by identifying patterns across calls.
### Network Firewalls
Voice data on VoIP calls is transferred over UDP. Ensure that your network firewall allows the transmission of UDP packets between client devices and the public internet.
If your firewall requires whitelisting of external IP addresses, make sure to whitelist [Plivo's SIP Signaling and Media Server IP addresses](/docs/voice/concepts/firewall-network-configuration/#rtp-media-servers).
### Device Characteristics
Certain software and hardware device characteristics have a direct impact on VoIP call quality.
#### Browser and OS
The Plivo Browser SDK is tested and supported only for the browsers listed in the [Supported browsers](#supported-browsers) section. Browser SDK uses WebRTC for voice calls on these browsers:
* `Chrome` on Windows, Linux, macOS, and Android
* `Firefox` on Windows, Linux, macOS, and Android
* `Safari 11+` on iOS and macOS
* `New Microsoft Edge` (based on Chromium) on Windows
`Chrome for iOS` and `Firefox for iOS` don't support WebRTC.
Plivo highly recommends using our native iOS and Android SDKs to build app-based calling functionality on mobile devices. Mobile browsers would be required to be in the foreground for the entire duration of a call and lack call interruption handling for cellular calls received while on a browser call. Both these features are supported through the Plivo iOS and Android SDKs.
#### Device Hardware
While most modern PC and smartphone devices are more than capable of handling VoIP calls, incompatibilities between hardware components such as network drivers, audio cards, and other firmware components can result in unexpected issues with media handling.
Attempting to reproduce issues on other devices should be a key step in your debugging process.
#### The Audio Input and Output Device
Plivo recommends using quality headsets for browser-based calls.
Headsets minimize echo by providing acoustic isolation between the speaker and the microphone. High-quality VoIP headsets with noise-canceling features can greatly enhance call quality in noisy environments by eliminating background sounds.
Wired headsets generally offer more stable sound quality than wireless or Bluetooth headsets. Wireless headsets are more prone to adapter and driver configuration issues, which can lead to static or white noise on calls. We recommend testing with a different headset, or with a built-in mic and speaker, when troubleshooting audio quality issues.
## Next steps
Now that you know the fundamentals, you can build a simple app. Get inspiration from our [sample applications](https://github.com/plivo/plivo-browser-sdk2-examples/) and learn implementation details from our [Browser SDK Reference documentation](/docs/voice/sdk/browser/reference/).
# Browser SDK Reference
Source: https://plivo.com/docs/voice/sdk/browser/reference
Complete API reference for the Plivo Browser SDK including methods, events, callbacks, and audio device APIs.
Plivo Browser SDK allows you to make and receive calls using Plivo applications directly from any web browser that supports webRTC. Using our SDK you can create applications like Click to Call, Conferencing Apps and even Webphones.
## Variables
| Variable | Description |
| ------------ | -------------------------------------------------------------- |
| `version` | Returns current version of the Plivo SDK. |
| `isLoggedIn` | Returns `true` if the user is logged in and `false` otherwise. |
## Methods
| Method | Description |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `login(username, password)` | Register a Plivo endpoint using username and password credentials. |
| `loginWithAccessToken(accessToken)` | Register a Plivo endpoint using a JSON Web Token (JWT). Added in v2.2.16. |
| `loginWithAccessTokenGenerator(accessTokenObject)` | Register a Plivo endpoint using a JWT generator object that provides tokens dynamically. Added in v2.2.16. |
| `logout()` | Log out from the registered endpoint. |
| call(number, extraHeaders) | Call a number or SIP address. 'number' takes a String value and 'extraHeaders' takes a JSON object. Extra headers should start with X-PH.
Example of 'extraHeaders': \{'X-PH-Test1': 'test1', 'X-PH-Test2': 'test2'}
Note: Browser SDK supports specific characters in extra headers. Those include \[A-Z], \[a,z], \[0-9]. Additionally, special characters +-\_() are also allowed. Any other characters apart from these are ignored by Browser SDK. |
| `answer(callUUID, actionOnOtherIncomingCalls)` | Answer an incoming call.
When callUUID is given, the SDK will attempt to answer the incoming call identified by it.
When callUUID is not given, the SDK will attempt to answer the most recent ringing call.
When callUUID is invalid, the SDK will return false with an error log.
actionOnOtherIncomingCalls is Optional -
Possible string values:
`reject` — This is the default value. Other incoming calls (if any) are rejected.
`ignored` — Other incoming calls (if any) stop ringing locally but ring for the caller. These incoming calls cannot be answered after ignored.
`letring` — Other incoming calls ring silently in local and continue to ring for the caller. These incoming calls can be answered until they stop ringing. |
| `hangup()` | Hang up the ongoing call. |
| `reject(callUUID)` | Reject an incoming call.
When callUUID is given, the SDK attempts to reject the ringing call it identifies. When callUUID is not given or an invalid callUUID is given, the SDK attempts to answer the most recent ringing call. |
| `ignore(callUUID)` | Stops the incoming sound (ring) and sets the call state to `ignored`, but does not send a hangup message to the dialing party. The incoming call keeps ringing for the called party until the call times out.
When callUUID is given, the SDK attempts to ignore the incoming call it identifies. When callUUID is not given or an invalid callUUID is given, the SDK attempts to ignore the most recent ringing call. |
| `sendDtmf(digit)` | Send the digits as DTMF.
`digit` can be any numeric one-character strings or "\*" or "#". |
| mute() | Mutes the mic. |
| unmute() | Unmutes the mic. |
| setRingTone(url or boolean) | Configures the ringtone played locally by the browser for incoming calls.
`true` (default) — `default tone` is played during incoming call
`false` — no ringtone is played during incoming call
`url` — media at the URL is played during incoming call |
| `setRingToneBack(url or boolean)` | Use this function to configure the ringtone played locally by the browser when an outgoing call starts ringing.
`true` (default) — the `default tone` is played when an outbound call rings. Note that ringtone and pre-answer announcements passed by Plivo's media servers will not be played.
`false` — ringtone and pre-answer announcements received from Plivo's media servers are played
`url` — remote ringtone is paused and media URL passed is played during outbound call `ringing` status. |
| `setConnectTone(boolean)` | `true` (default) — Dial tone plays while the call is being connected.
`false` — No dial tone plays. |
| `setDebug(debug)` | Set the log level of the SDK. Allowed values: OFF, ERROR, WARN, INFO, DEBUG, ALL |
| getPeerConnection() | Returns a RTCPeerConnection object.
Example:
\{
status: 'success',
pc: RTCPeerConnection
} |
| submitCallQualityFeedback(callUUID, starRating, issues, note, sendConsoleLogs) | `callUUID` is a mandatory string parameter used to identify the call the feedback belongs to. You can get the callUUID from getCallUUID() or getLastCallUUID().
`starRating` is a mandatory integer parameter with a value from 1 to 5. For a score from 1 to 4, issues parameter is mandatory; it is optional for a score of 5.
`issues` is an array and must have at least one of these reasons for a starRating value from 1 to 4: AUDIO\_LAG, BROKEN\_AUDIO, CALL\_DROPPPED, CALLERID\_ISSUES, DIGITS\_NOT\_CAPTURED, ECHO, HIGH\_CONNECT\_TIME, LOW\_AUDIO\_LEVEL, ONE\_WAY\_AUDIO, ROBOTIC\_AUDIO, OTHERS
`note` is an optional string attribute for user remarks.
`sendConsoleLogs` is an boolean optional paramter with default value `false`. Set to `true` to enable Plivo's team to collect and analyze Browser SDK's logs so we can better understand the issue. |
| `getCallUUID()` | Returns a string call UUID if a call is active, else returns null. |
| `getLastCallUUID()` | Returns the call UUID of the latest answered call. Useful if you want to send feedback for the last call. |
| `startNoiseReduction()` | Starts noise reduction. |
| `stopNoiseReduction()` | Stops noise reduction. |
| `isConnected()` | This function returns a boolean value indicating whether the WebSocket is connected. It serves to check the status of the WebSocket connection before attempting to re-initiate it. |
| `isConnecting()` | This function returns a boolean value indicating whether the WebSocket connection is currently in progress. It serves to check the status of the WebSocket connection before attempting to re-initiate it. |
| `isRegistered()` | This function returns a boolean value indicating whether the registration is sucessful. |
| `register()` | This method will register the SDK once it is connected to Plivo servers. The onWebSocketConnected event will be triggered when the SDK is successfully connected to the Plivo servers. |
| `unregister()` | This method will unregister the SDK while keeping it connected to Plivo servers. |
| `disconnect()` | This method will disconnect the SDK from Plivo servers and unregister it. |
| `getContactUri()` | Returns a contact URI string that can be used to redirect a call to different tabs, typically used in multi-tab scenarios. |
| `redirect(uri)` | This method allows redirecting a call to the specified URI, directing it to the required tab. |
| `getCurrentSession()` | Returns the current active session. If there is no active session, it returns null; otherwise, it returns the active session object. |
| `setIdentifier()` | Helps to uniquely identify a tab. |
| `webRTC()` | Returns `true` if webRTC is supported and `false` if not. |
| `supportedBrowsers()` | Returns a string listing the browsers supported by the SDK. |
| `getIncomingCalls()` | Returns an array of all current incoming calls when `allowMultipleIncomingCalls` is enabled. |
| `getErrorStringByErrorCodes(errorCode)` | Returns a human-readable error string for a given error code. |
## Audio Device API
### Methods
| Method | Description |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `availableDevices(filter)` | Returns promise that resolves with an array of device objects.
The filter parameter is optional and takes a String value. Pass input to filter by input audio devices, output to filter by output audio devices, null to get all audio devices.
Wrapper for `MediaDevices.enumerateDevices()` that filters out non-audio devices.
**Note** :
1. When media permission is not given by users, labels do not appear. In this case, to get labels for a device, use revealAudioDevices(), then call availableDevices().
2. Device ID remains the same, unless the domain changes or private browsing mode is used. Refer: MediaDeviceInfo.deviceId
3. Device Enumerator API from browser can also be used to list devices IDs and labels — enumerateDevices. |
| `revealAudioDevices(arg)` | Returns a promise that resolves with `success` if user allows media permission. If `returnStream` is passed as an argument, the promise will resolve with the MediaStream object. |
### Objects
| Object | Methods and Parameters | Description |
| ------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `microphoneDevices` | `set(deviceID)`
`get()`
`reset()` | `set` takes the deviceID parameter and sets it as the default input device for taking input audio. The deviceID parameter is mandatory and takes a String value.
`get` returns the input audio device ID that is set.
`reset` removes any input audio device ID that is already set. |
| `speakerDevices` | `set(deviceID)`
`get()`
`reset()`
`media(source)` | `set` sets the audioDevice ID as default speaker device for DTMF and remote audio. The deviceID parameter is mandatory and takes a String value.
`get` returns the speaker device ID that is set.
`reset` removes any speaker device ID that is already set.
`media` takes `dtmf` or `ringback` as a source parameter and returns the corresponding HTML audio element. This parameter is mandatory. |
| `ringtoneDevices` | `set(deviceID)`
`get()`
`reset()`
`media` | `set` takes the deviceID parameter and sets it as the ringtone device for playing an incoming call ringtone. The deviceID parameter is mandatory and takes a String value.
`get` returns the ringtone device ID that is set.
`reset` removes any ringtone device ID that is already set.
`media` returns the HTML audio element for playing the ringtone. |
## Events
| Event | Description |
| -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onLogin` | Occurs when a login is successful. |
| `onLoginFailed(cause)` | Occurs when a login has failed. `cause` returns the login failure reason. |
| `onLogout` | Occurs when a logout is successful. |
| `onCalling` | Occurs when a call is initiated. |
| `onCallRemoteRinging(callInfo)` | Occurs when the call is initiated towards the remote end from the plivo servers during an outbound call. |
| `onCallConnected(callInfo)` | Occurs when the PSTN remote end starts ringing during an outbound call. This event is not applicable for Multi-Party Call (MPC) or Conference based calls. |
| `onCallAnswered(callInfo)` | Occurs when an outbound or an inbound call is answered. |
| `onMediaConnected(callInfo)` | Occurs when the media connection is established. |
| `onCallTerminated(hangupInfo, callInfo)` | Occurs when an outbound or an inbound call has ended. |
| `remoteAudioStatus(bool)` | Provides a boolean value indicating audio activity from the remote party. True denotes the reception of an audio packet, while False indicates the absence of audio packet reception from the other end. This feature is exclusively accessible in conference or Multi-Party Call (MPC) calls. |
| `onIncomingCall(callerID, extraHeaders, callInfo, callerName)` | Occurs when there is an incoming call. `callerID` provides the caller ID, `callerName` provides the caller name set by the initiator of the call, and `extraHeaders` return the X-Headers from Plivo. |
| `onIncomingCallCanceled(callInfo)` | Occurs when an incoming call is canceled by the caller. |
| `onIncomingCallIgnored(callInfo)` | Occurs when an incoming call is successfully ignored using the ignore(callUUID) function. |
| `onCallFailed(cause, callInfo)` | Occurs when an outbound or an inbound call fails. `cause` returns the reason for call failing.
Possible error events:
`INVALID_ACCESS_TOKEN`
`INVALID_ACCESS_TOKEN_HEADER`
`INVALID_ACCESS_TOKEN_ISSUER`
`INVALID_ACCESS_TOKEN_SUBJECT`
`ACCESS_TOKEN_NOT_VALID_YET`
`ACCESS_TOKEN_EXPIRED`
`INVALID_ACCESS_TOKEN_SIGNATURE`
`INVALID_ACCESS_TOKEN_GRANTS`
`EXPIRATION_EXCEEDS_MAX_ALLOWED_TIME`
`MAX_ALLOWED_LOGIN_REACHED` |
| `onMediaPermission(event)` | Occurs when media permission has been granted. `event` returns the stream access status. The success event returns `{'status':'success','stream':true}`. On failure the event returns `{'status':'failure','error':errorName}`. |
| `onWebrtcNotSupported` | Occurs when browser does not support WebRTC. |
| `mediaMetrics` | Works only for Chrome. Object sent in the event callback:
**high\_jitter**: when the jitter is higher than 30 ms for three out of last five samples.
\{
group: 'network',
level: 'warning',
type: 'high\_jitter',
value: '\',
active: true \|\| false, //Will be false when value goes to normal level.
desc: 'jitterLocalMeasures' \|\| 'jitterRemoteMeasures',
stream: 'local \|\| remote'
}
**high\_rtt**: When the RTT is higher than 400 ms for three out of last five samples.
\{
group: 'network',
level: 'warning',
type: 'high\_rtt',
value: '\',
active: true \|\| false, //Will be false when value goes to normal level.
desc: 'high latency',
stream: 'None'
}
**high\_packetloss**: When the packet loss is > 10% for Opus and loss > 20% PCMU.
\{
group: 'network',
level: 'warning',
type: 'high\_packetloss',
value: '\';,
active: true \|\| false, //Will be false when value goes to normal level.
desc: 'packetLossLocalMeasure' \|\| 'packetLossRemoteMeasure',
stream: 'local \|\| remote'
}
**low\_mos**: When sampled MOS is \< 3 for three out of last five samples, no\_microphone\_access When we detect one way audio (\<80 bytes sent in three seconds).
\{
group: 'network',
level: 'warning',
type: 'low\_mos',
value: '\',
active: true \|\| false, //Will be false when value goes to normal level.
desc: 'mosRemoteMeasure',
stream: 'None'
}
**no\_audio\_received** : When remote or local audio is silent.
\{
group: 'audio',
level: 'warning',
type: 'no\_audio\_received',
value: '\',
active: true \|\| false, //Will be false when value goes to normal level.
desc: 'local\_audio' \|\| 'remote\_audio',
stream: 'local \|\| remote'
}
**ice\_timeout** : Alert if ICE gathering takes more than two seconds either for outgoing call invite or incoming call answer.
\{
group: 'network',
level: 'warning',
type: 'ice\_timeout',
value: '2000',
active: true,
desc: 'Possible NAT/Firewall issue',
stream: 'None'
}
**no\_microphone\_access** : When Chrome losses access to microphone. This event is generated if preDetectOwa is set to true.
\{
group: 'audio',
level: 'warning',
type: 'no\_microphone\_access',
active: true,
desc: 'Chrome lost access to microphone — restart browser',
stream: 'None'
}
**ice\_connection** : When call's ICE connection state changes.
\{
group: 'network',
level: 'warning',
type: 'ice\_connection',
active: true \|\| false, // Will be false when value is 'connected'
value: 'connected' \|\| 'disconnected' \|\| 'failed',
desc: 'network drop', //when value is 'connected'
stream: 'None'
}
**mute\_detection**: Speech is detected when the call is muted during an ongoing conversation.
\{
group: 'audio',
level: 'warning',
type: 'speaking\_on\_mute',
active: true
value: '0',
desc: 'User is trying to speak on mute'
stream: 'None'
} |
| `audioDeviceChange(deviceObj)` | Occurs when a USB audio device is added or removed. This event emits an object with two properties: `change` and `device`. `change` may have the values `added` or `removed`. `device` provides device-specific properties. |
| `onConnectionChange` | Generated when the state of Plivo's WebSocket connection changes; for example, when the WebSocket is disconnected due to internet issues.
On WebSocket disconnect
\{
'state':'disconnected',
'eventCode':\,
'eventReason':\
}
On WebSocket reconnect
\{
'state':'connected'
}
Common WebSocket event codes (`RFC 6455`)
1006 indicates that the connection was closed abnormally, without sending or receiving a Close control frame. For example, internet disconnection.
1009 indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process.
1011 indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. |
| `onNoiseReductionReady` | Upon initialization of the SDK with the "enableNoiseReduction" flag, a necessary file for call processing is loaded. Once the file is successfully loaded and prepared for use, the "onNoiseReductionReady" event is triggered. Subsequently, you have the option to initiate noise suppression by calling the "startNoiseReduction()" function at any point. |
| `onWebSocketConnected` | This event triggers when the SDK is connected to the Plivo servers. |
| `volume(audioStats)` | Display user real-time volume of mic and speaker.
The volume event handler is invoked 60 times per second. The handler receives inputVolume and outputVolume as percentages of maximum volume represented by a floating point number between 0.0 and 1.0, inclusive. This value represents a range of relative decibel values between -100dB and -30dB.
audioStats JSON object:
\{
'inputVolume': '\',
'outputVolume': '\'
}
'inputVolume': input device volume (mic)
'outputVolume': output device volume (speaker) |
| `onDtmfReceived(dtmfData)` | DTMF received from the other end during an ongoing call.
dtmf data JSON object:
\{
tone: '\',
duration: '\',
};
'tone': dtmf tone received from other end
'duration': duration of the tone received |
## CallInfo Object
A CallInfo object is passed as a parameter for the following event callbacks:
1. onCallRemoteRinging
2. onCallConnected
3. onCallAnswered
4. onMediaConnected
5. onCallTerminated
6. onIncomingCall
7. onIncomingCallCanceled
8. onIncomingCallIgnored
9. onCallFailed
This JSON object contains the callUUID as well as other information about the call for which the event was generated.
| Property | Description |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `callUUID` | The UUID of the call. |
| `direction` | The call direction. Can be `INCOMING` or `OUTGOING`. |
| `src` | The source address for the call.
Will be the SIP URI of the endpoint in the case of an outgoing call.
Will be the FROM number/endpoint in the case of an incoming call. |
| `dest` | The destination address for the call.
Will be the TO number/endpoint in the case of an outgoing call.
Will be the the SIP URI of the endpoint in the case of an incoming call. |
| `extraHeaders` | The extraHeaders (json object) sent to or received from the Plivo SIP server. |
| `Reason` | Indicates the cause of disconnection. |
| `Protocol` | The values can be either Q.850 or SIP. |
| `Code` | Hangup error code from SIP. |
| `Originator` | Source of disconnection, with possible values being remote or local. |
| `state` | The current state of the call.
Can be one of:
1. ringing
2. answered
3. rejected
4. ignored
5. canceled
6. failed
7. ended
Call state will be set to failed if an error leads to the call being hung up before it could be answered. |
## Examples
Visit our GitHub repo for [examples](https://github.com/plivo/plivo-browser-sdk2-examples/tree/master).
# Troubleshooting Call Failures
Source: https://plivo.com/docs/voice/troubleshooting/call-failures
Debug and resolve voice call issues including failed connections, one-way audio, and quality problems
Use this guide to diagnose and fix common voice call issues. Start with the symptom you're experiencing.
***
## Quick Diagnosis
**Check in order:**
1. Verify credits balance in Console → Billing
2. Check geo permissions for destination country
3. Verify caller ID is a Plivo number or verified
4. Review [hangup cause](/docs/voice/troubleshooting/hangup-causes) in call logs
**Common causes:**
| Hangup Cause | Solution |
| ---------------------------- | --------------------------------------------------- |
| `destination_country_barred` | Enable country in Console → Voice → Geo Permissions |
| `unknown_caller_id` | Use Plivo-rented number as caller ID |
| `insufficient_credits` | Add credits to account |
| `invalid_destination` | Use E.164 format (+14155551234) |
**Check in order:**
1. Verify number is assigned to an application (Console → Phone Numbers)
2. Check application Answer URL is accessible
3. Verify Answer URL returns valid Plivo XML
4. Check for firewall blocking Plivo IPs
**Debug steps:**
1. Go to Console → Voice → Logs → Calls
2. Find the failed call
3. Check the hangup cause and debug logs
4. Test your Answer URL manually with curl
**Common causes:**
* Firewall blocking RTP/media ports
* NAT traversal issues
* Codec mismatch
**Solutions:**
1. Whitelist Plivo IP ranges for UDP ports 10000-60000
2. Enable STUN/TURN if behind NAT
3. Use standard codecs (G.711, Opus)
See [Plivo IP Ranges](https://www.plivo.com/docs/voice/concepts/ip-addresses/) for whitelisting.
**Check hangup cause in call logs:**
| Hangup Cause | Meaning | Solution |
| ---------------------- | --------------------------- | ------------------------------- |
| `scheduled_hangup` | Max duration reached | Increase `time_limit` parameter |
| `media_timeout` | No audio for 60 seconds | Check network stability |
| `xml_end` | No more XML instructions | Add more XML or use `` |
| `insufficient_credits` | Ran out of credits mid-call | Enable auto-recharge |
| Issue | Likely Cause | Solution |
| ------------- | ----------------- | ------------------------------------------------- |
| Echo | Acoustic feedback | Use headset, reduce speaker volume |
| Delay/latency | Network distance | Use nearest Plivo region |
| Choppy audio | Packet loss | Check internet connection, reduce bandwidth usage |
| Robotic voice | Codec issues | Use G.711 codec |
For persistent issues, capture a PCAP and contact [Plivo Support](https://support.plivo.com).
***
## Step-by-Step Debugging
### 1. Check Call Logs
1. Go to **Console → Voice → Logs → Calls**
2. Find the failed call by time or phone number
3. Note the **Hangup Cause** and **Hangup Source**
4. Click the call to view debug details
### 2. Verify Configuration
**For outbound calls:**
```bash theme={null}
# Test your setup with curl
curl -i --user AUTH_ID:AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{"from": "+14155551234", "to": "+14155559876", "answer_url": "https://example.com/answer"}' \
https://api.plivo.com/v1/Account/{auth_id}/Call/
```
**For inbound calls:**
* Verify number → application assignment in Console
* Test Answer URL returns valid XML
### 3. Test Answer URL
Your Answer URL must:
* Return HTTP 200 status
* Return `Content-Type: application/xml` or `text/xml`
* Return valid [Plivo XML](/docs/voice/xml/overview)
**Example valid response:**
```xml theme={null}
Hello, this is a test call.
```
### 4. Check Firewall Settings
Plivo requires these ports open:
| Traffic | Protocol | Ports |
| --------------- | -------- | ----------- |
| SIP signaling | UDP/TCP | 5060, 5080 |
| Secure SIP | TLS | 5061 |
| RTP (audio) | UDP | 10000-60000 |
| HTTPS callbacks | TCP | 443 |
See [IP Addresses](/docs/voice/concepts/firewall-network-configuration) for ranges to whitelist.
***
## Common Error Scenarios
### "Call immediately goes to voicemail"
**Possible causes:**
1. Carrier is blocking based on caller ID reputation
2. Number flagged as spam
3. Destination has call blocking enabled
**Solutions:**
* Register for STIR/SHAKEN attestation
* Use a different caller ID
* Contact carrier about spam flagging
### "API returns 403 Forbidden"
**Check:**
1. Account is verified and active
2. Geo permissions enabled for destination
3. Caller ID is verified or Plivo-owned
4. No outstanding balance issues
### "Calls work sometimes but not always"
**Debug steps:**
1. Check if failures correlate with specific destinations
2. Review call volume vs CPS limits
3. Check for carrier-specific issues in logs
4. Monitor for pattern (time of day, destination, etc.)
***
## Debug Logs
For detailed debugging, enable debug logs:
1. Go to **Console → Voice → Logs → Calls**
2. Click on the specific call
3. View the **Debug** tab for:
* XML requests/responses
* SIP signaling details
* Timing information
***
## When to Contact Support
Contact [Plivo Support](https://support.plivo.com) if:
* Issue persists after following this guide
* You see `internal_error` or `routing_error` hangup causes
* Calls fail with no clear hangup cause
* You need PCAP analysis for audio issues
**Include in your support request:**
* Call UUID(s)
* Timestamp of failures
* Steps already tried
* Any error messages
***
## Related
* [Hangup Causes Reference](/docs/voice/troubleshooting/hangup-causes)
* [Voice API Overview](/docs/voice/api/overview)
* [IP Addresses](/docs/voice/concepts/firewall-network-configuration)
* [Account Limits](/docs/voice/concepts/account-limits)
# Hangup Causes
Source: https://plivo.com/docs/voice/troubleshooting/hangup-causes
Voice API hangup codes, causes, and troubleshooting
Plivo identifies why and how calls are disconnected in call detail records (CDR), which you can [retrieve via API](/docs/voice/api/calls#retrieve-a-call) or view on the Plivo console at Voice → Logs → [Calls](https://cx.plivo.com/logs?tab=voice).
Hangup information is also included in callback requests:
* **Outbound API calls**: Sent to `hangup_url` specified in [Make Call API](/docs/voice/api/calls#create-a-call)
* **Incoming calls**: Sent to `hangup_url` in the [Plivo application](/docs/account/api/application/)
* **Dial XML calls**: Sent to `callbackUrl` in DialHangup events
***
## Hangup Sources
| Source | Description |
| ------------------ | ------------------------------------------------------- |
| **Caller** | Call hung up by the caller |
| **Call recipient** | Call hung up by the dialed party |
| **Plivo** | Plivo initiated hangup (various reasons detailed below) |
| **Carrier** | Hangup signal from remote carrier |
| **API Request** | Terminated via Hangup or Cancel Call API |
| **Answer XML** | Hung up using Hangup XML element |
| **Error** | Error condition terminated the call |
| **Unknown** | Hangup source could not be determined |
***
## Hangup Causes
Normal call terminations - typically no action required.
| Code | Cause | Description | Next Steps |
| ---- | ------------------------------- | ----------------------------------- | ---------------------------------------------- |
| 4000 | `Normal Hangup` | Call terminated normally | None - call completed successfully |
| 4010 | `End Of XML Instructions` | No more XML instructions to execute | None - normal for XML-controlled calls |
| 4020 | `Multiparty Call Ended` | MPC ended via API or max duration | None - check if max duration was intentional |
| 4030 | `Kicked Out Of Multiparty Call` | Participant removed via API | None - verify participant removal was expected |
Calls canceled before being answered.
| Code | Cause | Description | Next Steps |
| ---- | -------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------ |
| 0 | `Unknown` | Hangup reason undetermined. Known bug: Delete All Calls API sets this | Check call logs for context |
| 1000 | `Canceled` | Call canceled via Hangup Call API before answer | None - intentional cancellation |
| 1010 | `Canceled (Out Of Credits)` | Account ran out of credits | Add credits. Enable auto-recharge in Console → Billing |
| 1020 | `Canceled (Simultaneous dial limit reached)` | Simultaneous dial limit exceeded | Reduce concurrent dials to same destination |
Issues with the destination number or endpoint.
| Code | Cause | Description | Next Steps |
| ---- | ----------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------- |
| 2000 | `Invalid Destination Address` | Destination number/endpoint invalid | Use E.164 format (+14151234567). Verify number is valid |
| 2010 | `Destination Out Of Service` | Destination unavailable | Retry later. Verify destination is active |
| 2020 | `Endpoint Not Registered` | SIP endpoint unregistered/unreachable | Verify endpoint is logged in. Check [SDK troubleshooting](/docs/voice/client/androidios/overview) |
| 2030 | `Destination Country Barred` | Country disabled in geo permissions | Enable country in Console → Voice → [Geo Permissions](https://cx.plivo.com/geo-permissions/voice) |
| 2040 | `Destination Number Barred` | Premium rate numbers disabled | Enable high-risk permissions in Console → Voice → Geo Permissions |
| 2050 | `Destination Prefix Barred` | Prefix not permitted | Enable prefix in Console → Voice → Geo Permissions |
| 2060 | `Loop Detected` | B-leg would redial A leg's number | Fix routing logic to prevent loops |
| 2070 | `Violates Media Anchoring` | India PSTN regulation violation | For India calls: server must be in India. Don't mix PSTN and WebRTC in conferences |
Calls rejected by destination or carrier.
| Code | Cause | Description | Next Steps |
| ---- | -------------------- | ------------------------------------- | ------------------------------------------- |
| 3000 | `No Answer` | Destination unavailable/unreachable | Retry. Check if destination is online |
| 3010 | `Busy Line` | Destination is busy | Retry later or implement voicemail fallback |
| 3020 | `Rejected` | Call rejected by called party | None - recipient declined the call |
| 3030 | `Unknown Caller ID` | Non-Plivo number used as caller ID | Use a Plivo-rented number as caller ID |
| 3040 | `Forbidden` | Destination rejected/blocked call | Have recipient check for blocked numbers |
| 3050 | `Unallocated number` | Destination invalid or out of service | Verify destination number accuracy |
Errors from remote carrier or network.
| Code | Cause | Description | Next Steps |
| ---- | ------------------------------------ | ------------------------------------ | -------------------------------------------------------------- |
| 3070 | `Request timeout` | Carrier didn't respond in time | Retry. Check carrier availability |
| 3080 | `Internal server error from carrier` | Carrier encountered error | Retry. If persistent, contact support |
| 3090 | `Network congestion from carrier` | Carrier network overloaded | Retry with backoff |
| 3100 | `Busy everywhere` | All destination endpoints busy | Retry later |
| 3110 | `Declined` | Destination cannot/won't participate | Verify destination accepts calls |
| 3120 | `User does not exist anywhere` | End user doesn't exist | Verify destination number |
| 3130 | `Spam block` | Carrier rejected due to spam flag | Register number with STIR/SHAKEN. Consider different caller ID |
| 3140 | `DNO Caller ID` | Caller ID on Do Not Originate list | Use different number - this one is inbound-only |
Calls that failed [SIP authentication](/docs/voice/concepts/sip-authentication/). See that page for setup, validation limits, and detailed troubleshooting.
| Code | Cause | Description | Next Steps |
| ---- | ------------------ | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| 4210 | `sip_auth_failed` | Inbound caller failed IP ACL or credential check | Verify the caller's IP matches an ACL entry. For credentials, check username/password match exactly |
| 4240 | `sip_auth_failed` | Outbound credentials were rejected by the remote provider | Verify username/password with the provider. Check if the provider uses IP auth instead of digest |
| 4250 | `sip_auth_timeout` | Remote provider did not respond to the authentication attempt | Provider may be unreachable. Check network connectivity and provider status |
Internal system, network, or capacity errors.
| Code | Cause | Description | Next Steps |
| ---- | ---------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------- |
| 5000 | `Network Error` | Fatal network condition | [Contact Plivo support](https://support.plivo.com) with call UUID |
| 5010 | `Internal Error` | Plivo system error | [Contact Plivo support](https://support.plivo.com) with call UUID |
| 5020 | `Routing Error` | Could not route to destination | [Contact Plivo support](https://support.plivo.com) with call UUID |
| 5030 | `Concurrency Limit Breached` | India concurrent call limit exceeded | Reduce active calls or [upgrade CPS](/docs/voice/concepts/india-concurrency/) to increase capacity |
Calls ended due to timeout conditions.
| Code | Cause | Description | Next Steps |
| ---- | ---------------------- | -------------------------------- | ------------------------------------------------------------------------------------ |
| 6000 | `Scheduled Hangup` | Max call duration reached | None - configure `time_limit` (API) or `timeLimit` (Dial XML) if longer calls needed |
| 6010 | `Ring Timeout Reached` | Not answered within ring timeout | Increase `ring_timeout` (API) or `timeout` (Dial XML). Default is 120 seconds |
| 6020 | `Media Timeout` | No media packets for 60 seconds | Check network connectivity. May indicate lost connection |
Errors fetching or validating callback URLs.
| Code | Cause | Description | Next Steps |
| ---- | --------------------------------- | ---------------------------------- | -------------------------------------------------------- |
| 7011 | `Error Reaching Answer URL` | Non-2xx response from answer URL | Verify URL is accessible. Check server logs |
| 7012 | `Error Reaching Action URL` | Non-2xx response from action URL | Verify URL is accessible (only fails if `redirect=true`) |
| 7013 | `Error Reaching Transfer URL` | Non-2xx response from transfer URL | Verify URL is accessible |
| 7014 | `Error Reaching Redirect URL` | Non-2xx response from redirect URL | Verify URL is accessible |
| 7022 | `Invalid Action URL` | Action URL not valid | Ensure URL starts with `http://` or `https://` |
| 7023 | `Invalid Transfer URL` | Transfer URL not valid | Ensure URL starts with `http://` or `https://` |
| 7024 | `Invalid Redirect URL` | Redirect URL not valid | Ensure URL starts with `http://` or `https://` |
| 7032 | `Invalid Method For Action URL` | Unsupported HTTP method | Use only GET or POST |
| 7033 | `Invalid Method For Transfer URL` | Unsupported HTTP method | Use only GET or POST |
| 7034 | `Invalid Method For Redirect URL` | Unsupported HTTP method | Use only GET or POST |
Invalid Plivo XML returned by URLs.
| Code | Cause | Description | Next Steps |
| ---- | ---------------------- | --------------------------------- | ------------------------------------------------ |
| 8011 | `Invalid Answer XML` | Answer URL returned invalid XML | Check debug logs in Console. Validate XML syntax |
| 8012 | `Invalid Action XML` | Action URL returned invalid XML | Check debug logs. Only fails if `redirect=true` |
| 8013 | `Invalid Transfer XML` | Transfer URL returned invalid XML | Check debug logs. Validate XML syntax |
| 8014 | `Invalid Redirect XML` | Redirect URL returned invalid XML | Check debug logs. Validate XML syntax |
Specialized hangup scenarios.
| Code | Cause | Description | Next Steps |
| ---- | ------------------------------ | --------------------------------------- | --------------------------------------------- |
| 9000 | `Lost Race` | Another parallel B-leg answered first | None - normal for simultaneous dial |
| 9100 | `Machine Detected` | Answered by answering machine | None - occurs when `machine_detection=hangup` |
| 9110 | `Confirm Key Challenge Failed` | Participant failed to enter confirm key | Inform participant of required DTMF input |
Codes not listed here are surfaced in the API response's `hangup_cause_name`. If you encounter a code that is not documented, contact [Plivo Support](https://support.plivo.com) with the `call_uuid`.
***
## Other Code Spaces
These codes apply to Voice API and Dial XML calls. Related products use their own code sets:
* **SIP Trunking (Zentrunk)** calls use a separate set of hangup codes — see [Zentrunk Hangup Codes](/docs/sip-trunking/troubleshooting/zentrunk-hangup-codes).
* **Multiparty calls** expose a separate `termination_cause_code` field on the MPC object — see the [Multiparty Call API](/docs/voice/api/multiparty-calls). Individual participant legs still report the hangup causes above (for example, 4020 and 4030).
* **XML callbacks** also include a raw telephony `HangupCause` value (for example, `NORMAL_CLEARING`, `USER_BUSY`) — see [XML overview](/docs/voice/xml/overview#hangup-causes).
***
## Getting Help
If issues persist after troubleshooting:
1. View debug logs in Console → Voice → Logs → Calls
2. Note the Call UUID and hangup code
3. Contact [Plivo Support](https://support.plivo.com) with this information
# PINless Conference Calls
Source: https://plivo.com/docs/voice/use-cases/call-conference
Set up PINless conference calls to connect multiple participants on one call
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to implement a conference call
Create a file called `conference_call.js` and paste into it this code.
```js theme={null}
var express = require('express')
var app = express()
app.post('/conference_call/', function(req, res) {
var plivo = require('plivo');
var response = plivo.Response();
var speak_body = "You will now be placed into the demo conference";
response.addSpeak(speak_body);
var params = {
'startConferenceOnEnter': "true",
'endConferenceOnExit': "true"
};
var conference_name = "demo";
response.addConference(conference_name, params);
res.send(response.toXML());
})
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
$ node conference_call.js
```
You should see your basic server application in action at [http://localhost:3000/conference\_call/](http://localhost:3000/conference_call/).
## Create a Plivo application for the conference call
Associate the Node.js application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to implement a conference call
Change to the project directory and run this command to create a Rails controller for inbound calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This will generate a controller named plivo\_controller in the app/controllers/ directory and a view in app/views/plivo. We can delete the view as we don’t need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and paste this code into the PlivoController class:
```ruby theme={null}
def conference
response = Response.new
speak_body = 'You will now be placed into the demo conference'
response.addSpeak(speak_body)
params = {
'startConferenceOnEnter' => "false",
'waitSound' => "https://.com/waitmusic/"
}
conference_name = "demo"
response.addConference(conference_name, params)
xml = PlivoXML.new(response)
puts xml.to_xml
render xml: xml.to_xml
end
```
### Add a route
Add a route for the inbound function in the PlivoController class. Edit config/routes.rb and add the line below after the inbound route:
```shell theme={null}
get 'plivo/conference'
```
Now plivo\_controller is ready to forward incoming calls to your Plivo number. To start the Rails server, run
```shell theme={null}
$ rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/conference/](http://localhost:3000/plivo/conference/).
## Create a Plivo application for the conference call
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Flask application to implement a conference call
Create a file called `conference_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, Response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/conference_call/', methods=['GET', 'POST'])
def conference_cal():
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('You will now be placed into the demo conference'))
response.add(
plivoxml.ConferenceElement(
'demo',
start_conference_on_enter=False,
wait_sound='https://.com/waitmusic/'))
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Save the file and run it.
```shell theme={null}
$ python conference_call.py
```
You should see your basic server application in action at [http://localhost:5000/conference\_call/](http://localhost:5000/conference_call/).
## Create a Plivo application for the conference call
Associate the Python application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to implement a conference call
Change to the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller VoiceController
```
Edit the app/http/controllers/voiceController.php file and paste into it this code.
```php theme={null}
addSpeak($speak_body);
$params = array(
'startConferenceOnEnter' => "true",
'endConferenceOnExit' => "true"
);
$conference_name = "demo";
$response->addConference($conference_name, $params);
Header('Content-type: text/xml');
echo $response->toXML();
}
}
```
### Add a route
Add a route for the forward function in the VoiceController class. Edit routes/web.php and add this line.
```shell theme={null}
Route::match(['get', 'post'], '/conferencecall', 'VoiceController@conferenceCall');
```
Now VoiceController is ready to forward incoming calls to your Plivo number. Start the Laravel server.
```shell theme={null}
$ php artisan serve
```
You should see your basic server application in action at [http://localhost:8000/conferencecall/](http://localhost:8000/conferencecall/).
## Create a Plivo application for the conference call
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to implement a conference call
In Visual Studio, create a controller called `ConferencecallController.cs` and paste into it this code.
```cs theme={null}
using System;
using Plivo.XML;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace Conferencecall
{
public class ConferencecallController : Controller
{
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddSpeak("You will now be placed into the demo conference",
new Dictionary() { });
resp.AddConference("demo",
new Dictionary()
{
{"startConferenceOnEnter", "true"},
{"endConferenceOnExit", "true"},
{"waitSound", "https://.com/waitmusic/"}
});
var output = resp.ToString();
Console.WriteLine(output);
return this.Content(output, "text/xml");
}
}
}
```
Run the project and you should see your basic server application in action at [http://localhost:5000/conferencecall/](http://localhost:5000/conferencecall/).
## Create a Plivo application for the conference call
Associate the .NET application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application to implement a conference call
Ceate a Java class called `conferencecall` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Response;
public class conferencecall {
public static void main(String[] args) {
get("/conference_call/", (request, response) - > {
Response response = new Response()
.children(
new Speak("You will now be placed into the demo conference"),
new Conference("demo")
.endConferenceOnExit(true)
.startConferenceOnEnter(false)
.waitSound("https://.com/waitmusic/")
);
System.out.println(response.toXmlString());
// Returns the XML
return response.toXmlString();
});
}
}
```
Save the file and run the project, and you should see your basic server application in action at [http://localhost:4567/conference\_call/](http://localhost:4567/conference_call/).
## Create a Plivo application for the conference call
Associate the Java application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
## Overview
This guide shows how to create and configure conference calling, which lets you connect multiple people to one call at the same time.
You can implement PINless conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” using the [Conference XML](/docs/voice/xml/conference/) element.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to implement a conference call
Create a file called `conference_call.go` and paste into it this code.
```go theme={null}
package main
import (
"net/http"
"github.com/plivo/plivo-go/v7/xml"
)
func handler(w http.ResponseWriter, r *http.Request) {
response := xml.ResponseElement{
Contents: []interface{} {
new(xml.SpeakElement).
AddSpeak("You will now be placed into the demo conference"),
new(xml.ConferenceElement).
SetEndConferenceOnExit(true).
SetStartConferenceOnEnter(false).
SetWaitSound("https://.com/waitmusic/").
SetContents("demo"),
},
}
w.Write([]byte(response.String()))
return
}
func main() {
http.HandleFunc("/conference_call/", handler)
http.ListenAndServe(":8080", nil)
}
```
Save the file and run it.
```shell theme={null}
$ go run conference_call.go
```
You should see your basic server application in action at [http://localhost:8080/conference\_call/](http://localhost:8080/conference_call/).
## Create a Plivo application for the conference call
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be placed into a conference.
# Call Forwarding
Source: https://plivo.com/docs/voice/use-cases/call-forwarding
Route incoming calls dynamically based on availability, time, or location
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to forward incoming calls
Create a file called `forward_call.js` and paste into it this code.
```js theme={null}
var express = require('express')
var app = express()
app.post('/forward_call/', function(req, res) {
var plivo = require('plivo');
var response = plivo.Response();
var dial = response.addDial();
dial.addNumber(""); // call wll be forwarded to this number
res.send(response.toXML());
})
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the destination number placeholder with an actual phone number (for example, 12025551234).
Save the file and run it.
```shell theme={null}
$ node forward_call.js
```
## Create a Plivo application to forward calls
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to forward incoming calls
Edit the app/controllers/plivo\_controller.rb file and add this code in the PlivoController class:
```ruby theme={null}
def forward
response = Response.new
dial = response.addDial()
dest_number = ""
dial.addNumber(dest_number)
xml = PlivoXML.new(response)
puts xml.to_xml
render xml: xml.to_xml
end
```
### Add a route
Add a route for the inbound function in the **PlivoController** class. Edit config/routes.rb and add this line after the inbound route:
```shell theme={null}
get 'plivo/forward'
```
Now the controller is ready for inbound calls. Use this command to start the server to handle inbound calls.
```shell theme={null}
$ rails server
```
## Create a Plivo application to forward calls
Associate the Rails server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask server to forward incoming calls
Create a file called `forward_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, request, make_response, Response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/forward_call/', methods=['GET', 'POST'])
def forwardcall():
response = plivoxml.ResponseElement()
response.add(
plivoxml.DialElement().add(
plivoxml.NumberElement(''))) // call wll be forwarded to this number
return(response.to_string())
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Replace the destination number placeholder with an actual phone number (for example, 12025551234).
Save the file and run it.
```shell theme={null}
$ python forward_call.py
```
## Create a Plivo application to forward calls
Associate the Python application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel server to forward incoming calls
Change to the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller VoiceController
```
The command generates a controller named VoiceController in the app/http/controllers/ directory. Edit the app/http/controllers/voiceController.php file and paste into it this code.
```php theme={null}
"https://.com/dial_status/",
'method' => "POST",
'redirect' => "true"
);
$dial = $response->addDial($params);
$number = ""; // call will be forwarded to this number
$dial->addNumber($number);
Header('Content-type: text/xml');
echo $response->toXML();
}
}
```
Replace the destination number placeholder with an actual phone number (for example, 12025551234).
## Create a Plivo application to forward calls
Associate the Laravel server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to forward incoming calls
In Visual Studio, create a new project. Use the template for Web Application (Model-View-Controller). Navigate to the Controllers directory and create a controller called `ForwardcallController.cs`, and paste into it this code.
```cs theme={null}
using System;
using Plivo.XML;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace Receivecall
{
public class ForwardcallController : Controller
{
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {
});
dial.AddNumber("",
new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
return this.Content(output, "text/xml");
}
}
}
```
Replace the destination number placeholder with an actual phone number (for example, 12025551234).
## Create a Plivo application to forward calls
Associate the .NET application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Java server to forward incoming calls
Create a Java class called `ForwardCall` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Response;
public class forwardcall {
public static void main(String[] args) {
get("/forward_call/", (request, response) -> {
String from_number = request.queryParams("From");
response.type("application/xml");
Response res = new Response()
.children(
new Dial()
.callerId(from_number)
.children(
new Number("")
)
);
// Returns the XML
return res.toXmlString();
});
}
}
```
Replace the destination number placeholder with an actual phone number (for example, 12025551234).
## Create a Plivo application to forward calls
Associate the Java application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
## Overview
You can use call forwarding to dynamically route incoming calls based on any of several factors.
* **Agent availability:** You can place calls in a holding queue and route them to an available agent as soon as one is available.
* **Business hours:** You can route calls to an office number during business hours and to a mobile phone or voicemail during non-business hours.
* **Time zones:** You can forward calls to agents from different time zones to ensure round-the-clock availability.
This guide shows how to forward calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to use Plivo XML to forward calls.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo forwards the call using the [Dial XML](/docs/voice/xml/routing#dial) element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to forward incoming calls
Create a file called `forward_call.go` and paste into it this code.
```go theme={null}
package main
import (
"net/http"
"plivo-go/xml"
)
func handler(w http.ResponseWriter, r *http.Request) {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).
SetContents(
[]interface{}{
new(xml.NumberElement).
SetContents(""),
},
),
},
}
w.Write([]byte(response.String()))
}
func main() {
http.HandleFunc("/forward_call/", handler)
http.ListenAndServe(":8080", nil)
}
```
Replace the destination number placeholder with an actual phone number (for example, 12025551234).
Save the file and run it.
```shell theme={null}
$ go run forward_call.go
```
## Create a Plivo application to forward calls
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Forward Call`. Enter the server URL you want to use (for example `https://.com/forward_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Forward Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then forward the call according to the instructions in the XML document the server provides.
# Call Tracking
Source: https://plivo.com/docs/voice/use-cases/call-tracking
Track and analyze inbound calls to measure marketing campaign performance
Call tracking lets marketers measure the performance of marketing campaigns both online (such as with Google Ads) and offline (using newspaper, billboards, etc.) via analytics of inbound calls. With call tracking, you can see how many times a phone number has been called, the duration of each call, the number and location of the caller, and more. These analytics helps companies track conversion rates across all marketing channels to optimize marketing ROI and identify unique behaviors of highly qualified leads.
## Basic call tracking
Plivo lets you retrieve call analytics on all live and completed calls to and from Plivo phone numbers. We provide examples and [server SDKs](/docs/sdk/server/) so that you can add the functionality in any web standard languages you need.
To get all call details, set your URI to:
```sh theme={null}
URI: https://api.plivo.com/v1/Account/{auth_id}/Call/
Method: GET
```
Plivo will return values for these parameters:
```json theme={null}
[{
"call_duration": 3,
"total_amount": "0.02000",
"parent_call_uuid": null,
"call_direction": "outbound",
"to_number": "",
"total_rate": "0.02000",
"from_number": "",
"end_time": "2022-08-20T10:53:17",
"call_uuid": "xxx-1111-xxxx-",
"resource_uri": "/v1/Account/XXXXXXXXXXXXXXXX/Call/XXXX1/"
},
{
"call_duration": 3,
"total_amount": "0.02000",
"parent_call_uuid": null,
"call_direction": "inbound",
"to_number": "xxxxxxxxx",
"total_rate": "0.02000",
"from_number": "xxxxxxxxx",
"end_time": "2022-08-20T10:59:16",
"call_uuid": "xxx-2222-xxxx-",
"resource_uri": "/v1/Account/XXXXXXXXXXXXXXXX/Call/XXXX2/"
}]
```
# Click to Call
Source: https://plivo.com/docs/voice/use-cases/click-to-call
Set up click-to-call for website visitors using the Plivo Browser SDK
Click-to-call enables your website users to engage with your support and sales teams on the website itself. Sometimes they want to speak to someone via their handset but initiate the call online or talk to someone directly from the website. You can implement this click to call use case using Plivo's Browser SDK.
## How it works
The [Plivo Browser SDK](/docs/sdk/client/browser/reference/) lets you make and receive calls using Plivo applications directly from any web browser.
User enters their phone number in the settings. When a call is placed, the user's handset is called first, then the call is connected to the destination number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). Click to call requires JavaScript; we recommend using Node.js. If this is your first time triggering a PHLO with Node.js, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
### Create a PHLO to handle call logic
To create a PHLO, visit the [PHLO](https://cx.plivo.com/agents) page of the Plivo console. If this is your first PHLO, the PHLO page will be empty.
* Click **Create New PHLO**.
* In the **Choose your use case** pop-up, click **Build my own**. The PHLO canvas will appear with the **Start** node.
**Note**: The Start node is the starting point of any PHLO. It lets you trigger a PHLO to start upon one of three actions: incoming SMS message, incoming call, or API request.
* Click the **Start** node to open the Configuration tab, and then enter the information to retrieve from the HTTP Request payload — in this case key names are `destinationNumber` and `phoneMeNumber`. The values will remain blank as we will receive them when the request is made by the browser.
* Validate the configuration by clicking **Validate**. Do the same for each node as you go along.
* From the list of components on the left side, drag and drop the **Initiate Call** component onto the canvas. This adds an Initiate Call node onto the canvas. When a component is placed on the canvas it becomes a node.
* Draw a line to connect the **Start** node’s **API Request** trigger state to the **Initiate Call** node.
* In the Configuration tab of the **Initiate Call** node, give the node a name. To enter values for the **From** and **To** fields, enter two curly brackets to view all available variables, and choose the appropriate ones. The values for the numbers will be retrieved from the HTTP Request payload you defined in the Start node. Here **From** is **14159142884** and **To** is **\{\{Start.http.params.phoneMeNumber}}**.
* From the list of components on the left side, drag and drop the **Call Forward** component onto the canvas. Draw a line to connect the **Answered** trigger state of the **Initiate Call** node with the **Call Forward** node.
* Configure the **Call Forward** node to initiate call forward to another user. To enter values for the **From** and **To** fields, enter two curly brackets to view all available variables, and choose the appropriate ones. The values for the numbers will be retrieved from the HTTP Request payload you defined in the Start node. Here **From** is **\{\{Start.http.params.phoneMeNumber}}** and **To** is **\{\{Start.http.params.destinationNumber}}**.
* After you complete and validate the node configurations, give the PHLO a name by clicking in the upper left, then click **Save**.
* From the list of components on the left side, drag and drop the **Call Forward** component onto the canvas.
* Draw a line to connect the **Start** node’s **Incoming call** trigger state to the **Call Forward** node.
* In the Configuration tab of the **Call Forward** node, give the node a name. To enter values for the **From** and **To** fields, enter two curly brackets to view all available variables, and choose the appropriate ones. The values for the numbers will be retrieved from the HTTP Request payload you defined in the Start node. Here **From** is **\{\{Start.http.params.header1}}**. and **To** is **\{\{Start.http.params.to}}**.
* After you complete and validate the node configurations, give the PHLO a name by clicking in the upper left, then click **Save**.
Your complete PHLO should look like this:
## Set up the demo application locally
Download and modify the code to trigger the PHLO.
* Clone the repository from [GitHub](https://github.com/plivo/click2call-webRTC.git).
```shell theme={null}
git clone https://github.com/plivo/click2call-webRTC.git
```
* Change your working directory to click2call-webRTC.
```shell theme={null}
cd click2call-webRTC
```
* Install the necessary dependencies using the package.json file.
```shell theme={null}
npm install
```
* Edit the **.env** file. Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Enter your PHLO ID, which you can find on the [Plivo console](https://cx.plivo.com/agents).
```shell theme={null}
PORT="8080"
PLIVO_AUTH_ID=""
PLIVO_AUTH_TOKEN=""
PHLO_ID=""
```
* Edit **/client/src/index.jsx** and replace the caller\_id placeholder with a Plivo number.
```sh theme={null}
const customCallerId = ;
const extraHeaders = {
'X-PH-Test1': 'test1',
'X-PH-callerId': customCallerId
};
this.plivoBrowserSdk.client.call(dest, extraHeaders);
```
## A review of the code
Let‘s walk through what the code does. The PHLO can be triggered either by an incoming call or an HTTP request.
### Broswer SDK call
When someone clicks on an application button to initiate a call, we can use the Browser SDK‘s **call()** method to initiate a call from the application endpoint to the destination phone number. In this case our PHLO is the endpoint, so our outbound call is treated as an *incoming* call to our PHLO. When the request we make from the browser reaches the endpoint, the browser is connected to Plivo via the endpoint and the endpoint is attached to the PHLO, so when the browser makes a request to Plivo as an incoming call, Plivo connects to the endpoint, which in turn triggers the PHLO to forward the call to the destination number.
The code looks like this.
```js theme={null}
const customCallerId = ;
const extraHeaders = {
'X-PH-Test1': 'test1',
'X-PH-callerId': customCallerId
};
this.plivoBrowserSdk.client.call(dest, extraHeaders);
```
Here the **extraHeaders** is used to pass the caller\_id for a call initiated by the broswer.
### Click to call
Click to call is a more complicated use case because it requires us to actually send an HTTP request with a payload to the PHLO endpoint. Remember that we‘re making a call to our user‘s handset first, then connecting to the destination once the first call is answered. We need to get both phone numbers from the application and send them to the server. The code looks like this.
```js theme={null}
let XMLReq = new XMLHttpRequest();
XMLReq.open("POST", "/makeCall");
XMLReq.setRequestHeader("Content-Type", "application/json");
XMLReq.onreadystatechange = function() {
console.log('response text', XMLReq.responseText);
}
XMLReq.send(JSON.stringify({
"src": this.state.phoneMeNumber,
"dst": dest
}));
```
We need to listen for this request on the server. Once we receive the request and get the numbers from the payload, we set up another HTTP request that sends this data to the PHLO.
```js theme={null}
// when we receive an http post request
app.post('/makeCall/', function(req, res) {
console.log(req.fields);
jsonObject = JSON.stringify({
"phoneMeNumber": req.fields.src,
"destinationNumber": req.fields.dst,
});
// prepare the header
let postHeaders = {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + new Buffer.from(process.env. +':' + process.env.).toString('base64')
};
// set the post options
let postOptions = {
port: 443,
host: 'phlo-runner-service.plivo.com',
path: process.env.,
method: 'POST',
headers: postHeaders,
};
// do the POST request
let reqPost = https.request(postOptions, function(response) {
console.log("statusCode: ", response.statusCode);
response.on('data', function(d) {
console.info('POST result:\n');
process.stdout.write(d);
console.info('\n\nPOST completed');
res.send(d);
});
});
// write the json data
console.log(jsonObject);
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) { // log any errors
console.error(e);
});
})
```
## Assign the PHLO to a Plivo number
Once you’ve created and configured your PHLO, assign it to a Plivo number.
* On the [Numbers](https://cx.plivo.com/phone-numbers) page of the console, under **Your Numbers**, click the phone number you want to use for the PHLO.
* In the **Number Configuration** box, select **PHLO** from the **Application Type** drop-down.
* From the **PHLO Name** drop-down, select the PHLO you want to use with the phone number, then click **Update Number**.
## Test
Run these commands.
```shell theme={null}
npm run watch
npm run start
```
You should see your basic server application running at [http://localhost:8080/](http://localhost:8080/). Set up ngrok to expose your local server to the internet. Now make a call from your browser-based application to test it.
**Note**: If you’re using a Plivo Trial account, you can make calls only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers [Sandbox Numbers](https://cx.plivo.com/home) page.
# Conference Calling with a PIN
Source: https://plivo.com/docs/voice/use-cases/conference-with-pin
Create secure conference calls with PIN-based access control
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to implement a conference call with PIN
Create a file called `conference_call.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.set('port', (process.env.PORT || 5000));
// Message that Plivo reads when the caller dials in
var WelcomeMessage = "Welcome to the demo. Press 1234 to join the conference";
// Message that Plivo reads when the caller does nothing
var NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number.
var WronginputMessage = "Sorry, that's an invalid PIN";
app.post('/conference/', function(request, response) {
var r = plivo.Response();
var getinput_action_url, params, get_input;
getinput_action_url = request.protocol + '://' + request.headers.host + '/conference/firstbranch/';
params = {
'action': getinput_action_url,
'method': 'POST',
'inputType': 'dtmf',
'digitEndTimeout': '5',
'numDigits': '5',
'redirect': 'true',
};
get_input = r.addGetInput(params);
get_input.addSpeak(WelcomeMessage);
r.addSpeak(NoinputMessage);
console.log(r.toXML());
response.set({'Content-Type': 'text/xml'});
response.send(r.toXML());
});
app.post('/conference/firstbranch/', function(request, response) {
var r = plivo.Response();
var getinput_action_url, params, get_input;
var digit = request.query.Digits;
console.log(digit);
if (digit === '1234') {
var params = {
'startConferenceOnEnter': "true",
'endConferenceOnExit': "true"
};
var conference_name = "demo";
r.addConference(conference_name, params);
} else {
r.addSpeak(WronginputMessage);
}
console.log(r.toXML());
response.set({'Content-Type': 'text/xml'});
response.send(r.toXML());
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
$ node conference_call.js
```
You should see your basic server application in action at [http://localhost:3000/conference/](http://localhost:3000/conference/).
## Create a Plivo application for the conference call
Associate the Express application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to implement a conference call with PIN
Change to the project directory and run this command to create a Rails controller for inbound calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This will generate a controller named plivo\_controller in the app/controllers/ directory and a view in app/views/plivo. We can delete the view as we don’t need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and paste this code into the PlivoController class:
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
# Message that Plivo reads when the caller dials in
$welcome_message = "Welcome to the demo. Press 1234 to join the conference"
# Message that Plivo reads when the caller does nothing
$noinput_message = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller enters an invalid number
$wronginput_message = "Sorry, that's and invalid PIN"
def conference
r = Response.new()
getinput_action_url = "https://.com/firstbranch/"
params = {
action: getinput_action_url,
method: 'POST',
digitEndTimeout: '5',
inputType:'dtmf',
numDigits:'4',
redirect:'true'
}
getinput = r.addGetInput(params)
getinput.addSpeak($welcome_message)
r.addSpeak($noinput_message)
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
def firstbranch
digit = params[:Digits]
r = Response.new()
if (digit == "1234")
params = {
'startConferenceOnEnter' => "false",
'waitSound' => "https://.com/waitmusic/"
}
conference_name = "demo"
r.addConference(conference_name, params)
else
r.addSpeak($wronginput_message)
end
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
end
```
### Add a route
Add a route for the inbound function in the PlivoController class. Edit config/routes.rb and add these lines after the inbound route.
```shell theme={null}
get 'plivo/conference'
get 'plivo/firstbranch'
```
Now plivo\_controller is ready for your first inbound call. To start the Rails server, run
```shell theme={null}
$ rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/conference/](http://localhost:3000/plivo/conference/).
## Create a Plivo application for the conference call
Associate the Rails application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask application to implement a conference call with PIN
Create a file called `conference_call.py` and paste into it this code.
```py theme={null}
# -*- coding: utf-8 -*-
from flask import Flask, Response, request, url_for
from plivo import plivoxml
# Message that Plivo reads when the caller dials in
welcome_message = "Welcome to the demo. Press 1234 to join the conference"
# Message that Plivo reads when the caller does nothing
noinput_message = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller enters an invalid number
wronginput_message = "Sorry, that's an invalid PIN"
app = Flask(__name__)
@app.route('/conference/', methods=['GET','POST'])
def conference():
response = plivoxml.ResponseElement()
getinput_action_url = "https://.com/conference/firstbranch/"
response.add(plivoxml.GetInputElement().
set_action(getinput_action_url).
set_method('POST').
set_input_type('dtmf').
set_digit_end_timeout(5).
set_num_digits(4).
set_redirect(True).add(
plivoxml.SpeakElement(welcome_message)))
response.add(plivoxml.SpeakElement(noinput_message))
return Response(response.to_string(), mimetype='application/xml')
@app.route('/conference/firstbranch/', methods=['GET','POST'])
def firstbranch():
response = plivoxml.ResponseElement()
digit = request.values.get('Digits')
if digit == "1234":
getinput_action_url = "https://.com/secondbranch/"
response.add(
plivoxml.ConferenceElement(
'demo',
start_conference_on_enter=False,
wait_sound='https://.com/waitmusic/'))
else:
response.add_speak(wronginput_message)
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Save the file and run it.
```shell theme={null}
$ python conference_call.py
```
You should see your basic server application in action at [http://localhost:5000/conference/](http://localhost:5000/conference/).
## Create a Plivo application for the conference call
Associate the Flask application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to implement a conference call with PIN
Change to the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller ConferencecallController
```
This generates a controller named ConferencecallController in the app/http/controllers/ directory. Edit app/http/controllers/ConferencecallController.php and add into it this code.
```php theme={null}
addGetInput(
[
'action' => "https://.com/conference/confbranch",
'method' => "POST",
'digitEndTimeout' => "5",
'numDigits' => "4",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($welcome_message, ['language'=>"en-US", 'voice'=>"Polly.Salli"]);
$response->addSpeak($no_input);
Header('Content-type: text/xml');
echo $response->toXML();
}
public function confBranch(Request $request)
{
$wrong_input = "Sorry, that's an invalid PIN"; // Message that Plivo reads when the caller enters an invalid number
$digit = $request->query('Digits');
$response = new Response();
if ($digit=="1234") {
$params = array(
'startConferenceOnEnter' => "true",
'endConferenceOnExit' => "true"
);
$conference_name = "demo";
$response->addConference($conference_name, $params);
} else {
$response->addSpeak($wrong_input);
}
Header('Content-type: text/xml');
echo $response->toXML();
}
}
```
### Add a route
Add a route for the forward function in the ConferencecallController class. Edit routes/web.php and add these lines.
```shell theme={null}
Route::match(['get', 'post'], '/conference', 'ConferenceCallController@conferenceCall');
Route::match(['get', 'post'], '/conference/confbranch', 'ConferenceCallController@confBranch');
```
Now ConferencecallController is ready to forward incoming calls to your Plivo number. Start the Laravel server.
```shell theme={null}
$ php artisan serve
```
You should see your basic server application in action at [http://localhost:8000/conference/](http://localhost:8000/conference/).
## Create a Plivo application for the conference call
Associate the Laravel application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to implement a conference call with PIN
In Visual Studio, create a controller called `ConferencecallController.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Plivo.XML;
namespace Receivecall
{
public class ConferencecallController : Controller
{
// Message that Plivo reads when the caller dials in
String WelcomeMessage = "Welcome to the demo. Press 1234 to join the conference";
// Message that Plivo reads when the caller does nothing
String NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
String WronginputMessage = "Sorry, that's an invalid PIN";
// GET: //
public IActionResult Index()
{
var resp = new Response();
Plivo.XML.GetInput get_input = new
Plivo.XML.GetInput("",
new Dictionary()
{
{"action", "https://.com/conference/firstbranch/"},
{"method", "POST"},
{"digitEndTimeout", "5"},
{"numDigits", "4"},
{"inputType", "dtmf"},
{"redirect", "true"},
});
resp.Add(get_input);
get_input.AddSpeak(WelcomeMessage,
new Dictionary() { });
resp.AddSpeak(NoinputMessage,
new Dictionary() { });
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// Conference Branch
public IActionResult FirstBranch()
{
String digit = Request.Query["Digits"];
Debug.WriteLine("Digit pressed : {0}", digit);
var resp = new Response();
if (digit == "1234")
{
// Add Conference XML Tag
resp.AddConference("demo",
new Dictionary()
{
{"startConferenceOnEnter", "true"},
{"endConferenceOnExit", "true"},
{"waitSound", "https://.com/waitmusic/"}
});
}
else
{
// Add Speak XML Tag
resp.AddSpeak(WronginputMessage,
new Dictionary() { });
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Before you start the application, update Properties/launchSettings.json:
"applicationUrl": "[http://localhost:5000/](http://localhost:5000/)"
Run the project and you should see your basic server application in action at [http://localhost:5000/conference/](http://localhost:5000/conference/).
## Create a Plivo application for the conference call
Associate the .NET application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application to implement a conference call with PIN
Create a Java class called `ConferenceCall` and paste into it this code.
```java theme={null}
import com.plivo.api.xml.*;
import static spark.Spark.post;
public class ConferenceCall {
public static void main(String[] args) {
// Message that Plivo reads when the caller dials in
String WelcomeMessage = "Welcome to the demo. Press 1234 to join the conference";
// Message that Plivo reads when the caller does nothing
String NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
String WronginputMessage = "Sorry, that's an invalid PIN";
post("/conference/", (request, response) -> {
response.type("application/xml");
Response resp = new Response();
resp.children(
new GetInput()
.action("https://.com/ivr/firstbranch/")
.method("POST")
.inputType("dtmf")
.digitEndTimeout(5)
.numDigits(4)
.redirect(true)
.children(
new Speak(WelcomeMessage)
)
);
resp.children(new Speak(NoinputMessage));
return resp.toXmlString();
});
post("/conference/firstbranch/", (request, response) -> {
response.type("application/xml");
String digit = request.queryParams("Digits");
Response resp = new Response();
if (digit.equals("1234")){
resp.children(
new Speak("You will now be placed into the demo conference"),
new Conference("demo")
.endConferenceOnExit(true)
.startConferenceOnEnter(false)
.waitSound("https://.com/waitmusic/")
);
resp.children(new Speak(NoinputMessage));
}
else {
resp.children(
new Speak(WronginputMessage)
);
}
return resp.toXmlString();
});
}
}
```
Save the file and run it. You should see your basic server application in action at [http://localhost:4567/conference/](http://localhost:4567/conference/).
## Create a Plivo application for the conference call
Associate the Spark application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
## Overview
This guide shows how to create and configure conference calls with a PIN to let multiple people securely connect to a single call. Only participants who have a specified passcode can enter the conference call.
You can make conference calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to receive a call on a Plivo number and add the caller to a conference call named “demo” after the caller enters a valid PIN.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to implement a conference call with PIN
Create a file called `conference_call.go` and paste into it this code.
```go theme={null}
package main
import (
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
m := martini.Classic()
const
(
// Message that Plivo reads when the caller dials in
WelcomeMessage = "Welcome to the demo. Press 1234 to join the conference"
// Message that Plivo reads when the caller does nothing
NoInputMessage = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller enters an invalid number
WrongInputMessage = "Sorry, that's an invalid PIN"
)
m.Post("/conference/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.GetInputElement).
SetAction("https://.com/ivr/firstbranch/").
SetMethod("POST").
SetDigitEndTimeout(5).
SetInputType("dtmf").
SetNumDigits(4).
SetRedirect(true).
SetContents([]interface{}{new(xml.SpeakElement).
AddSpeak(WelcomeMessage),
}),
new(xml.SpeakElement).
AddSpeak(NoInputMessage),
},
}
return response.String()
})
m.Post("/conference/firstbranch/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
digit := r.FormValue("Digits")
if digit == "1234" {
return xml.ResponseElement{
Contents: []interface{} {
new(xml.SpeakElement).
AddSpeak("You will now be placed into the demo conference"),
new(xml.ConferenceElement).
SetEndConferenceOnExit(true).
SetStartConferenceOnEnter(false).
SetWaitSound("https://.com/waitmusic/").
SetContents("demo"),
},
}.String()
} else {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak(WrongInputMessage),
},
}.String()
}
})
m.Run()
}
```
Save the file and run it.
```shell theme={null}
$ go run conference_call.go
```
You should see your basic server application in action at [http://localhost:8080/conference/](http://localhost:8080/conference/).
## Create a Plivo application for the conference call
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Conference Call`. Enter the server URL you want to use (for example `https://.com/conference/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Conference Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number. You should be prompted for a PIN, then placed into a conference after PIN validation.
# Connect a Call to a Second Person
Source: https://plivo.com/docs/voice/use-cases/connect-call-to-second-person
Dial out and connect a caller to a second person programmatically
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to connect calls to a second person
Create a file called `connect_call.js` and paste into it this code.
```js theme={null}
var express = require('express');
var plivo = require('plivo');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.urlencoded({extended: true}));
app.all('/outbound_call/', function(request, response) {
var client = new plivo.Client("","");
var resp = client.calls.create(
"",
"",
request.protocol + '://' + request.get('host') + "/connect",
).then(function (response) {
console.log(response);
},function (err) {
console.error(err);
});
});
app.post('/connect/', function(request, response) {
var res = plivo.Response();
res.addSpeak("Please wait while we connect the call to second person");
var dial = res.addDial();
dial.addNumber(""); // Dial to second number
response.set({'Content-Type': 'text/xml'});
response.send(res.toXML());
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Save the file and run it.
```shell theme={null}
node connect_call.js
```
You should see your basic server application in action at [http://localhost:3000/outbound\_call/](http://localhost:3000/outbound_call/).
Set up ngrok to expose your local server to the internet.
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use `process.env` to store environment variables and fetch them when initializing the client.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to connect calls to a second person
Change to the project directory and run this command to create a Rails controller for inbound calls.
```shell theme={null}
rails generate controller Plivo voice
```
This command generates a controller named plivo\_controller in the app/controllers/ directory and a respective view in the app/views/plivo directory. We can delete the view, as we don’t need it.
```shell theme={null}
rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and add this code in the PlivoController class.
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
def outbound_call
api = RestClient.new('','')
response = api.calls.create(
'',
[''],
'https://'+request.host+'/plivo/connect',
{answer_method:'GET'}
)
render json: response.to_s
end
def connect
response = Response.new
response.addSpeak('Please wait while we connect your call')
dial = response.addDial()
dial.addNumber('') # Dial to second number
xml = PlivoXML.new(response)
render xml: xml.to_xml
end
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
### Add a route
Add a route for the inbound function in the PlivoController class. Edit the config/routes.rb file and add these lines.
```shell theme={null}
get 'plivo/outbound_call'
get 'plivo/connect'
```
Start the Rails server.
```shell theme={null}
rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/outbound\_call/](http://localhost:3000/plivo/outbound_call/).
Set up ngrok to expose your local server to the internet.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask application to connect calls to a second person
Create a file called `connect_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, Response, url_for
import plivo
from plivo import plivoxml
app = Flask(__name__)
@app.route('/outbound_call/')
def outbound_call():
client = plivo.RestClient('','')
response = client.calls.create(
from_='',
to_='',
answer_url=url_for('connect', _external=True))
return response
@app.route('/connect', methods = ['POST'])
def connect():
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Please wait while we connect your call to the second number'))
response.add(plivoxml.DialElement().add(
plivoxml.NumberElement(''))) # Dial to second number
return Response(response.to_string(), mimetype='text/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Save the file and run it.
```shell theme={null}
python connect_call.py
```
You should see your basic server application in action at [http://localhost:5000/outbound\_call/](http://localhost:5000/outbound_call/).
Set up ngrok to expose your local server to the internet.
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use the os module (`os.environ`) to store environment variables and fetch them when initializing the client.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to connect calls to a second person
Change to the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller VoiceController
```
This generates a controller named VoiceController in the app/http/controllers/ directory. Now, Edit app/http/controllers/voiceController.php and paste into it this code.
```php theme={null}
getHttpHost();
$client = new RestClient('','');
$response = $client->calls->create(
'',
[''],
'https://'.$host.'/connect',);
echo json_encode($response);
}
public function connect()
{
$response = new Response();
$response->addSpeak('Please wait while we connect your call');
$dial = $response->addDial();
$dial->addNumber('');
Header('Content-type: text/xml');
echo ($response->toXML());
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use `$_ENV` or `putenv/getenv` functions to store environment variables and fetch them when initializing the client.
### Add a route
Add a route for the forward function in VoiceController. Edit the routes/web.php file and add these lines.
```shell theme={null}
Route::match(['get','post'], '/outboundCall', 'App\Http\Controllers\VoiceController@outboundCall');
Route::match(['get','post'], '/connect', 'App\Http\Controllers\VoiceController@connect');
```
Start the Laravel server.
```shell theme={null}
php artisan serve
```
You should see your basic server application in action at [http://localhost:8000/outboundCall/](http://localhost:8000/outboundCall/).
Set up ngrok to expose your local server to the internet.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to connect calls to a second person
In Visual Studio, create a controller called `Connect.cs` and paste into it this code.
```cs theme={null}
using System;
using Plivo;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace VoiceApp.Controllers
{
public class Connect : Controller
{
public IActionResult Index()
{
var hostName = Request.HttpContext.Request.Host.Value;
Console.WriteLine(hostName);
var api = new PlivoApi("", "");
var response = api.Call.Create(
to: new List { "" },
from: "",
answerUrl: "https://" + hostName + "/Connect/Dial/"
);
return this.Content(response.ToString());
}
public IActionResult Dial()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddSpeak("Please wait while we connect your call to the second number",
new Dictionary() { });
Plivo.XML.Dial dial = new Plivo.XML.Dial(new Dictionary(){});
dial.AddNumber("",
new Dictionary() { }); // Dial to second number
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
return this.Content(output, "text/xml");
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Before starting the application, edit Properties/launchSettings.json and set the applicationUrl as
```json theme={null}
"applicationUrl": "http://localhost:5000/"
```
Run the project and you should see your basic server application in action at [http://localhost:5000/Connect/](http://localhost:5000/Connect/).
Set up ngrok to expose your local server to the internet.
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use the `Environment.SetEnvironmentVariable` method to store environment variables and `Environment.GetEnvironmentVariable` to fetch them when when initializing the client.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spring server to connect calls to a second person
Edit the PlivoVoiceApplication.java file in the src/main/java/com.example.demo/ folder and paste into it this code.
Note: Here, the demo application name is PlivoVoiceApplication.java because we provided the friendly name `Plivo Voice` in the Spring Initializr.
```java theme={null}
package com.example.connect;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.exceptions.PlivoValidationException;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
import com.plivo.api.xml.Dial;
import javax.servlet.http.HttpServletRequest;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Collections;
@RestController
@SpringBootApplication
public class ConnectApplication {
public static void main(String[] args) {
SpringApplication.run(ConnectApplication.class, args);
}
@RequestMapping(value = "/outbound_call", produces = {"application/json"}, method = {RequestMethod.GET})
public String call(HttpServletRequest request) throws PlivoXmlException, PlivoValidationException, IOException, PlivoRestException {
String hostName = request.getRequestURL().toString();
Plivo.init("","");
System.out.println(hostName + "/connect");
CallCreateResponse response = Call.creator("", Collections.singletonList(""), hostName + "connect")
.create();
return response.toString();
}
@RequestMapping(value = "outbound_call/connect", produces = {"text/xml"})
public String connect() throws PlivoXmlException, PlivoValidationException {
Response response = new Response()
.children(
new Speak("Please wait while we connect your call to the second number"),
new Dial()
.children(
new Number("") // Dial to second number
));
return response.toXmlString();
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Save the file and run it.
You should see your basic server application in action at [http://localhost:8080/outbound\_call/](http://localhost:8080/outbound_call/).
Set up ngrok to expose your local server to the internet.
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `System.getenv()` to store environment variables and retrieve them when initializing the client.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
## Overview
You may want to have an application dial out for someone, so that it calls them on their phone, then connects them to the number they want. This involves three tasks:
1. Make an outbound call to a caller.
2. When the call recipient answers the phone, place a new call to a different number (second user).
3. Bridge the calls (first and second user) after the second user answers.
Common use cases for this practice include click to call, where a server application directs a call to a person who clicks on a web link, then connects them with a company representative.
This guide shows how to code connecting a user to second person on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to connect a call to a second person using XML.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to connect calls to a second person
Create a file called `connect_call.go` and paste into it this code.
```go theme={null}
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/plivo/plivo-go/v7"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
r: = gin.Default()
r.GET("/outbound-call", func(c * gin.Context) {
c.Header("Content-Type", "application/JSON")
fmt.Println("https://" + c.Request.Host + "/connect")
client, err: = plivo.NewClient("", "", & plivo.ClientOptions {})
if err != nil {
panic(err)
}
response, err: = client.Calls.Create(
plivo.CallCreateParams {
From: "",
To: "",
AnswerURL: "https://" + c.Request.Host + "/connect",
},
)
if err != nil {
panic(err)
}
fmt.Printf("Response: %#v\n", response)
c.JSON(200, response)
})
r.POST("/connect", func(c * gin.Context) {
c.Header("Content-Type", "text/xml")
response: = xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak("Please wait while we connect your call to the second number", "WOMAN", "en-US", 1),
new(xml.DialElement).
SetContents(
[] interface {} {
new(xml.NumberElement).
SetContents(""),
},
),
},
}
c.String(200, response.String())
})
r.Run()
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
Save the file and run it.
```shell theme={null}
go run connect_call.go
```
You should see your basic server application in action at [http://localhost:8080/outbound-call/](http://localhost:8080/outbound-call/).
Set up ngrok to expose your local server to the internet.
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use the `os.Setenv` and `os.Getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Have your application make a call to a regular mobile phone. Plivo will send a request to your answer URL requesting a valid XML response and connect the call to a second user.
# Connect External Phone Numbers to Plivo
Source: https://plivo.com/docs/voice/use-cases/connect-external-numbers
Route calls from phone numbers you can't port to Plivo applications using DID forwarding or direct SIP
If you have a phone number with another provider that you can't port to Plivo, you can still use it with Plivo applications (XML apps, Audio Streaming, AI voice agents). This guide covers two ways to do it.
***
## How It Works
The call lands at your existing provider (the carrier where your number lives).
Either as a forwarded call to a Plivo phone number (Option 1), or as a direct SIP INVITE to your Plivo application's SIP URI (Option 2).
For direct SIP, Plivo verifies the incoming call against your IP ACL or SIP credentials before accepting it.
The call hits your XML application's Answer URL. Your server returns XML instructions (e.g., `` to connect to a WebSocket-based AI agent).
Audio flows in real-time between the caller and your application via Plivo's voice infrastructure.
***
## Two Options
| Option | What It Does | Best For |
| ---------------------------- | ------------------------------------------------------------------ | ----------------------------------------------- |
| **DID forwarding** | Your provider forwards calls from your number to a Plivo number | Quick setup, no SIP knowledge required |
| **Direct SIP** (recommended) | Your provider sends SIP traffic directly to your Plivo application | Lower cost, lower latency, fewer failure points |
***
## When to Use This
* You have phone numbers with carriers that don't support porting
* You have geographic numbers (e.g., specific countries) where Plivo doesn't offer numbers
* You have toll-free or vanity numbers you've owned for years and can't move
* You want to connect existing PBX or contact center extensions to Plivo AI agents
* You're testing AI voice agents on existing numbers without committing to porting
***
## Option 1: DID Forwarding
The simplest approach. Configure your existing provider to forward all incoming calls to a Plivo phone number.
```text theme={null}
Caller dials your external number
|
v
Your Provider (Provider X)
|
v [forward leg, outbound from Provider X]
Your Plivo Number (inbound)
|
v
Plivo XML App -> Answer URL -> WebSocket / AI Agent
```
### Setup
[Purchase a voice-enabled Plivo number](https://cx.plivo.com/phone-numbers) and assign it to your XML application.
In your existing provider's dashboard, set up call forwarding to route inbound calls to your Plivo number. The exact steps depend on your provider — look for "call forwarding", "auto-forward", or "external destination" settings.
Call your external number. It should ring through to your Plivo number, hit your XML app's Answer URL, and trigger your voice agent.
### Trade-offs
* **Pros:** Quick to set up, works with any provider that supports forwarding, no SIP knowledge needed
* **Cons:** Three call legs (caller → provider, provider → Plivo number outbound, Plivo number inbound). Higher cost and latency.
***
## Option 2: Direct SIP (Recommended)
Configure your existing provider to send SIP traffic directly to your Plivo XML application's SIP URI. Use [SIP Authentication](/docs/voice/concepts/sip-authentication/) to secure the inbound stream.
**Request-URI requirement:** For inbound SIP authentication to apply, the Request-URI of the INVITE must be `sip:{app_id}@app.plivo.com`. Plivo resolves the application from the Request-URI user part, not from the To header. If your SIP provider places a phone number in the Request-URI, configure the provider to send INVITEs to the application's SIP URI instead. Without this, calls bypass authentication silently.
```text theme={null}
Caller dials your external number
|
v
Your Provider (Provider X)
|
v [SIP INVITE to sip:{app_id}@app.plivo.com]
Plivo SIP Auth check (IP ACL or credentials)
|
v
Plivo XML App -> Answer URL -> WebSocket / AI Agent
```
### Why Direct SIP Is Recommended
* **Lower cost** — single Plivo SIP termination charge instead of provider forwarding + Plivo inbound
* **Lower latency** — eliminates the extra forwarding hop
* **Better quality** — fewer transcoding steps means cleaner audio
* **Fewer failure points** — fewer legs means fewer things that can go wrong
### Setup
Every Plivo application has a SIP URI in the format:
```
sip:{app_id}@app.plivo.com
```
Find your `app_id` in the [Plivo Console](https://cx.plivo.com/home) under **Voice > Applications**, or via the [Application API](/docs/account/api/application/).
Choose one auth method:
**Option A: IP ACL** (recommended if your provider has stable outbound IPs)
```bash theme={null}
# Create the IP ACL
curl -X POST "https://api.plivo.com/v1/Account//SipAuth/IpAccessControlList/" \
-u ":" \
-H "Content-Type: application/json" \
-d '{"name": "External Provider"}'
# Response: {"ip_acl_uuid": "acl-abc123"}
# Add your provider's outbound SIP IP
curl -X POST "https://api.plivo.com/v1/Account//SipAuth/IpAccessControlList/acl-abc123/Entry/" \
-u ":" \
-H "Content-Type: application/json" \
-d '{"ip": "203.0.113.10", "cidr_prefix": 32, "description": "Provider X SIP outbound"}'
```
**Option B: SIP digest credentials** (use if your provider's IPs change)
```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account//SipAuth/Credential/" \
-u ":" \
-H "Content-Type: application/json" \
-d '{"username": "external-provider", "password": ""}'
# Response: {"credential_uuid": "cred-def456"}
```
Update your application to require SIP authentication:
```bash theme={null}
# For IP ACL
curl -X POST "https://api.plivo.com/v1/Account//Application//" \
-u ":" \
-H "Content-Type: application/json" \
-d '{
"sip_auth_type": "ip_acl",
"ip_acl_uuid": "acl-abc123"
}'
```
In your existing provider's dashboard, configure inbound calls to your number to forward via SIP to:
```
sip:{app_id}@app.plivo.com
```
Look for "SIP termination", "SIP forwarding", or "external SIP destination" settings.
If you're using credentials, configure your provider with the username and password you created in Step 2.
Call your external number. The call should hit your provider, route as a SIP INVITE to `sip:{app_id}@app.plivo.com`, pass Plivo's auth check, and trigger your XML application.
Check the Plivo Console under **Voice > Logs > Calls** to verify routing.
### Connecting to AI Voice Agents
Once your external number routes to a Plivo Application via SIP, your Answer URL can return the `` XML element to connect to a WebSocket-based AI voice agent (Pipecat, LiveKit Agents, or your own framework).
```xml theme={null}
Connecting you to our AI assistant.
wss://your-server.com/stream
```
For full AI voice agent setup, see [Build with Audio Streaming](/docs/voice-agents/audio-streaming/overview/).
***
## Cost & Latency Comparison
For a typical 5-minute inbound call:
| Approach | Legs | Cost Components |
| ------------------ | ----------------------------------------------------------------------------- | ----------------------------------------------------- |
| **DID forwarding** | 3 (caller → provider, provider → Plivo number outbound, Plivo number inbound) | Provider's outbound forward rate + Plivo inbound rate |
| **Direct SIP** | 1 (caller → Plivo via SIP) | Plivo's SIP termination rate only |
Direct SIP typically eliminates 50-70% of the per-minute cost and shaves 100-300ms of latency.
***
## Verify It's Working
After setup, make a test call and check your `answer_url` callback for these parameters:
| Parameter | What It Confirms |
| ------------- | ------------------------------------------------------------------------- |
| `SIPAuthType` | Auth method that ran (`ip_acl`, `credential`, or `ip_acl_and_credential`) |
| `SIPAuthUser` | The authenticated username (credential auth only) |
| `SIPSourceIP` | The caller's source IP |
If `SIPAuthType` is missing from the callback, auth is not running — the most common cause is the provider placing a phone number in the Request-URI instead of your app\_id.
***
## Security (Direct SIP)
* **Always use SIP Authentication** — leaving an XML app's SIP URI open invites toll fraud and abuse
* **Prefer IP ACL when possible** — if your provider has stable outbound IPs, IP ACL is faster (no challenge/response handshake) and harder to abuse
* **Use credentials when IPs are dynamic** — if your provider rotates IPs, use SIP digest credentials with a strong password
* **Beware of shared IPs** — if your provider is on carrier-grade NAT or a shared-IP platform, IP ACL alone is not sufficient. Use `ip_acl_and_credential` for defense in depth.
* **Combine both for maximum security** — set `sip_auth_type` to `ip_acl_and_credential` to require both checks
* **Rate limiting is automatic** — 10 failed auth attempts from the same IP triggers a lockout. Updating the IP ACL to include the locked-out IP does NOT clear an active lockout. See [SIP Authentication](/docs/voice/concepts/sip-authentication/) for details.
***
## Troubleshooting
| Issue | Solution |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| All calls get 403 Forbidden | Verify your provider's outbound SIP IP matches an entry in your IP ACL, or that the credentials match exactly |
| Calls succeed but no `SIPAuthType` in callback | Your provider is placing a phone number in the Request-URI instead of your app\_id. Configure the provider to send INVITEs to `sip:{app_id}@app.plivo.com`. |
| Call rejected with 407 (then drops) | Your provider isn't responding to the digest challenge. Configure the SIP credentials in your provider's setup. |
| Auth passes but no XML executes | Check that the Application has a valid `answer_url` configured, and that your server returns valid XML |
| Calls work intermittently | Your provider may be rotating outbound IPs. Switch to credential auth, or expand your IP ACL CIDR range |
***
## Full API Reference
* [SIP Authentication API](/docs/account/api/sip-authentication/) — Create and manage SIP credentials and IP Access Control Lists
* [Application API](/docs/account/api/application/) — Configure `sip_auth_type`, `credential_uuid`, `ip_acl_uuid` on your Plivo application
* [Voice Call API](/docs/voice/api/calls/) — Make outbound calls and retrieve call logs
## Related
* [Transfer to Human Agent](/docs/voice/use-cases/transfer-to-human-agent/) — Route AI-handled calls to a human agent
* [SIP Authentication](/docs/voice/concepts/sip-authentication/) — Full concept guide for IP ACL and credential auth
* [Build with Audio Streaming](/docs/voice-agents/audio-streaming/overview/) — Connect external numbers to AI voice agents
# Dial Status Reporting
Source: https://plivo.com/docs/voice/use-cases/dial-status-reporting
Track call status at each stage using webhook-based dial status reporting
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server for dial status reporting
Create a file called `dial_status.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.all('/dialstatus/', function(request, response) {
var r = plivo.Response();
var params = {
'action': "https://.com/dialstatus/action/",
'method': "POST",
'redirect': "true"
};
var dial = r.addDial(params);
var first_number = "";
dial.addNumber(first_number);
console.log (r.toXML());
response.set({
'Content-Type': 'text/xml'
});
response.end(r.toXML());
});
app.all('/dialstatus/action/', function(request, response) {
var status = request.param('Status');
var aleg = request.param('DialALegUUID');
var bleg = request.param('DialBLegUUID');
console.log ('Status : ' + status + ' Aleg UUID : ' + aleg + ' Bleg UUID : ' + bleg);
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the Express server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller for dial status reporting
Change to the project directory and run this command to create a Rails controller to reject incoming calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This command generates a controller named plivo\_controller in the app/controllers/ directory, and a view will be generated in app/views/plivo directory. We can delete the view as we don’t need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Open the file app/controllers/plivo\_controller.rb and paste this code in the PlivoController class:
```rb theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
def dialstatus
r = Response.new()
params = {
'action' => "https://.com/dialstatus/action/", # Redirect to this URL after leaving Dial.
'method' => 'GET' # Submit to action URL using GET or POST.
}
r.addSpeak("Connecting your call..")
d = r.addDial(params)
d.addNumber("")
xml = Plivo::PlivoXML.new(r)
render xml: xml.to_xml
end
def dialstatusaction
status = params[:DialStatus]
aleg = params[:DialALegUUID]
bleg = params[:DialBLegUUID]
puts "Status : #{status}, ALeg UUID : #{aleg}, BLeg UUID : #{bleg}"
end
end
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the Rails controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask application for dial status reporting
Create a file called `dial_status.py` and paste into it this code.
```py theme={null}
from flask import Flask, request, Response
from plivo import plivoxml
app=Flask(__name__)
@app.route('/dialstatus/', methods=['GET','POST'])
def dial_xml():
# Generate Dial XML
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Connecting your call..'))
response.add(plivoxml.DialElement(action='https://.com/dialstatus/action/', method='POST', redirect=True)
.add(plivoxml.NumberElement("")))
return Response(response.to_string(), mimetype='application/xml')
@app.route('/dialstatus/action/', methods=['GET','POST'])
def dial_status():
# After completion of the call, Plivo will report back the status to the action URL in the Dial XML.
status = request.args.get('DialStatus')
aleg = request.args.get('DialALegUUID')
bleg = request.args.get('DialBLegUUID')
print "Status : %s, ALeg Uuid : %s, BLeg Uuid : %s" % (status,aleg,bleg)
return "Dial status reported"
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the Flask application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller for dial status reporting
Create a file called `dial_status.php` and paste into it this code.
```php theme={null}
addSpeak($body);
$params = array(
'action' => 'https://.com/dial_action/', # Redirect to this URL after leaving Dial.
'method' => 'GET' # Submit to action URL using GET or POST.
);
// Add Dial tag
$d = $r->addDial($params);
$number = "";
$d->addNumber($number);
Header('Content-type: text/xml');
echo($r->toXML());
}
// Action URL Block
public function dialstatusAction()
{
// Print the Dial Details
$status = $_REQUEST['DialStatus'];
$aleg = $_REQUEST['DialALegUUID'];
$bleg = $_REQUEST['DialBLegUUID'];
echo "Status = $status , Aleg UUID = $aleg , Bleg UUID = $bleg";
}
}
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the Laravel controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller for dial status reporting
Navigate to the Controllers directory in the Dialstatus app. Create a Controller named `DialstatusController.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
using Microsoft.AspNetCore.Mvc;
namespace Dialstatus.Controllers
{
public class DialstatusController : Controller
{
// GET: //
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
// Generate Dial XML
Plivo.XML.Dial dial = new Plivo.XML.Dial(new Dictionary()
{
{"action","https://.com/dialstatus/action/"}, // Redirect to this URL after leaving Dial.
{"method","GET"} // Submit to action URL using GET or POST.
});
dial.AddNumber("", new Dictionary() { });
resp.Add(dial);
var output = resp.ToString();
return this.Content(output, "text/xml");
}
//Action URL
public String Action()
{
var status = Request.Query["DialStatus"];
var aleg = Request.Form["DialALegUUID"];
var bleg = Request.Form["DialBLegUUID"];
Debug.WriteLine("Status : {0}, ALeg UUID : {1}, BLeg UUID : {2}", status, aleg, bleg);
return "OK";
}
}
}
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application for dial status reporting
Create a Java class named `DialStatus` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Response;
public class dialstatus {
public static void main(String[] args) {
post("/dialstatus/", (request, response) -> {
response.type("application/xml");
Response resp = new Response()
.children(
new Dial()
.action("https://.com/dialstatus/action/")
.method("POST")
.redirect(true)
.children(
new Number("")
)
);
return resp.toXmlString();
});
post("/dialstatus/action/", (request, response) -> {
String status = request.queryParams("Status");
String aleg = request.queryParams("DialALegUUID");
String bleg = request.queryParams("DialBLegUUID");
System.out.println("Status : " + status + " ALeg UUID : " + aleg + " Bleg UUID : " + bleg);
response.raw().getWriter().print("Status : " + status + " ALeg UUID : " + aleg + " Bleg UUID : " + bleg);
return "done";
});
}
}
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the Spark application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
## Overview
Plivo passes the call status of an ongoing call so you can decide how to process it. For all the calls made using Plivo’s [Make a Call API](/docs/voice/api/calls#create-a-call) or [Dial XML](/docs/voice/xml/routing#dial), Plivo sends the call status to the application server at different stages of a call. We send call status as an HTTP webhook request to URLs such as `ring_url`, `answer_url`, `fallback_url`, `action_url`, `callback_url`, and `hangup_url`.
In each callback, the `CallStatus` parameter takes one of these values:
| | |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **in-progress** | The call was answered and is in progress. Calls with this status can be terminated using the [Hangup API](/docs/voice/api/calls#hang-up-a-call). |
| **completed** | The call was completed, terminated either by the Hangup API or by one of the parties in the call. |
| **ringing** | The call is ringing. This status is sent to the Ring URL. |
| **no-answer** | The call was not answered. |
| **busy** | The called line is busy. |
| **cancel** | The call was canceled by the caller. |
| **timeout** | There was a timeout while connecting your call, caused by either an issue with one of the terminating carriers or network lag in our system. |
Plivo sends these parameters to the application server in the webhook:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `DialRingStatus` | Indicates whether the dial attempt rang or not. Values: `true`, `false` |
| `DialHangupCause` | The [standard telephony hangup cause](/docs/voice/troubleshooting/hangup-causes/#list-of-hangup-causes). |
| `DialStatus` | Status of the dial. Values: `completed`, `busy`, `failed`, `timeout`, `no-answer` |
| `DialALegUUID` | CallUUID of the A leg. |
| `DialBLegUUID` | CallUUID of the B leg. Empty if nobody answers. |
You can implement dial status reporting either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to send callback events for dial status reporting.
## How it works
Plivo requests an answer URL when a Plivo number receives a call (step 2) and expects the file at that URL to be configured in the application assigned to the number to hold a valid XML response with instructions on how to handle the call. For [outbound calls](/docs/voice/use-cases/make-outbound-calls) you specify an answer URL along with the make call API request, and for [incoming calls](/docs/voice/use-cases/receive-incoming-calls) the answer URL is specified in the Plivo application associated with the phone number.
In addition to requests to the answer URL, Plivo initiates HTTP requests to your application server throughout the course of a call based on specific XML elements and attributes in your answer XML document (step 5). Such requests are broadly classified into two categories:
**Action URL requests:** These requests are typically invoked at the end of an XML element’s execution, and the server expects XML instructions to carry forward the call in response to these requests. This happens, for example, when a caller provides Touch-Tone input during GetInput XML execution.
**Callback URL requests:** These requests serve as webhooks to pass the application server information about events through the course of an XML element’s execution, such as when a conference participant is muted or unmuted. These callback URL requests can be used for dial status reporting. No XML instructions are expected in response to these requests.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go application for dial status reporting
Create a file called `dial_status.go` and paste into it this code.
```go theme={null}
package main
import (
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
m := martini.Classic()
m.Post("/dialstatus/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).
SetAction("https://.com/dialstatus/action/").
SetMethod("POST").
SetRedirect(true).
SetContents([]interface{}{
new(xml.NumberElement).
SetContents(""),
}),
},
}
return response.String()
})
m.Post("/dialstatus/action", func(w http.ResponseWriter, r *http.Request) string {
status := r.FormValue("DialStatus")
aleg := r.FormValue("DialALegUUID")
bleg := r.FormValue("DialBLegUUID")
result := status + " " + aleg + " " + bleg
return result
})
m.Run()
}
```
Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
In this code, we tell Plivo to POST the call status to https\://\.com/dialstatus/. We set the [redirect attribute](/docs/voice/xml/routing#redirect), which determines whether to change the call flow of an ongoing call based on the actions performed, to `true`, which tells Plivo to expect a valid XML document to be posted to https\://\.com/dialstatus/action. The code creates an XML document with a Dial XML element.
## Create a Plivo application for dial status reporting
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Dial Status Report`. Enter the server URL you want to use (for example `https://.com/dialstatus/`) in the `Answer URL` field and set the method to `POST`. Click on `Create Application` to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Dial Status Report` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides, and call details will be posted to your application server via the action and callback URLs you configured throughout the course of the call.
# Download Recordings
Source: https://plivo.com/docs/voice/use-cases/download-recordings
Retrieve and download call recordings to local storage from Plivo
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a Node development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```js theme={null}
// Example script for downloading recording files
var plivo = require('plivo');
var axios = require('axios');
var fs = require('fs');
var path = require('path');
const AUTH_ID = "";
const AUTH_TOKEN = "";
(function main() {
'use strict';
var client = new plivo.Client(AUTH_ID,AUTH_TOKEN);
// Directory where the recordings will be saved
var recordingsDir = path.join(__dirname, "recordings");
if (!fs.existsSync(recordingsDir)) {
fs.mkdirSync(recordingsDir, { recursive: true });
}
client.recordings.list(
{
add_time__gt: "2023-04-01 00:00:00",
add_time__lt: "2023-04-30 00:00:00",
offset: 0,
limit: 5,
},
).then(function (response) {
console.log("Found " + response.length + " recordings.");
response.forEach(recording => {
var recording_url = recording.recordingUrl;
var recording_id = recording.recordingId;
var format = recording.recordingFormat;
console.log("Downloading recording: " + recording_url);
var output_file = path.join(recordingsDir, recording_id + "." + format);
// Download the file
axios({
url: recording_url,
method: 'GET',
responseType: 'stream',
}).then(function (response) {
var fileStream = fs.createWriteStream(output_file);
response.data.pipe(fileStream);
fileStream.on('finish', function () {
console.log("Downloaded file to: " + output_file);
});
}).catch(function (error) {
console.log("Error downloading file: " + error.message);
});
});
}, function (err) {
console.error(err);
});
})();
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```rb theme={null}
#
# Example script for downloading recording files
#
require 'rubygems'
require 'plivo'
require 'open-uri'
require 'fileutils'
include Plivo
include Plivo::Exceptions
AUTH_ID = ""
AUTH_TOKEN = ""
api = RestClient.new(AUTH_ID,AUTH_TOKEN)
begin
response = api.recordings.list(
add_time__gt: "2023-04-01 00:00:00",
add_time__lt: "2023-04-30 00:00:00",
limit: 5,
offset: 0
)
puts "Found #{response[:objects].length} recordings."
response[:objects].each do |recording|
recording_url = recording.recording_url
recording_id = recording.recording_id
format = recording.recording_format
puts "Downloading recording: #{recording_url}"
output_file = "recordings/#{recording_id}.#{format}"
# Directory where the recordings will be saved
FileUtils.mkdir_p 'recordings'
begin
# Download the file
open(recording_url) do |file|
File.open(output_file, "wb") do |output|
output.write(file.read)
end
end
puts "Downloaded file to: #{output_file}"
rescue StandardError => e
puts "Error downloading file: #{e.message}"
end
end
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a python development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```py theme={null}
import plivo
import requests
import os
AUTH_ID = ""
AUTH_TOKEN = ""
client = plivo.RestClient(AUTH_ID,AUTH_TOKEN)
response = client.recordings.list(
add_time__gt='2023-07-01 00:00:00',
add_time__lt='2023-07-30 00:00:00',
offset=0,
limit=5,
)
print(f"Found {len(response)} recordings.")
# Directory where the recordings will be saved
path = 'recordings'
os.makedirs(path, exist_ok=True)
for i, recording in enumerate(response):
url = recording['recording_url']
print(f"Downloading recording: {url}")
# Download the file
r = requests.get(url)
file_path = os.path.join(path, f'{recording["recording_id"]}.{recording["recording_format"]}')
with open(file_path, 'wb') as f:
f.write(r.content)
print(f"Downloaded file to: {file_path}")
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```php theme={null}
";
$AUTH_TOKEN = "";
$client = new RestClient($AUTH_ID,$AUTH_TOKEN);
try {
$response = $client->recordings->list(
[
'add_time__gt' => "2023-04-01 00:00:00",
'add_time__lt' => "2023-04-30 00:00:00",
'limit' => 5,
'offset' => 0
]
);
echo "Found " . count($response->resources) . " recordings." . PHP_EOL;
// Directory where the recordings will be saved
$dir = "./recordings";
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
$http = new Client();
foreach ($response as $recording) {
$recording_url = $recording->recordingUrl;
$recording_id = $recording->recordingId;
$format = $recording->recordingFormat;
echo "Downloading recording: " . $recording_url . PHP_EOL;
$output_file = $dir . "/" . $recording_id . "." . $format;
// Download the file
$http->get($recording_url, ['sink' => $output_file]);
echo "Downloaded file to: " . $output_file . PHP_EOL;
}
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```cs theme={null}
/**
* Example script for downloading recording files
*/
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace PlivoExamples
{
internal class Program
{
private const string AUTH_ID = "";
private const string AUTH_TOKEN = "";
public static async Task Main(string[] args)
{
var api = new PlivoApi(AUTH_ID,AUTH_TOKEN);
try
{
var response = api.Recording.List(
addTime_Gt: DateTime.Parse("2023-04-01 00:00:00"),
addTime_Lt: DateTime.Parse("2023-04-30 00:00:00"),
limit:5,
offset:0
);
Console.WriteLine($"Found {response.Objects.Count} recordings.");
// Directory where the recordings will be saved
string dir = "./recordings";
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
foreach (var recording in response.Objects)
{
string recordingUrl = recording.RecordingUrl;
string recordingId = recording.RecordingId;
string format = recording.RecordingFormat;
Console.WriteLine("Downloading recording: " + recordingUrl);
string outputFilePath = Path.Combine(dir, recordingId + "." + format);
// Download the file
using (var httpClient = new HttpClient())
{
var fileBytes = await httpClient.GetByteArrayAsync(recordingUrl);
await File.WriteAllBytesAsync(outputFilePath, fileBytes);
}
Console.WriteLine("Downloaded file to: " + outputFilePath);
}
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```java theme={null}
package com.plivo.examples;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.exceptions.PlivoValidationException;
import com.plivo.api.models.base.ListResponse;
import com.plivo.api.models.recording.Recording;
import com.plivo.api.util.PropertyFilter;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Example script for downloading recording files
*/
public class DownloadRecordings {
private static final String AUTH_ID = "";
private static final String AUTH_TOKEN = "";
public static void main(String[] args) {
Plivo.init(AUTH_ID, AUTH_TOKEN);
try {
String greaterThan = "2023-04-01 00:00:00";
String lessThan = "2023-04-30 00:00:00";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date greaterThanDate = formatter.parse(greaterThan);
Date lessThanDate = formatter.parse(lessThan);
ListResponse response = Recording.lister().addTime(new PropertyFilter().greaterThan(greaterThanDate).lessThan(lessThanDate)).offset(0).limit(5).list();
System.out.println("Found " + response.getObjects().size() + " recordings.");
for (Recording recording : response.getObjects()) {
String recordingURL = recording.getRecordingUrl();
String recordingId = recording.getRecordingId();
String format = recording.getRecordingFormat();
System.out.println("Downloading recording: " + recordingURL);
// Directory where the recordings will be saved
File outputFile = new File("recordings/" + recordingId + "." + format);
outputFile.getParentFile().mkdirs();
try {
// Download the file
FileUtils.copyURLToFile(new URL(recordingURL), outputFile);
System.out.println("Downloaded file to: " + outputFile.getPath());
} catch (IOException e) {
System.out.println("Error downloading file: " + e.getMessage());
}
}
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
} catch (PlivoValidationException e) {
throw new RuntimeException(e);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
## Overview
This guide shows how to retrieve recordings and download them to local storage. Plivo begins charging for stored recordings after 90 days. To avoid these charges, you can download recordings and store them elsewhere.
## Prerequisites
To use Plivo APIs, follow our instructions to set up a go development environment and a web server and safely expose that server to the internet.
## Download recordings to local storage
Here’s sample code you can use to retrieve recordings to a local directory.
```go theme={null}
// Example script for downloading recording files
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"github.com/plivo/plivo-go/v7"
)
var (
AuthID = ""
AuthToken = ""
)
func main() {
client, err := plivo.NewClient(AuthID, AuthToken, &plivo.ClientOptions{})
if err != nil {
fmt.Println("Error", err.Error())
return
}
response, err := client.Recordings.List(
plivo.RecordingListParams{
AddTimeGreaterThan: "2023-04-01 00:00:00",
AddTimeLessThan: "2023-04-30 00:00:00",
Offset: 0,
Limit: 5,
},
)
if err != nil {
fmt.Println("Error", err.Error())
return
}
fmt.Printf("Found %d recordings.\n", len(response.Objects))
// Directory where the recordings will be saved
os.MkdirAll("recordings", os.ModePerm)
for _, recording := range response.Objects {
fmt.Println("Downloading recording: ", recording.RecordingURL)
filePath := filepath.Join("recordings", recording.RecordingID+recording.RecordingFormat)
err = downloadFile(filePath, recording.RecordingURL)
if err != nil {
fmt.Println("Error downloading file: ", err)
} else {
fmt.Println("Downloaded file to: ", filePath)
}
}
}
func downloadFile(filepath string, url string) error {
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
return err
}
```
## Delete recordings from Plivo storage
You can delete a recording by using the Delete a Recording API and specifying a recording ID, which you can retrieve from list all recordings API or the HTTP callback details stored in your database. You can also delete recordings from the Voice Recordings page of the Plivo console.
# Phone system IVR
Source: https://plivo.com/docs/voice/use-cases/ivr
Build an interactive voice response phone system with menu navigation
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to implement IVR
Create a file called `ivr.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.set('port', (process.env.PORT || 5000));
// Message that Plivo reads when the caller dials in
var IvrMessage1 = "Welcome to the demo. Press 1 to contact sales. Press 2 to contact support";
// Message that Plivo reads when the caller does nothing
var NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
var WronginputMessage = "Sorry, that's not a valid entry";
// Sales Phone number
var salesPhoneNumber = "+15671234567"
// Support Phone number
var supportPhoneNumber = "+15671234578"
app.post('/ivr/', function(request, response) {
var r = plivo.Response();
var getinput_action_url, params, get_input;
getinput_action_url = request.protocol + '://' + request.headers.host + '/ivr/firstbranch/';
params = {
'action': getinput_action_url,
'method': 'POST',
'inputType': 'dtmf',
'digitEndTimeout': '5',
'redirect': 'true',
};
get_input = r.addGetInput(params);
get_input.addSpeak(IvrMessage1);
r.addSpeak(NoinputMessage);
console.log(r.toXML());
response.set({'Content-Type': 'text/xml'});
response.send(r.toXML());
});
app.post('/ivr/firstbranch/', function(request, response) {
var r = plivo.Response();
var digit = request.body.Digits;
console.log(digit);
if (digit === '1') {
var dial = r.addDial();
dial.addNumber(salesPhoneNumber);
} else if (digit === '2') {
var dial = r.addDial();
dial.addNumber(supportPhoneNumber);
} else {
r.addSpeak(WronginputMessage);
}
console.log(r.toXML());
response.set({'Content-Type': 'text/xml'});
response.send(r.toXML());
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
node ivr.js
```
You should see your basic server application in action at [http://localhost:3000/ivr/](http://localhost:3000/ivr/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the Express server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to implement IVR
Change to the project directory and run this command to create a Rails controller for inbound calls.
```shell theme={null}
rails generate controller Plivo voice
```
This generates a controller named plivo\_controller in the app/controllers/ directory and a respective view in app/views/plivo. We can delete the view as we don‘t need it.
```shell theme={null}
rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and paste into the PlivoController class this code.
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
$ivr_message1 = "Welcome to the demo. Press 1 to contact sales. Press 2 to contact support"
# Message that Plivo reads when the caller does nothing
$noinput_message = "Sorry, I did not catch that. Please hang up and try again"
# Message that Plivo reads when the caller enters an invalid number
$wronginput_message = "Sorry, that's not a valid entry"
# Sales Phone number
$salesphone_number = "+15671234567"
# Support Phone number
$supportphone_number = "+15671234578"
def ivr
r = Response.new()
getinput_action_url = "https://.com/ivr/firstbranch/"
params = {
action: getinput_action_url,
method: 'POST',
digitEndTimeout: '5',
inputType:'dtmf',
redirect:'true'
}
getinput = r.addGetInput(params)
getinput.addSpeak($ivr_message1)
r.addSpeak($noinput_message)
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
def firstbranch
digit = params[:Digits]
r = Response.new()
if (digit == "1")
r = response.addDial()
r.addNumber(salesphone_number)
elsif (digit == "2")
r = response.addDial()
r.addNumber(supportphone_number)
else
r.addSpeak($wronginput_message)
end
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
end
```
### Add a route
Add a route for the inbound function in PlivoController class. Edit config/routes.rb and add these lines after the inbound route:
```shell theme={null}
get 'plivo/ivr'
get 'plivo/firstbranch'
```
Start the Rails server.
```shell theme={null}
rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/ivr/](http://localhost:3000/plivo/ivr/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the Rails controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask server to implement IVR
Create a file called `ivr.py` and paste into it this code.
```py theme={null}
# -*- coding: utf-8 -*-
from flask import Flask, Response, request, url_for
from plivo import plivoxml
# Message that Plivo reads when the caller dials in
ivr_message1 = "Welcome to the demo. Press 1 to contact sales. Press 2 to contact support"
# Message that Plivo reads when the caller does nothing
noinput_message = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller enters an invalid number
wronginput_message = "Sorry, that's not a valid entry"
# Sales Phone number
salesphone_number = "+15671234567"
# Support Phone number
supportphone_number = "+15671234578"
app = Flask(__name__)
@app.route('/ivr/', methods=['GET','POST'])
def ivr():
response = plivoxml.ResponseElement()
response.add(plivoxml.GetInputElement().
set_action(url_for('firstbranch', _external=True)).
set_method('POST').
set_input_type('dtmf').
set_digit_end_timeout(5).
set_redirect(True).add(
plivoxml.SpeakElement(ivr_message1)))
response.add(plivoxml.SpeakElement(noinput_message))
return Response(response.to_string(), mimetype='application/xml')
@app.route('/ivr/firstbranch/', methods=['GET','POST'])
def firstbranch():
response = plivoxml.ResponseElement()
digit = request.values.get('Digits')
if digit == "1":
response.add(plivoxml.DialElement().add(
plivoxml.NumberElement(salesphone_number)))
elif digit == "2":
response.add(plivoxml.DialElement().add(
plivoxml.NumberElement(supportphone_number)))
else:
response.add_speak(wronginput_message)
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Save the file and run it.
```shell theme={null}
python ivr.py
```
You should see your basic server application in action at [http://localhost:5000/ivr/](http://localhost:5000/ivr/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the Flask application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel server to implement IVR
Change the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
php artisan make:controller IvrController
```
This generates a controller named IvrController in the app/http/controllers/ directory. Edit app/http/controllers/IvrController.php and paste into it this code.
```php theme={null}
.com/firstbranch.php";
$get_input = $r->addGetInput([
'action' => $getinput_action_url,
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($IvrMessage);
$r->addSpeak($NoinputMessage);
Header('Content-type: text/xml');
echo $r->toXML();
}
// Action URL block for DTMF
public function firstBranch(Request $request)
{
# File to be played when a caller presses 2
$PlivoSong = "https://s3.amazonaws.com/plivocloud/music.mp3";
$IvrMessage = "Press 1 for English. Press 2 for French. Press 3 for Russian";
# Message that Plivo reads when the caller does nothing
$NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
# Message that Plivo reads when the caller enters an invalid number
$WronginputMessage = "Sorry, that's not a valid entry";
$r = new Response();
$digit = $_REQUEST['Digits'];
if ($digit == '1'){
$dial = $response->addDial();
$dial->addNumber($salesPhoneNumber);
}
else if ($digit == '2'){
$dial = $response->addDial();
$dial->addNumber($supportPhoneNumber);
}
else {
$r->addSpeak($WronginputMessage);
}
Header('Content-type: text/xml');
echo $r->toXML();
}
}
```
### Add a route
Add a route for the forward function in the IvrController class. Edit routes/web.php and add these lines:
```shell theme={null}
Route::match(['get', 'post'], '/ivr', 'IvrController@ivrMain');
Route::match(['get', 'post'], '/firstbranch', 'IvrController@firstBranch');
```
Start the Laravel server.
```shell theme={null}
php artisan serve
```
You should see your basic server application in action at [http://localhost:8000/ivr](http://localhost:8000/ivr).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the Laravel server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to implement IVR
In Visual Studio, create a controller called `IvrController.cs` and paste into it this code.
```cs theme={null}
using System;
using Plivo.XML;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Diagnostics;
namespace Ivrphonetree.Controllers
{
public class IvrController : Controller
{
// Message that Plivo reads when the caller dials in
String IvrMessage = "Welcome to the demo. Press 1 to contact sales. Press 2 to contact support";
// Message that Plivo reads when the caller does nothing
String NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
String WronginputMessage = "Sorry, that's not a valid entry";
// Sales Phone Number
String salesPhoneNumber = "+15671234567";
// Support Phone number
String supprtPhoneNumber = "+15671234578";
// GET: //
public IActionResult Index()
{
var resp = new Response();
Plivo.XML.GetInput get_input = new
Plivo.XML.GetInput("",
new Dictionary()
{
{"action", "https://.com/ivr/firstbranch/"},
{"method", "POST"},
{"digitEndTimeout", "5"},
{"inputType", "dtmf"},
{"redirect", "true"},
});
resp.Add(get_input);
get_input.AddSpeak(IvrMessage,
new Dictionary() { });
resp.AddSpeak(NoinputMessage,
new Dictionary() { });
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// First branch of IVR phone tree
public IActionResult FirstBranch()
{
String digit = Request.Query["Digits"];
Debug.WriteLine("Digit pressed : {0}", digit);
var resp = new Response();
if (digit == "1")
{
String getinput_action_url = "https://.com/ivr/secondbranch/";
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {{}});
dial.AddNumber(salesPhoneNumber,
new Dictionary() { });
resp.Add(dial);
}
else if (digit == "2")
{
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary() {{}});
dial.AddNumber(supprtPhoneNumber,
new Dictionary() { });
resp.Add(dial);
}
else
{
// Add Speak XML tag
resp.AddSpeak(WronginputMessage,new Dictionary() { });
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Before starting the application, edit Properties/launchSettings.json and set the applicationUrl as
"applicationUrl": "[http://localhost:5000/](http://localhost:5000/)"
Run the project and you should see your basic server application in action at [http://localhost:5000/ivr/](http://localhost:5000/ivr/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the MVC controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark web application to implement IVR
Create a Java class called `IVR` and paste into it this code.
```java theme={null}
import com.plivo.api.exceptions.PlivoValidationException;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.GetInput;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
import com.plivo.api.xml.Number;
import static spark.Spark.*;
public class ivr {
public static void main(String[] args) throws PlivoValidationException, PlivoXmlException {
// Message that Plivo reads when the caller dials in
String ivrMessage = "Welcome to the demo. Press 1 to contact sales. Press 2 to contact support";
// Message that Plivo reads when the caller does nothing
String noInputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
String wrongInputMessage = "Sorry, that's not a valid entry";
// Sales Phone number
final String salesPhoneNumber = "+15671234567";
// Support Phone number
final String supportPhoneNumber = "+15671234578";
post("/ivr/", (req, res) -> {
res.type("application/xml");
Response resp = new Response();
resp.children(
new GetInput()
.action("https://.com/ivr/firstbranch/")
.method("POST")
.inputType("dtmf")
.digitEndTimeout(5)
.redirect(true)
.children(
new Speak(ivrMessage)
)
);
resp.children(new Speak(noInputMessage));
return resp.toXmlString();
});
post("/ivr/firstbranch/", (req, res) -> {
res.type("application/xml");
String digit = req.queryParams("Digits");
Response resp = new Response();
if (digit.equals("1")) {
resp.children(
new Dial()
.children(
new Number(salesPhoneNumber)
)
);
resp.children(new Speak(noInputMessage));
} else if (digit.equals("2")) {
resp.children(
new Dial()
.children(
new Number(supportPhoneNumber)
)
);
} else {
resp.children(
new Speak(wrongInputMessage)
);
}
return resp.toXmlString();
});
}
}
```
Run the project and you should see your basic server application in action at [http://localhost:4567/ivr/](http://localhost:4567/ivr/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the Spark web application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
## Overview
Interactive voice response (IVR) systems let incoming callers access information and find contacts via a menu of prerecorded messages, without having to speak to an agent, and let you automate polling via outgoing calls. Callers and call recipients can respond to prompts via Touch-Tone keypad presses or speech recognition. IVR systems can handle larger call volumes than operators and reduce costs associated with customer service.
Common IVR use cases include:
* **Auto-attendant**: You can replace a receptionist with an IVR system that routes calls to agents during business hours and accepts voicemail when no one is available.
* **Call center**: You can route calls coming in to call centers to the appropriate representatives based on user input.
* **Surveys, polling, and voting**: You can implement IVR in outbound calls to collect customer satisfaction scores or conduct political polling.
* **Appointment reminders**: You can send automated reminders to customers before their scheduled visits to help avoid missed appointments and facilitate rescheduling.
* **Lead assignment and lead routing**: For inbound sales calls, you can set up an IVR menu with a set of qualifying questions to discover a customer’s interests, then redirect their call to a representative based on their responses.
This guide shows how to build an IVR menu system on the Plivo platform, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here‘s how to implement an IVR system using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to implement IVR
Create a file called `ivr.go` and paste into it this code.
```go theme={null}
package main
import (
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
m := martini.Classic()
const
(
// Message that Plivo reads when the caller dials in
WelcomeMessage = "Welcome to the demo. Press 1 to contact sales. Press 2 to contact support"
// Message that Plivo reads when the caller does nothing
NoInputMessage = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller enters an invalid number
WrongInputMessage = "Sorry, that's not a valid entry"
// Sales phone number
SalesPhoneNumber = "+15671234567"
// Support phone number
SupportPhoneNumber = "+15671234578"
)
m.Post("/ivr/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.GetInputElement).
SetAction("https://.com/ivr/firstbranch/").
SetMethod("POST").
SetDigitEndTimeout(5).
SetInputType("dtmf").
SetRedirect(true).
SetContents([]interface{}{new(xml.SpeakElement).
AddSpeak(WelcomeMessage),
}),
new(xml.SpeakElement).
AddSpeak(NoInputMessage),
},
}
return response.String()
})
m.Post("/ivr/firstbranch/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
digit := r.FormValue("Digits")
if digit == "1" {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).
SetContents(
[]interface{}{
new(xml.NumberElement).
SetContents(SalesPhoneNumber),
},
),
},
}.String()
} else if digit == "2" {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).
SetContents(
[]interface{}{
new(xml.NumberElement).
SetContents(SupportPhoneNumber),
},
),
},
}.String()
} else {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak(WrongInputMessage),
},
}.String()
}
})
m.Run()
}
```
Save the file and run it.
```shell theme={null}
$ go run ivr.go
```
You should see your basic server application in action at [http://localhost:8080/ivr/](http://localhost:8080/ivr/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application
Associate the Go server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application#create-an-application).
Give your application a name — we called ours `Phone IVR`. Enter the server URL you want to use (for example `https://.com/ivr/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Phone IVR` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo phone number and see how the IVR application works.
# Make Bulk Calls
Source: https://plivo.com/docs/voice/use-cases/make-bulk-calls
Make outgoing voice calls to multiple numbers with text-to-speech greetings
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Node.js development environment.
## Make an outbound call to multiple numbers
Create a file called `Bulkcall.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.create(
"", // from
"destination_number1
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Ruby development environment.
## Make an outbound call to multiple numbers
Create a file called `bulk_call.rb` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'',
['', ''],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',
{
answer_method: "GET",
},
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
$ ruby bulk_call.rb
```
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Python development environment.
## Make an outbound call to multiple numbers
Create a file called `bulk_call.py` and paste into it this code.
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from='',
to='destination_number1
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a PHP development environment.
## Make an outbound call to multiple numbers
Create a file called `BulkCall.php` and paste into it this code:
```php theme={null}
";
$auth_token = "";
$p = new RestClient($auth_id, $auth_token);
$response = $client->calls->create('',
['', ''],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',);
print_r($response);
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
$ php BulkCall.php
```
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a .NET development environment.
## Make an outbound call to multiple numbers
In Visual Studio, in the CS project, open the file `Program.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
namespace testplivo
{
class Program
{
static void Main(string[] args)
{
var api = new PlivoApi("","");
var response = api.Call.Create(
to: new List { "", "" },
from: "",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/answer.xml"
);
Console.WriteLine(response);
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Java development environment.
## Make an outbound call to multiple numbers
Create a Java class in the project called `BulkCall` and paste into it this code.
```java theme={null}
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class MakeCall {
public static void main(String [] args) throws IOException, PlivoRestException {
Plivo.init("","");
CallCreateResponse response = Call.creator("",
Collections.singletonList("", ""),
"https://s3.amazonaws.com/static.plivo.com/answer.xml")
.answerMethod("GET")
.create();
System.out.println(response);
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
## Overview
This guide shows how to make an outgoing call to multiple numbers and greet call recipients with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
To make bulk calls using Plivo APIs, you make an HTTP POST request to the Call API as you would to place a single outbound call, but add multiple destination numbers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation and a web server and safely expose that server to the internet.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment.
## Make an outbound call to multiple numbers
Create a file called `BulkCall.go` and paste into it this code:
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
client, err := plivo.NewClient("","", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Calls.Create(
plivo.CallCreateParams{
From: "",
To: "destination_number1
# Make Outbound Calls
Source: https://plivo.com/docs/voice/use-cases/make-outbound-calls
Place outbound voice calls programmatically using the Plivo Voice API
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Node.js development environment.
## Make an outbound call
Create a file called `Makecall.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.create(
"", // from
"", // to
"https://s3.amazonaws.com/static.plivo.com/answer.xml", // answer url
{
answerMethod: "GET",
},
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
$ node Makecall.js
```
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Ruby development environment.
## Make an outbound call
Create a file called `make_call.rb` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'+12025550000',
['+12025551111'],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',
{
answer_method: "GET",
},
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
$ ruby make_call.rb
```
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Python development environment.
## Make an outbound call
Create a file called `make_call.py` and paste into it this code.
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from_='',
to_='',
answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml',
answer_method='GET', )
print(response)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
$ python make_call.py
```
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a PHP development environment.
## Make an outbound call
Create a file called `MakeCall.php` and paste into it this code:
```php theme={null}
";
$auth_token = "";
$p = new RestClient($auth_id, $auth_token);
$response = $client->calls->create('',
[''],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',);
print_r($response);
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
$ php MakeCall.php
```
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a .NET development environment.
## Make an outbound call
In Visual Studio, in the CS project, open the file `Program.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
namespace testplivo
{
class Program
{
static void Main(string[] args)
{
÷ var api = new PlivoApi("","");
var response = api.Call.Create(
to: new List { "" },
from: "",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/answer.xml"
);
Console.WriteLine(response);
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Java development environment.
## Make an outbound call
Create a Java class in the project `MakeCall` and paste into it this code.
```java theme={null}
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class MakeCall {
public static void main(String [] args) throws IOException, PlivoRestException {
Plivo.init("","");
CallCreateResponse response = Call.creator("",
Collections.singletonList(""),
"https://s3.amazonaws.com/static.plivo.com/answer.xml")
.answerMethod("GET")
.create();
System.out.println(response);
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
## Overview
This guide shows how to make an outgoing call and greet the call recipient with a text-to-speech message when they answer. Use cases such as voice notifications and alerts, voice surveys, and, voice one-time passwords involve outbound calls as part of their call flow.
You can start making and receiving calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call and leave a text-to-speech message when the recipient answers the call.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You can also follow our instructions to set up a Go development environment.
## Make an outbound call
Create a file called `MakeCall.go` and paste into it this code:
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
client, err := plivo.NewClient("","", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Calls.Create(
plivo.CallCreateParams{
From: "",
To: "",
AnswerURL: "https://s3.amazonaws.com/static.plivo.com/answer.xml",
AnswerMethod: "GET",
},
)
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
## Test
Save the file and run it.
```shell theme={null}
go run MakeCall.go
```
# Number Masking
Source: https://plivo.com/docs/voice/use-cases/number-masking
Hide caller and recipient phone numbers using proxy number masking
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## How it works
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created sample mapping data in a config.js file:
```javascript theme={null}
const config = {app: {port: 5000}}
config.customerAgentMap = {
'14156667777':'14156667778',
'14156667779':'14156667780',
'14156667781':'14156667782'
};
module.exports = config;
```
## Create an Express application for number masking
Create a file called `number_masking.js` and paste into it this code.
```js theme={null}
const config = require('./config');
const plivo = require('plivo');
const express = require('express');
const app = express();
app.set('port', (process.env.PORT || 5000));
// Handle incoming calls to a Plivo number, connect agent with customer and vice versa without revealing their actual phone numbers.
app.all('/handleincoming/', function(req, res) {
const fromNumber = (req.query.From);
const toNumber = (req.query.To);
const response = plivo.Response();
const customerPhoneMapping = config.customerAgentMap;
const agentCustomerMapping = Object.fromEntries(Object.entries(customerPhoneMapping).map(v => v.reverse()));
if(fromNumber in customerPhoneMapping){ // Check whether the customer's number is in the customer-agent mapping
const number = customerPhoneMapping[fromNumber]; // Assign the value from the customer-agent array to number variable
const params = {
'callerId': toNumber, // Plivo number is used as the caller ID for the call toward the agent
};
const dial = response.addDial(params);
const destNumber = number;
dial.addNumber(destNumber);
res.send(response.toXML());
}
else if(fromNumber in agentCustomerMapping){ // Check whether the agent's number is in the customer-agent mapping
const number = agentCustomerMapping[fromNumber]; // Assign the key from the customer-agent array to number variable
const params = {
'callerId': toNumber, // Plivo number is used as the caller ID for the call toward the customer
};
const dial = response.addDial(params);
const destNumber = number;
dial.addNumber(destNumber);
res.send(response.toXML());
}
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
$ node number_masking.js
```
You should see your basic server application in action at [http://localhost:5000/handleincoming/](http://localhost:5000/handleincoming/).
Set up ngrok to expose your local server to the internet.
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the Express application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## Outline
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created sample mapping data in a config/application.rb file:
```
# customer <> agent map
config.base_map = {"14156667777" => "14156667778", "14156667779" => "14156667780", "14156667781" => "14156667782"}
```
## Create a Rails controller for number masking
Change to the project directory and run the command `rails generate controller Numbermasking` to create a Rails controller named numbermasking\_controller in the app/controllers/ directory. Edit the app/controllers/numbermasking\_controller.rb file and paste into it this code:
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
\# Handle incoming calls to a Plivo number, connect agent with customer and vice versa without revealing their actual phone numbers.
class NumbermaskingController < ApplicationController
def handle_incoming
customer_agent_map = Rails.application.config.base_map
agent_customer_map = customer_agent_map.invert
from_number = params[:From]
to_number = params[:To]
response = Response.new()
customer_to_agent = customer_agent_map.include?(from_number) # Check whether the customer's number is in the customer-agent mapping
agent_to_customer = agent_customer_map.include?(from_number) # Check whether the agent's number is in the customer-agent mapping
if(customer_to_agent == true)
dest_number = customer_agent_map[from_number] # Assign the value from the customer-agent array to dest_number variable
params = {
'callerId' => to_number # Plivo number is used as the caller ID for the call toward the agent
}
dial = response.addDial(params)
dial.addNumber(dest_number)
elsif(agent_to_customer == true)
dest_number = agent_customer_map[from_number] # Assign the key from the customer-agent array to dest_number variable
params = {
'callerId' => to_number # Plivo number is used as the caller ID for the call toward the customer
}
dial = response.addDial(params)
dial.addNumber(dest_number)
end
xml = PlivoXML.new(response)
puts xml.to_xml()
render xml: xml.to_xml
end
end
```
### Add a route
Add a route for the handle\_incoming function in NumbermaskingController class. Edit the config/routes.rb file and add this line after the outbound route:
```shell theme={null}
get 'numbermasking/handle_incoming'
```
Start the Rails server to forward incoming calls.
```shell theme={null}
$ rails server
```
You should see your basic server application in action at [http://localhost:3000/numbermasking/handle\_incoming/](http://localhost:3000/numbermasking/handle_incoming/).
Set up ngrok to expose your local server to the internet.
Note: Before you start the ngrok service, add ngrok in the config.hosts list in the config/environments/development.rb file and include the line below. You’ll start to see Blocked host errors if you fail to add this.
```shell theme={null}
# Whitelist ngrok domain
config.hosts << /[a-z0-9]+\.ngrok\.io/
```
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the Rails controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## How it works
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created sample mapping data in a config.ini file:
```
[c2amap]
customer_agent = {"14156667777":"14156667778", "14156667779":"14156667780", "14156667781":"14156667782"}
```
## Create a Flask application for number masking
Create a file called `number_masking.py` and paste into it this code.
```py theme={null}
import json
from flask import Flask, Response, request
from configparser import ConfigParser
from plivo import plivoxml
config = ConfigParser()
config.read('config.ini')
app = Flask(__name__)
\# Handle incoming calls to a Plivo number, connect agent with customer and vice versa without revealing their actual phone numbers.
@app.route("/handleincoming/", methods=["GET", "POST"])
def number_masking():
base_map = config.get("c2amap","customer_agent")
customer_agent_map = json.loads(base_map) # Customer-agent mapping data
agent_customer_map = {v: k for k, v in customer_agent_map.items()} # Agent-customer mapping data
from_number = request.form.get("From") or request.args.get("From")
to_number = request.form.get("To") or request.args.get("To")
response = plivoxml.ResponseElement()
if from_number in customer_agent_map: # Check whether the customer's number is in the customer-agent mapping
number = customer_agent_map[from_number] # Assign the value from the customer-agent array to number variable
response.add(
plivoxml.DialElement(
caller_id=to_number, # Plivo number is used as the caller ID for the call toward the agent
).add(plivoxml.NumberElement(number))
)
elif from_number in agent_customer_map: # Check whether the agent's number is in the customer-agent mapping
number = agent_customer_map[from_number] # Assign the key from the customer-agent array to number variable
response.add(
plivoxml.DialElement(
caller_id=to_number, # Plivo number is used as the caller ID for the call toward the customer
).add(plivoxml.NumberElement(number))
)
print(response)
return Response(response.to_string(), mimetype='application/xml')
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
Save the file and run it.
```shell theme={null}
$ python number_masking.py
```
You should see your basic server application in action at [http://localhost:5000/handleincoming/](http://localhost:5000/handleincoming/).
Set up ngrok to expose your local server to the internet.
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the Flask application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## How it works
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created sample mapping data in a config/app.php file:
```php theme={null}
'customer_agent_map' => [
'14156667777' => '14156667778',
'14156667779' => '14156667780',
'14156667781' => '14156667782',
],
```
## Create a Laravel controller for number masking
Change to the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller MaskingController
```
This command generates a controller named MaskingController in the app/http/controllers/ directory. Edit the app/http/controllers/MaskingController.php file and paste into it this code:
```php theme={null}
$to_number, // Plivo number is used as the caller ID for the call toward the agent
);
$dial = $response->addDial($params);
$dial->addNumber($number);
} elseif ($agent_to_customer == true){
$number = array_search($from_number, $customerPhoneMaping); // Assign the key from the customer-agent array to $number variable
$params = array(
'callerId' => $to_number, // Plivo number is used as the caller ID for the call toward the customer
);
$dial = $response->addDial($params);
$dial->addNumber($number);
}
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
}
```
### Add a route
To add a route for the functions in the MaskingController class, edit the routes/web.php file and add this line at the end of the file:
```shell theme={null}
Route::match(['get', 'post'], '/numbermasking', 'App\Http\Controllers\MaskingController@numberMasking');
```
Note: You can edit the app/Http/Middleware/VerifyCsrfToken.php file and add the route of the app numbermasking to the “except” array to disable CSRF verification.
Run this command to start the Laravel server to forward incoming calls.
```shell theme={null}
$ php artisan serve
```
You should see the Laravel controller in action on [http://localhost:8000/numbermasking/](http://localhost:8000/numbermasking/).
Set up ngrok to expose your local server to the internet.
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the Laravel controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## How it works
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created an App.config file with sample mapping data for this project:
```xml theme={null}
```
## Create an MVC controller for number masking
In Visual Studio, navigate to the Controllers directory in the NumberMasking application. Create a controller named `HandleIncomingController.cs` and paste into it this code:
```cs theme={null}
using System.Configuration;
using Plivo.XML;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using System.Collections;
// Handle incoming calls to a Plivo number, connect agent with customer and vice versa without revealing their actual phone numbers.
namespace NumberMasking.Controllers
{
public class HandleIncomingController : Controller
{
// GET: //
public IActionResult Index()
{
string FromNumber = Request.Query["From"];
string ToNumber = Request.Query["To"];
var resp = new Response();
// Customer-agent mapping
var CustomerAgentMap = (ConfigurationManager.GetSection("CustomerAgent") as Hashtable)
.Cast()
.ToDictionary(n => n.Key.ToString(), n => n.Value.ToString());
// Agent-customer mapping
var AgentCustomerMap = CustomerAgentMap.ToDictionary(kp => kp.Value, kp => kp.Key);
if (CustomerAgentMap.ContainsKey(FromNumber)) // Check whether the customer's number is in the customer-agent mapping
{
var DestNumber = CustomerAgentMap[FromNumber]; // Assign the value from the customer-agent array to number variable
Dial dial = new Dial(new
Dictionary() {
{"callerId", ToNumber} // Plivo number is used as the caller ID for the call toward the agent
});
dial.AddNumber(DestNumber,
new Dictionary() { });
resp.Add(dial);
}
else if (AgentCustomerMap.ContainsKey(FromNumber)) // Check whether the agent's number is in the customer-agent mapping
{
var DestNumber = AgentCustomerMap[FromNumber]; // Assign the key from the customer-agent array to number variable
Dial dial = new Dial(new
Dictionary() {
{"callerId", ToNumber} // Plivo number is used as the caller ID for the call toward the customer
});
dial.AddNumber(DestNumber,
new Dictionary() { });
resp.Add(dial);
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Before you start the application, edit the Properties/launchSettings.json file and set the `applicationUrl`:
```json theme={null}
"applicationUrl": "http://localhost:5000/"
```
Run the project and you should see your basic server application in action at [http://localhost:5000/handleincoming/](http://localhost:5000/handleincoming/).
Set up ngrok to expose your local server to the internet.
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the MVC controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## How it works
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created sample mapping data in the src/main/resources/application.properties file:
```json theme={null}
spring.main.banner-mode=off
spring.output.ansi.enabled=ALWAYS
logging.pattern.console=%clr(%d{yy-MM-dd E HH:mm:ss.SSS}){blue} %clr(%-5p) %clr(%logger{0}){blue} %clr(%m){faint}%n
number.map={"14156667777":"14156667778", "14156667779":"14156667780", "14156667781":"14156667782"}
```
## Create a Spring application for number masking
Open the NumberMaskingApplication.java file in the src/main/java/com.example.NumberMasking/ folder and paste into it this code.
Note: Here, the demo application name is NumberMaskingApplication.java because the friendly name we provided in Spring Initializr was `NumberMasking`.
```java theme={null}
package com.example.NumberMasking;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Number;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import com.google.common.collect.HashBiMap;
import java.util.Map;
@SpringBootApplication
@RestController
public class NumberMaskingApplication {
@Value("#{${number.map}}")
Map CustomerAgentMap;
public static void main(String[] args) {
SpringApplication.run(NumberMaskingApplication.class, args);
}
// Handle incoming calls to a Plivo number, connect agent with customer and vice versa without revealing their actual phone numbers.
@RequestMapping(value = "/number_masking/", produces = { "application/xml" }, method = { RequestMethod.GET, RequestMethod.POST })
public Response HandleIncoming(@RequestParam("From") String FromNumber, @RequestParam("To") String ToNumber)
throws PlivoXmlException {
Map AgentCustomerMap = HashBiMap.create(CustomerAgentMap).inverse();
Response response = new Response();
if(CustomerAgentMap.containsKey(FromNumber)) { // Check whether the customer's number is in the customer-agent mapping
var DestNumber = CustomerAgentMap.get(FromNumber); // Assign the value from the customer-agent map to DestNumber variable
response.children(new Dial()
.callerId(ToNumber) // Plivo number is used as the caller ID for the call toward the agent
.children(new Number(DestNumber)));
}
else if (AgentCustomerMap.containsKey(FromNumber)) { // Check whether the agent's number is in the customer-agent mapping
var DestNumber = AgentCustomerMap.get(FromNumber); // Assign the Kky from the customer-agent map to DestNumber variable
response.children(new Dial()
.callerId(ToNumber) // Plivo number is used as the caller ID for the call toward the customer
.children(new Number(DestNumber)));
}
System.out.println(response.toXmlString());
return response;
}
}
```
Save the file and run it.
You should see your basic server application in action at [http://localhost:8080/number\_masking/](http://localhost:8080/number_masking/).
Set up ngrok to expose your local server to the internet.
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the Spring application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
## Overview
Phone number masking hides the phone numbers of parties in a call from each other. Many businesses find it advantageous to anonymize communication between two parties — for example, between a customer and a delivery agent on a food delivery service platform or a driver and a rider using a ride-hailing application. Businesses can implement phone number masking by sending calls through an intermediate phone number that acts as a proxy between the two parties. A Plivo number can serve as the intermediate number to connect the two parties while keeping their contact information private.
## How it works
As an example, we’ll build a number-masking application for a food delivery service that lets the company connect customers with delivery agents and vice versa without revealing any actual phone numbers. To do this, you
1. Create a customer-to-agent phone number mapping in your application’s back end.
2. Create the number masking application using Plivo.
3. Assign the number masking application to a Plivo number.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a 1:1 map with actual numbers
Create customer-to-agent phone number mapping for the application. Whenever a customer places an order, their phone number should be stored in a database for your application to access. A delivery agent will be assigned for the order, and the agent’s number will also be stored in your database, and will be mapped to the customer's number:
-
Customer's Number1-415-666-7777
-
Agent's Number1-415-666-7778
We created sample mapping data in a .env file:
```sh theme={null}
json
BASEMAP = {"14156667777":"14156667778","14156667779":"14156667780","14156667781":"14156667782"}
```
## Create a Go server for number masking
Create a file called `masking.go` and paste into it this code.
```go theme={null}
package main
import (
"encoding/json"
"log"
"os"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
"github.com/plivo/plivo-go/v7/xml"
)
// init gets called before the main function
func init() {
// Log error if .env file does not exist
err := godotenv.Load(".env")
if err != nil {
log.Fatal("Error loading .env file")
}
}
// Handle incoming calls to a Plivo number, connect agent with customer and vice versa without revealing their actual phone numbers.
func main() {
r := gin.Default()
r.GET("/number_masking", func(c *gin.Context) {
customerAgentmap := os.Getenv("BASEMAP")
// Declares an empty map interface
var result map[string]string
fromNumber := c.Query("From")
toNumber := c.Query("To")
// Unmarshal or Decode the JSON to the interface.
json.Unmarshal([]byte(customerAgentmap), &result)
agentCustomermap := reverseMap(result)
_, custToagent := result[fromNumber]
_, agenTocust := agentCustomermap[fromNumber]
if custToagent { // Check whether the customer's number is in the customer-agent mapping
destNumber := result[fromNumber] // Assign the value from the customer-agent array to number variable
c.XML(200, xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).
SetCallerID(toNumber). // Plivo number is used as the caller ID for the call toward the agent
SetContents([]interface{}{
new(xml.NumberElement).
SetContents(destNumber),
}),
},
})
} else if agenTocust { // Check whether the agent's number is in the customer-agent mapping
destNumber := agentCustomermap[fromNumber] // Assign the key from the customer-agent array to number variable
c.XML(200, xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).
SetCallerID(toNumber). // Plivo number is used as the caller ID for the call toward the customer
SetContents([]interface{}{
new(xml.NumberElement).
SetContents(destNumber),
}),
},
})
}
c.Header("Content-Type", "application/xml")
})
r.Run() // listen and serve on 0.0.0.0:8080 (for Windows "localhost:8080")
}
// Reverse the Basemap from env file to get customer-agent mapping data
func reverseMap(m map[string]string) map[string]string {
n := make(map[string]string)
for k, v := range m {
n[v] = k
}
return n
}
```
Save the file and run it.
```shell theme={null}
$ go run masking.go
```
You should see your basic server application in action on [http://localhost:8080/number\_masking/](http://localhost:8080/number_masking/).
Set up ngrok to expose your local server to the internet.
Now people can call your Plivo number. If an incoming call to your Plivo number is from one of the customer phone numbers in the customer-agent map — for example, if the caller number is `14156667777` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
If the incoming call to your Plivo number is from one of the agent phone numbers in the customer-agent map — for example, if the caller number is `14156667778` — then Plivo will send the XML response to process the incoming call as below, and you can check the XML document in your browser.
## Create a Plivo application
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Number Masking`. Enter the server URL you want to use (for example, https\://\.ngrok.io/handleincoming/) in the `Answer URL` field and set the method as `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Number Masking` (the name we gave the application).
Click **Update Number** to save.
## Test
To test the application, you need two Plivo numbers. Set up one of your numbers as a customer and another as an agent in the customer-to-agent mapping data in the config file. Make a call from each of your mobile numbers to the Plivo number you mapped to the application. You should see that the call is forwarded to the other number, and that the incoming call has the Plivo number as the caller ID.
# Participant-Level Recording
Source: https://plivo.com/docs/voice/use-cases/participant-level-recording
Record individual audio tracks for each participant in a multiparty call
## Overview
The participant-level recording feature enables you to generate individual audio recordings for each participant in an MPC. This is useful for scenarios where you need clear, isolated audio tracks for each participant, such as in interviews, conferences, or any multi-party communication.
## Example Use Case
**Scenario: Conduct Sentiment Analysis on Customer-Support Agent Interaction**
An organization may seek to conduct sentiment analysis on interactions between customers and support agents. To achieve this, the organization requires separate recording files of both the customer and the agent.
Here's how the process unfolds:
- The customer initiates a call to the support toll-free number.
- Upon initiation, an application is triggered, which adds the customer to the MPC bridge and initiates participant-level recording.
- Simultaneously, the support agent joins the MPC bridge, also with participant-level recording activated.
- During the call, both the customer and the support agent's interactions are recorded separately.
- Upon call completion, two distinct recording files are generated: one containing the audio of the customer and the other of the support agent.
- These recording files are then utilized for sentiment analysis, providing valuable insights into customer-agent interactions.
## Step-by-Step Guide
Participant-level recording can be achieved using both [API](/docs/voice/api/multiparty-calls#add-a-participant) and [XML](/docs/voice/xml/multiparty-call)
### Starting single-track or participant-level recording when adding a participant to the MPC
Use the following request to add a participant to the MPC and initiate a single-track recording. Please refer to the [API documentation](/docs/voice/api/multiparty-calls#add-a-participant) for more details.
```sh theme={null}
curl -i --user \
AUTH_ID:AUTH_TOKEN \
-H \
"Content-Type: application/json" \
-d '{"to": "+12025551111","from": "+12025550000", "role": "Agent", "start_mpc_on_enter": true, "recordParticipantTrack": true}' \
https://api.plivo.com/v1/Account/{auth_id}/MultiPartyCall/name_{mpc_name}/Participant/
```
### Start single-track or participant-level recording for any member in the MPC
Use the following request to initiate participant-level recording for an existing member on the MPC bridge. Please refer to the [API documentation](/docs/voice/api/multiparty-calls#record-a-participant) for more details.
```sh theme={null}
curl -i --user \
AUTH_ID:AUTH_TOKEN \
-H \
"Content-Type: application/json" \
-d '{"file_format": "mp3","record_track_type":"participant"}' \
https://api.plivo.com/v1/Account/{auth_id}/MultiPartyCall/{mpc_name/UUID}/Participant/{Member_Id}/Record/
```
### Initiate MPC with participant level recording using XML
Here is a sample XML to start participant-level recording. Please refer to the [XML documentation](/docs/voice/xml/multiparty-call) for more details.
```
mpc_customer
```
# Pass Custom Headers
Source: https://plivo.com/docs/voice/use-cases/pass-custom-headers
Send custom SIP headers with outbound voice calls for metadata routing
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment.
## Create the outbound call application with custom SIP headers
Create a file called `Makecall.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
// If auth id and auth token are not specified, Plivo will fetch them from the environment variables.
var client = new plivo.Client("","");
client.calls.create(
"", // from
"", // to
"https://s3.amazonaws.com/static.plivo.com/answer.xml", // answer url
{
answerMethod: "GET",
sipHeaders: "Test=Sample"
},
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `process.env` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ node Makecall.js
```
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment.
## Create the outbound call application with custom SIP headers
Create a file called `make_call.rb` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'',
[''],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',
sip_headers: 'Test=Sample',)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ ruby make_call.rb
```
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment.
## Create the outbound call application with custom SIP headers
Create a file called `make_call.py` and paste into it this code.
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from_='',
to_='',
answer_url='https://s3.amazonaws.com/static.plivo.com/answer.xml',
answer_method='GET',
sip_headers='Test=Sample')
print(response)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `os module(os.environ)` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ python make_call.py
```
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment.
## Create the outbound call application with custom SIP headers
Create a file called `MakeCall.php` and paste into it this code:
```php theme={null}
","");
try {
$response = $client->calls->create(
'',
[''],
'https://s3.amazonaws.com/static.plivo.com/answer.xml',
[
'ring_url' => 'https://WWW.RING.URL',
'sip_headers' => 'Test=Sample',
'answer_method' => 'GET'
]
);
print_r($response);
}
catch (PlivoRestException $ex) {
print_r($ex);
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use the `$_ENV` or `putenv/getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ php MakeCall.php
```
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment.
## Create the outbound call application with custom SIP headers
Open the file in the CS project called `Program.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples
{
internal class Program
{
public static void Main(string[] args)
{
var api = new PlivoApi("","");
try
{
var response = api.Call.Create(
to:new List{""},
from:"",
answerMethod:"GET",
answerUrl:"https://s3.amazonaws.com/static.plivo.com/answer.xml",
sipHeaders: "customer=johndoe"
);
Console.WriteLine(response);
}
catch (PlivoRestException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `Environment.SetEnvironmentVariable Method` to store environment variables and fetch them using `Environment.GetEnvironmentVariable Method` when initializing the client.
## Test
Save the file and run it.
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment.
## Create the outbound call application with custom SIP headers
Create a Java class in the project called `MakeCall` and paste into it this code.
```java theme={null}
package com.plivo.api.samples.call;
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class CallCreate {
public static void main(String [] args) {
Plivo.init("","");
try {
CallCreateResponse response = Call.creator("", Collections.singletonList(""), "https://s3.amazonaws.com/static.plivo.com/answer.xml")
.answerMethod("GET")
.sipHeaders(new HashMap() )
.create();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `System.getenv()` to store and retrieve environment variables when initializing the client.
## Test
Save the file and run it.
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
## Overview
SIP headers (also called SIP fields) are part of every HTTP request made by an outbound call. They can convey message attributes to ensure that information packets travel along the correct path between devices on different networks.
SIP headers are categorized into [four main types](https://docs.switzernet.com/people/emin-gabrielyan/070412-SIP-record-route/index.htm): record-route headers, route headers, via headers, and contact headers. They always have the format
```shell theme={null}
:
```
Plivo SIP headers are always prefixed with `X-PH-`. Only characters \[A-Z], \[a-z], and \[0-9] are allowed as part of either a SIP header name or value to ensure that you can encode them in a URL. You can use multiple header fields by entering them as a comma-separated list:
```shell theme={null}
head1=val1,head2=val2,head3=val3,...,headn=valn
```
You can use custom SIP headers to pass information (such as customer ID or product information) from a front-end application to a back-end application and vice versa.
If you’re using a SIP endpoint and you’ve configured it to send custom SIP headers, Plivo will send the SIP headers with your HTTP request.
You can pass custom SIP headers either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to make an outbound call with custom SIP headers.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You've made your first outbound call!
```
This code instructs Plivo to say, “Congratulations! You’ve made your first outbound call!” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment.
## Create the outbound call application with custom SIP headers
Create a file called `MakeCall.go` and paste into it this code:
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
client, err := plivo.NewClient("","", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Calls.Create(
plivo.CallCreateParams{
From: "",
To: "",
AnswerURL: "https://s3.amazonaws.com/static.plivo.com/answer.xml",
AnswerMethod: "GET",
SipHeader: "customer=johndoe"
},
)
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination\_number may also be a SIP endpoint, in which case the destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note:
We recommend that you store your authentication credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `os.Setenv` and `os.Getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
go run MakeCall.go
```
### Sample response
```json theme={null}
(201, {
u'message': u'call fired',
u'request_uuid': u'85b1d45d-bc12-47f5-89c7-ae4a2c5d5713',
u'api_id': u'ad0e27a8-9008-11e4-b932-22000ac50fac'
}
)
```
The SIP header can be seen as a query parameter in the answer\_url
```json theme={null}
/answer.xml?Direction=outbound&From=1111111111&ALegUUID=5260e820-958c-11e4-b6bf-498d468c930b&BillRate=0.00300&
To=sip%3Aabcd150105094929%40phone.plivo.com&`X-PH-Test=Sample`&CallUUID=5260e820-958c-11e4-b6bf-498d468c930b&ALegRequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&
RequestUUID=2202d0ab-a890-4199-8582-e7a2615cb23b&SIP-H-To=%3Csip%3Aabcd150105094929%40phone.plivo.com%3E%3Btag%3D6U9J4.uVHI7KyEKSgD8vrPnAKQoR2QXc&
CallStatus=in-progress&Event=StartApp
```
# Build an App That Makes Phone Calls from Raspberry Pi
Source: https://plivo.com/docs/voice/use-cases/raspberry-pi
Build a Raspberry Pi app that makes voice calls using Plivo's API
This project was contributed by Andy Fundinger, a professional Python developer and trainer. Andy built this integration as a way to teach his students how to make calls to their mothers on Mother's Day, using Plivo and a keypad attached to a Raspberry Pi.
[Raspberry Pi](https://www.raspberrypi.org/documentation/faqs/) is a single-board computer that comes with
* A Linux-based operating system
* 700 MHz ARM11 CPU
* 256MB (or 512MB) RAM
* SD card storage
* 2 USB ports
* Composite and HDMI video out
* Stereo audio out
* 8 GPIO pins
* Wired Ethernet
## Build a Raspberry Pi call button
#### 1. RasPi Circuit Diagram and inputs flow via GPIO
I hooked up a four-button keypad to four of the Raspberry Pi GPIO pins as inputs, then run a continuous loop to check whether the buttons have been pushed.
Circuit diagram #1
Circuit diagram #2
#### 2. Call flow via Plivo Voice API
Plivo normally expects that you’ll be using it for a web app, so I had to fake that somewhat. Rather than building a full web app, I had each student create a single page that had at least the minimum viable XML to dial a specified number in response to the call being answered. We also played with having a little more in that XML file. But basically we told Plivo that it was a web service and Plivo was OK with that.
```py theme={null}
params = {
'from': "14245550100",
'to': '12015550164',
'answer_url':"https://example.com/static/call_mom/answerThenCallMom.xml",
'answer_method': "GET"
}
p.make_call(params)
```
Then you execute a script that makes an HTTP GET request for “answerThenCallMom.xml", which could be as simple as:
```xml theme={null}
14245550100
```
Get the code for [my Raspberry Pi project on GitHub](https://github.com/Ciemaar/RaspberryPython-CallMom).
Contributed by Andy Fundinger
# Receive Incoming Calls
Source: https://plivo.com/docs/voice/use-cases/receive-incoming-calls
Handle incoming calls on a Plivo number with text-to-speech greetings
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to handle incoming calls
In Visual Studio, create a new project. Use the template for Web Application (Model-View-Controller).
Give the project a name — we used `Receivecall`.
Navigate to the Controllers directory in the Receivecall project. Create a controller named ReceivecallController.cs and paste into it this code.
```cs theme={null}
using System;
using Plivo.XML;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace Receivecall
{
public class ReceivecallController : Controller
{
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddSpeak("Hello, you just received your first call",
new Dictionary() {
{
"loop",
"3"
}
});
var output = resp.ToString();
Console.WriteLine(output);
return this.Content(output, "text/xml");
}
}
}
```
## Create a Plivo application to receive calls
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Ruby application to handle incoming calls
Create a file called `receive_call.rb` and paste into it this code.
```rb theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
def inbound
response = Response.new
speak_body = 'Hello, you just received your first call'
response.addSpeak(speak_body)
xml = Plivo::PlivoXML.new(response)
render xml: xml.to_xml
end
end
```
## Create a Plivo application to receive calls
Associate the Ruby application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask server to handle incoming calls
Create a file called `receive_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, request, make_response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/receive_call/', methods=['GET','POST'])
def speak_xml():
response = (plivoxml.ResponseElement()
.add(plivoxml.SpeakElement('Hello, you just received your first call')))
return(response.to_string())
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
## Create a Plivo application to receive calls
Associate the Flask server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller for incoming calls
Change to the project directory and run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller VoiceController
```
The command generates a controller named VoiceController in the app/http/controllers/ directory. Edit the app/http/controllers/voiceController.php file and paste into it this code.
```php theme={null}
addSpeak($speak_body);
Header('Content-type: text/xml');
echo $response->toXML();
}
}
```
## Create a Plivo application to receive calls
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to handle incoming calls
In Visual Studio, create a new project. Use the template for Web Application (Model-View-Controller).
Give the project a name — we used `Receivecall`.
Navigate to the Controllers directory in the Receivecall project. Create a controller named ReceivecallController.cs and paste into it this code.
```cs theme={null}
using System;
using Plivo.XML;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace Receivecall
{
public class ReceivecallController : Controller
{
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddSpeak("Hello, you just received your first call",
new Dictionary() {
{
"loop",
"3"
}
});
var output = resp.ToString();
Console.WriteLine(output);
return this.Content(output, "text/xml");
}
}
}
```
## Create a Plivo application to receive calls
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application to handle incoming calls
Create a Java class called `ReceiveCall` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.Speak;
import com.plivo.api.xml.Response;
public class ReceiveCall {
public static void main(String[] args) {
post("/receive_call/", (request, response) -> {
response.type("application/xml");
return new Response()
.children(new Speak("Hello, you just received your first call")).toXmlString();
});
}
}
```
## Create a Plivo application to receive calls
Associate the Spark application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”÷÷
## Overview
This guide shows how to receiving incoming calls on a Plivo number and greet callers with a text-to-speech message. Managing incoming calls is a key part of the call flow in many common use cases, such as interactive voice response (IVR), call forwarding, and conference calling.
You can handle incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that handles incoming calls on a Plivo number by playing a text-to-speech message to the caller.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo’s text-to-speech engine plays a message using the [Speak](/docs/voice/xml/audio-output#speak) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go application to handle incoming calls
Create a file called `receive_call.go` and paste into it this code.
```go theme={null}
package main
import (
"fmt"
"net/http"
"github.com/plivo/plivo-go/v7"
)
func handler(w http.ResponseWriter, r *http.Request) {
response := xml.ResponseElement{
Contents: []interface{} {
new(xml.SpeakElement).
AddSpeak("Hello, you just received your first call"),
},
}
fmt.Printf(response.String())
}
func main() {
http.HandleFunc("/receive_call/", handler)
http.ListenAndServe(":8080", nil)
}
```
## Create a Plivo application to receive calls
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application#create-an-application).
Give your application a name — we called ours `Receive_call`. Enter the server URL you want to use (for example `https://.com/receive_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Receive_call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. You should hear the text-to-speech message, “Hello, you just received your first call.”
# Receive DTMF and Speech Input
Source: https://plivo.com/docs/voice/use-cases/receive-input
Capture DTMF keypress and speech input from callers during voice calls
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Detect DTMF input
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Code
Create a file called `detect_dtmf.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
// Welcome message, first branch
var WelcomeMessage = "Welcome to the demo. Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative"
// Message for second branch
var RepresentativeBranch = "Press 1 for sales. Press 2 for support"
// Message that Plivo reads when the caller does nothing
var NoInput = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller presses a wrong digit
var WrongInput = "Sorry, that's not a valid input"
app.all('/multilevelivr/', function (request, response) {
if (request.method == "GET") {
var r = new plivo.Response();
const get_input = r.addGetInput(
{
'action': 'https://.ngrok.io/multilevelivr/firstbranch/',
"method": 'POST',
'inputType': 'dtmf',
'digitEndTimeout': '5',
'language': 'en-US',
'redirect': 'true',
});
get_input.addSpeak(WelcomeMessage);
r.addSpeak(NoInput);
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
}
});
app.all('/multilevelivr/firstbranch/', function (request, response) {
var digits = request.query.Digits;
console.log("Digit pressed", digits)
var r = new plivo.Response();
if (digits == "1") {
var BalMessage = "Your account balance is $20";
r.addSpeak(BalMessage);
}
else if (digits == "2") {
var StatMessage = "Your account status is active"
r.addSpeak(StatMessage);
}
else if (digits == "3") {
const get_input = r.addGetInput(
{
'action': 'https://.ngrok.io/multilevelivr/secondbranch/',
"method": 'POST',
'inputType': 'dtmf',
'digitEndTimeout': '5',
'language': 'en-US',
'redirect': 'false',
'profanityFilter': 'true'
});
get_input.addSpeak(RepresentativeBranch, voice = "Polly.Salli", language = "en-US");
r.addSpeak(NoInput);
console.log(r.toXML());
}
else {
r.addSpeak(WrongInput);
}
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
});
app.all('/multilevelivr/secondbranch/', function (request, response) {
var from_number = request.query.From;
var digits = request.query.Digits;
console.log("Digit pressed", digits)
var r = new plivo.Response();
var params = {
'action': "https://.ngrok.io/multilevelivr/action/",
'method': "POST",
'redirect': "false",
'callerId': from_number
};
var dial = r.addDial(params);
if (digits == "1") {
dial.addNumber("");
console.log(r.toXML());
}
else if (digits == "2") {
dial.addNumber("");
console.log(r.toXML());
}
else {
r.addSpeak(WrongInput);
}
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
$ node detect_dtmf.js
```
You should see your application in action at [http://localhost:3000/multilevelivr/](http://localhost:3000/multilevelivr/).
### Control the gathering of DTMF input
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Code
Create a file called `detect_speech.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
// Welcome message, first branch
var WelcomeMessage = "Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative"
// Message that Plivo reads when the caller does nothing
var NoInput = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller speaks something unrecognized
var WrongInput = "Sorry, that's a not a valid input"
app.all('/ivrspeech/', function (request, response) {
if (request.method == "GET") {
var r = new plivo.Response();
const get_input = r.addGetInput(
{
'action': 'https://.ngrok.io/ivrspeech/firstbranch/',
'method': 'POST',
'interimSpeechResultsCallback': 'https://.ngrok.io/ivrspeech/firstbranch/',
'interimSpeechResultsCallbackMethod': 'POST',
'inputType': 'speech',
'redirect': 'true',
});
get_input.addSpeak(WelcomeMessage);
r.addSpeak(NoInput);
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
}
});
app.all('/ivrspeech/firstbranch/', function (request, response) {
var from_number = request.query.From;
var speech = request.query.Speech;
console.log("Speech Input is:", speech)
var r = new plivo.Response();
var params = {
'action': 'https://.ngrok.io/ivrspeech/action/',
'method': 'POST',
'redirect': 'false',
'callerId': from_number
};
var dial = r.addDial(params);
if (speech == "sales") {
dial.addNumber("");
console.log(r.toXML());
}
else if (speech == "support") {
dial.addNumber("");
console.log(r.toXML());
}
else {
r.addSpeak(WrongInput);
}
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
$ node detect_speech.js
```
And you should see your basic server app in action on [http://localhost:3000/ivrspeech/](http://localhost:3000/ivrspeech/).
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Detect DTMF input
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Create a Sinatra application to detect DTMF input
Create a file called `detect_dtmf.rb` and paste into it this code.
```rb theme={null}
# encoding: utf-8
require 'rubygems'
require 'sinatra'
require 'plivo'
require 'plivo/xml/element'
include Plivo
include Plivo::XML
# Welcome message, first branch
$WelcomeMessage = "Welcome to the demo. Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative"
# Message for second branch
$RepresentativeBranch = "Press 1 for sales. Press 2 for support"
# Message that Plivo reads when the caller does nothing
$NoInput = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller presses a wrong digit
$WrongInput = "Sorry, that's not a valid input"
get '/multilevelivr' do
response = Plivo::XML::Response.new
get_input = response.addGetInput(
action:'https://.ngrok.io/multilevelivr/firstbranch/',
digitEndTimeout: '5',
inputType:'dtmf',
method:'POST',
redirect:'true',
)
get_input.addSpeak($WelcomeMessage, voice: 'Polly.Salli', language: 'en-US')
response.addSpeak($NoInput)
xml = Plivo::XML::PlivoXML.new(response)
puts xml.to_xml()
content_type 'text/xml'
return xml.to_s()
end
post '/multilevelivr/firstbranch/' do
digit = params[:Digits]
puts "digit entered", digit
response = Response.new()
if (digit == "1")
response.addSpeak("Your account balance is $20")
elsif (digit == "2")
response.addSpeak("Your account status is active")
elsif (digit == "3")
response = Plivo::XML::Response.new
get_input = response.addGetInput(
action:'https://.ngrok.io/multilevelivr/secondbranch/',
digitEndTimeout: '5',
inputType:'dtmf',
method:'POST',
redirect:'true',
)
get_input.addSpeak($RepresentativeBranch, voice: 'Polly.Salli', language: 'en-US')
response.addSpeak($NoInput)
else
response.addSpeak($WrongInput)
end
xml = PlivoXML.new(response)
puts xml.to_xml
content_type 'text/xml'
return xml.to_s()
end
post '/multilevelivr/secondbranch/' do
digit = params[:Digits]
from_number = params[:From]
puts "digit entered", digit
response = Response.new()
if (digit == "1")
params = {
'action' => "https://.ngrok.io/multilevelivr/action/",
'method' => "POST",
'redirect' => "false",
'callerId' =>from_number
}
dial = response.addDial(params)
dial.addNumber("")
elsif (digit == "2")
params = {
'action' => "https://.ngrok.io/multilevelivr/action/",
'method' => "POST",
'redirect' => "false",
'callerId' =>from_number
}
dial = response.addDial(params)
dial.addNumber("")
else
response.addSpeak($WrongInput)
end
xml = PlivoXML.new(response)
puts xml.to_xml
content_type 'text/xml'
return xml.to_s()
```
Save the file and run it.
```shell theme={null}
$ ruby detect_dtmf.rb
```
You should see your application in action at [http://localhost:4567/multilevelivr/](http://localhost:4567/multilevelivr/).
### Control the gathering of DTMF input
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Create a Sinatra application to detect speech input
Create a file called `detect_speech.rb` and paste into it this code.
```rb theme={null}
# encoding: utf-8
require 'rubygems'
require 'sinatra'
require 'plivo'
require 'plivo/xml/element'
include Plivo
include Plivo::XML
# Welcome message, first branch
$WelcomeMessage = "Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative"
# Message that Plivo reads when the caller does nothing
$NoInput = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller speaks something unrecognized
$WrongInput = "Sorry, that's not a valid input."
get '/ivrspeech' do
response = Plivo::XML::Response.new
get_input = response.addGetInput(
action:'https://.ngrok.io/i/firstbranch/',
digitEndTimeout: '5',
inputType:'dtmf',
method:'POST',
redirect:'true',
)
get_input.addSpeak($WelcomeMessage, voice: 'Polly.Salli', language: 'en-US')
response.addSpeak($NoInput)
xml = Plivo::XML::PlivoXML.new(response)
puts xml.to_xml()
content_type 'text/xml'
return xml.to_s()
end
post '/ivrspeech/firstbranch/' do
speech = params[:Speech]
from_number = params[:From]
puts "Speech Input is:", speech
response = Response.new()
if (speech == "sales")
params = {
'action' => "https://.ngrok.io/ivrspeech/action/",
'method' => "POST",
'redirect' => "false",
'callerId' =>from_number
}
dial = response.addDial(params)
dial.addNumber("")
elsif (speech == "support")
params = {
'action' => "https://.ngrok.io/i/action/",
'method' => "POST",
'redirect' => "false",
'callerId' =>from_number
}
dial = response.addDial(params)
dial.addNumber("")
else
response.addSpeak($WrongInput)
end
xml = PlivoXML.new(response)
puts xml.to_xml
content_type 'text/xml'
return xml.to_s()
```
Save the file and run it.
```shell theme={null}
$ ruby detect_speech.rb
```
You should see your application in action at [http://localhost:4567/i/](http://localhost:4567/i/).
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Detect DTMF inputs
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Code
Create a file called `detect_dtmf.py` and paste into it this code.
```py theme={null}
#! / usr / bin / python
# -* - coding: utf - 8 -* -
from flask import Flask, Response, request, url_for
from plivo import plivoxml
# Welcome message, first branch
WelcomeMessage = "Welcome to the demo. Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative"
# Message for second branch
RepresentativeBranch = "Press 1 for sales. Press 2 for support"
# Message that Plivo reads when the caller does nothing
NoInput = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller presses a wrong digit
WrongInput = "Sorry, that's not a valid input"
app = Flask(__name__)
@app.route("/multilevelivr/", methods=["GET", "POST"])
def ivr():
element = plivoxml.ResponseElement()
if request.method == "GET":
response = (
element.add(
plivoxml.GetInputElement()
.set_action("https://.ngrok.io/multilevelivr/firstbranch/")
.set_method("POST")
.set_input_type("dtmf")
.set_digit_end_timeout(5)
.set_redirect(True)
.set_language("en-US")
.add_speak(
content=WelcomeMessage, voice="Polly.Salli", language="en-US"
)
)
.add_speak(content=NoInput)
.to_string(False)
)
print(response)
return Response(response, mimetype="text/xml")
@app.route("/multilevelivr/firstbranch/", methods=["GET", "POST"])
def firstbranch():
response = plivoxml.ResponseElement()
digit = request.form.get("Digits")
print("digit pressed: {digit}")
if digit == "1":
text = "Your account balance is $20"
params = {"language": "en-GB"}
response.add(plivoxml.SpeakElement(text, ** params))
elif digit == "2":
text = "Your account status is active"
params = {"language": "en-GB"}
response.add(plivoxml.SpeakElement(text, ** params))
elif digit == "3":
element = plivoxml.ResponseElement()
response = (
element.add(
plivoxml.GetInputElement()
.set_action("https://.ngrok.io/multilevelivr/secondbranch/")
.set_method("POST")
.set_input_type("dtmf")
.set_digit_end_timeout(5)
.set_redirect(True)
.set_language("en-US")
.add_speak(
content=RepresentativeBranch, voice="Polly.Salli", language="en-US"
)
)
.add_speak(content=NoInput)
.to_string(False)
)
print(response)
return Response(response, mimetype="text/xml")
else:
response.add(plivoxml.SpeakElement(WrongInput))
print(response.to_string())
return Response(response.to_string(), mimetype="text/xml")
@app.route("/multilevelivr/secondbranch/", methods=["GET", "POST"])
def secondbranch():
response = plivoxml.ResponseElement()
digit = request.form.get("Digits")
from_number = request.form.get("From")
print("digit pressed: {digit}")
if digit == "1":
response.add(
plivoxml.DialElement(
action="https://.ngrok.io/multilevelivr/action/",
method="POST",
redirect=False,
caller_id=from_number,
).add(plivoxml.NumberElement(""))
)
print(response.to_string())
return Response(str(response), mimetype="text/xml")
elif digit == "2":
response.add(
plivoxml.DialElement(
action="https://.ngrok.io/multilevelivr/action/",
method="POST",
redirect=False,
caller_id=from_number,
).add(plivoxml.NumberElement(""))
)
print(response.to_string())
return Response(str(response), mimetype="text/xml")
else:
response.add(plivoxml.SpeakElement(WrongInput))
print(response.to_string())
return Response(response.to_string(), mimetype="text/xml")
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
Save the file and run it.
```shell theme={null}
$ python detect_dtmf.py
```
You should see your application in action at [http://localhost:5000/multilevelivr/](http://localhost:5000/multilevelivr/).
### Control the gathering of DTMF inputs
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Create a Flask application to detect speech input
Create a file called `detect_speech.py` and paste into it this code.
```py theme={null}
#! / usr / bin / python
# -* - coding: utf - 8 -* -
from flask import Flask, Response, request, url_for
from plivo import plivoxml
# Welcome message, first branch
WelcomeMessage = "Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative"
# Message that Plivo reads when the caller does nothing
NoInput = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller speaks something unrecognized
WrongInput = "Sorry, that's not a valid input"
app = Flask(__name__)
@app.route("/ivrspeech/", methods=["GET", "POST"])
def ivr():
element = plivoxml.ResponseElement()
if request.method == "GET":
response = (
element.add(
plivoxml.GetInputElement()
.set_action("https://.ngrok.io/ivrspeech/firstbranch/")
.set_method("POST")
.set_input_type("dtmf")
.set_digit_end_timeout(5)
.set_redirect(True)
.set_language("en-US")
.add_speak(
content=WelcomeMessage, voice="Polly.Salli", language="en-US"
)
)
.add_speak(content=NoInput)
.to_string(False)
)
print(response)
return Response(response, mimetype="text/xml")
@app.route("/ivrspeech/firstbranch/", methods=["GET", "POST"])
def secondbranch():
response = plivoxml.ResponseElement()
speech = request.form.get("Speech")
from_number = request.form.get("From")
print("Speech Input is: {speech}")
if speech == "1":
response.add(
plivoxml.DialElement(
action="https://.ngrok.io/ivrspeech/action/",
method="POST",
redirect=False,
caller_id=from_number,
).add(plivoxml.NumberElement(""))
)
print(response.to_string())
return Response(str(response), mimetype="text/xml")
elif speech == "2":
response.add(
plivoxml.DialElement(
action="https://.ngrok.io/ivrspeech/action/",
method="POST",
redirect=False,
caller_id=from_number,
).add(plivoxml.NumberElement(""))
)
print(response.to_string())
return Response(str(response), mimetype="text/xml")
else:
response.add(plivoxml.SpeakElement(WrongInput))
print(response.to_string())
return Response(response.to_string(), mimetype="text/xml")
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
Save the file and run it.
```shell theme={null}
$ python detect_speech.py
```
You should see your application in action at [http://localhost:5000/ivrspeech/](http://localhost:5000/ivrspeech/).
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Detect DTMF input
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Create a Laravel controller to detect DTMF input
Change to the project directory and run
```shell theme={null}
$ php artisan make:controller MultilevelivrController
```
Edit app/http/controllers/MultilevelivrController.php and paste into it this code.
```
addGetInput(
[
'action' => "https://.ngrok.io/firstBranch/",
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($welcome_message, ['language'=>"en-US", 'voice'=>"Polly.Salli"]);
$response->addSpeak($no_input);
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
// Action URL block for DTMF
public function firstBranch(Request $request)
{
$representative_branch = "Press 1 for sales. Press 2 for support"; // Message for second branch
$no_input = "Sorry, I didn't catch that. Please hang up and try again"; // Message that Plivo reads when the caller does nothing
$digit = $request->query('Digits');
$response = new Response();
if ($digit=="1") {
$bal_message = "Your account balance is $20";
$response->addSpeak($bal_message);
} elseif($digit=="2") {
$stat_message = "Your account status is active";
$response->addSpeak($stat_message);
} elseif($digit=="3") {
$get_input = $response->addGetInput(
[
'action' => "https://.ngrok.io/secondBranch/",
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($representative_branch, ['language'=>"en-US", 'voice'=>"Polly.Salli"]);
} else {
$response->addSpeak($no_input);
}
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
// Action URL block for sales and support branch
public function secondBranch(Request $request)
{
$wrong_input = "Sorry, that's not a valid input"; // Message that Plivo reads when the caller inputs a wrong digit
$digit = $request->query('Digits');
$from_number = $request->query('From');
$response = new Response();
$params = array(
'callerId' => $from_number
);
if ($digit=="1") {
$dial = $response->addDial($params);
$number = "";
$dial->addNumber($number);
} elseif($digit=="2") {
$dial = $response->addDial($params);
$number = "";
$dial->addNumber($number);
} else {
$response->addSpeak($wrong_input);
}
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
}
```
### Add a route
Add a route for all the functions in the MultilevelivrController class. Edit routes/web.php and add these lines at the end of the file.
```shell theme={null}
Route::match(['get', 'post'], '/detectdtmf', 'MultilevelivrController@detectDtmf');
Route::match(['get', 'post'], '/firstbranch', 'MultilevelivrController@firstBranch');
Route::match(['get', 'post'], '/secondbranch', 'MultilevelivrController@secondBranch');
```
### Control the gathering of DTMF input
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Create a Laravel controller to detect speech input
Change to the project directory and run
```shell theme={null}
$ php artisan make:controller SpeechdetectionController
```
Edit app/http/controllers/SpeechdetectionController.php and paste into it this code.
```php theme={null}
addGetInput(
[
'action' => "https://.ngrok.io/repBranch/",
'method' => "POST",
'interimSpeechResultsCallback' => 'https://.ngrok.io/repBranch/',
'interimSpeechResultsCallbackMethod' => 'POST',
'inputType' => "speech",
'redirect' => "true",
]);
$get_input->addSpeak($welcome_message, ['language'=>"en-US", 'voice'=>"Polly.Salli"]);
$response->addSpeak($no_input);
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
// Action URL block for sales and support branch
public function repBranch(Request $request)
{
$wrong_input = "Sorry, that's not a valid input"; // Message that Plivo reads when the caller speaks something unrecognized
$speech = $request->query('Speech');
$from_number = $request->query('From');
$response = new Response();
$params = array(
'callerId' => $from_number
);
if ($speech=="sales") {
$dial = $response->addDial($params);
$number = "";
$dial->addNumber($number);
} elseif($speech=="support") {
$dial = $response->addDial($params);
$number = "";
$dial->addNumber($number);
} else {
$response->addSpeak($wrong_input);
}
$xml_response = $response->toXML();
return response($xml_response, 200)->header('Content-Type', 'application/xml');
}
}
```
### Add a route
Add a route for all the functions in the SpeechdetectionController class. Edit routes/web.php and add these lines at the end of the file.
```shell theme={null}
Route::match(['get', 'post'], '/detectspeech', 'SpeechdetectionController@detectSpeech');
Route::match(['get', 'post'], '/repbranch', 'SpeechdetectionController@repBranch');
```
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Detect DTMF input
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Create an MVC controller to detect DTMF input
In Visual Studio, create a controller named `MultilevelIvrController.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
namespace Receivecall.Controllers {
public class MultilevelIvrController: Controller {
// Welcome message, first branch
String WelcomeMessage = "Welcome to the demo. Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative";
// Message for second branch
String RepresentativeBranch = "Press 1 for sales. Press 2 for support";
// Message that Plivo reads when the caller does nothing
String NoInput = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller presses a wrong digit
String WrongInput = "Sorry, that's not a valid input";
// GET: //
public IActionResult Index() {
var resp = new Response();
GetInput get_input = new GetInput("", new Dictionary < string, string > () {
{
"action",
"https://.ngrok.io/multilevelivr/firstbranch/"
},
{
"method",
"POST"
},
{
"digitEndTimeout",
"5"
},
{
"inputType",
"dtmf"
},
{
"redirect",
"true"
},
});
resp.Add(get_input);
get_input.AddSpeak(WelcomeMessage, new Dictionary < string, string > () {});
resp.AddSpeak(NoInput, new Dictionary < string, string > () {});
var output = resp.ToString();
return this.Content(output, "text/xml");
}
public IActionResult FirstBranch() {
String digit = Request.Form["Digits"];
Debug.WriteLine("Digit pressed : {0}" + digit);
var resp = new Response();
if (digit == "1") {
// Add Speak XML element
resp.AddSpeak("Your account balance is $20", new Dictionary < string, string > () {});
}
else if (digit == "2") {
// Add Speak XML element
resp.AddSpeak("Your account status is active", new Dictionary < string, string > () {});
}
else if (digit == "3") {
String getinput_action_url = "https://.ngrok.io/multilevelivr/secondbranch/";
// Add GetInput XML element
GetInput get_input = new GetInput("", new Dictionary < string, string > () {
{
"action",
getinput_action_url
},
{
"method",
"POST"
},
{
"digitEndTimeout",
"5"
},
{
"inputType",
"dtmf"
},
{
"redirect",
"true"
},
});
resp.Add(get_input);
get_input.AddSpeak(RepresentativeBranch, new Dictionary < string, string > () {});
resp.AddSpeak(NoInput, new Dictionary < string, string > () {});
}
else {
// Add Speak XML element
resp.AddSpeak(WrongInput, new Dictionary < string, string > () {});
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// Second branch of IVR phone tree
public IActionResult SecondBranch() {
String FromNumber = Request.Form["From"];
var resp = new Response();
String digit = Request.Form["Digits"];
Debug.WriteLine("Digit pressed : {0}" + digit);
// Add Speak XMLTag
if (digit == "1") {
Dial dial = new Dial(new
Dictionary < string, string > () {
{
"callerId",
FromNumber
},
{
"action",
"https://.ngrok.io/multilevelivr/action/"
},
{
"method",
"POST"
},
{
"redirect",
"false"
}
});
dial.AddNumber("", new Dictionary < string, string > () {});
resp.Add(dial);
}
else if (digit == "2") {
Dial dial = new Dial(new
Dictionary < string, string > () {
{
"callerId",
FromNumber
},
{
"action",
"https://.ngrok.io/multilevelivr/action/"
},
{
"method",
"POST"
},
{
"redirect",
"false"
}
});
dial.AddNumber("", new Dictionary < string, string > () {});
resp.Add(dial);
}
else {
resp.AddSpeak(WrongInput, new Dictionary < string, string > () {});
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Run the project and you should see your application in action at [http://localhost:5000/multilevelivr/](http://localhost:5000/multilevelivr/).
### Control the gathering of DTMF input
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Create an MVC controller to detect speech input
In Visual Studio, create a controller named `IvrspeechController.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
namespace Receivecall.Controllers {
public class IvrspeechController: Controller {
// Welcome message, first branch
String WelcomeMessage = "Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative";
// Message that Plivo reads when the caller does nothing
String NoInput = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller speaks something unrecognized
String WrongInput = "Sorry, that's not a valid input";
public IActionResult Index() {
var resp = new Response();
GetInput get_input = new GetInput("", new Dictionary < string, string > () {
{
"action",
"https://.ngrok.io/ivrspeech/firstbranch/"
},
{
"method",
"POST"
},
{
"interimSpeechResultsCallback",
"https://.ngrok.io/ivrspeech/firstbranch/"
},
{
"interimSpeechResultsCallbackMethod",
"POST"
},
{
"inputType",
"speech"
},
{
"redirect",
"true"
},
});
resp.Add(get_input);
get_input.AddSpeak(WelcomeMessage, new Dictionary < string, string > () {});
resp.AddSpeak(NoInput, new Dictionary < string, string > () {});
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// IVR phone tree
public IActionResult FirstBranch() {
String speech = Request.Form["Speech"];
String FromNumber = Request.Form["From"];
Debug.WriteLine("Speech Input is :" + speech);
Dial dial = new Dial(new
Dictionary < string, string > () {
{
"callerId",
FromNumber
}
});
var resp = new Response();
if (speech == "sales") {
dial.AddNumber("", new Dictionary < string, string > () {});
resp.Add(dial);
}
else if (speech == "support") {
dial.AddNumber("", new Dictionary < string, string > () {});
resp.Add(dial);
}
else {
// Add Speak XML element
resp.AddSpeak(WrongInput, new Dictionary < string, string > () {});
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Save the controller and run it and you should see your application in action at [http://localhost:5000/ivrspeech/](http://localhost:5000/ivrspeech/).
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
You must set up and install Java(Java 1.8 or higher) and Plivo’s Java SDK to handle incoming calls and callbacks. Here’s how.
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Create a Spring application to detect DTMF input
Edit the PlivoVoiceApplication.java file in the src/main/java/com.example.demo/ folder and paste into it this code.
Note: Here, the demo application name is PlivoVoiceApplication.java because the friendly name we provided in the Spring Initializr was “Plivo Voice.”
```java theme={null}
package com.example.Plivo;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.*;
import com.plivo.api.xml.Number;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class PlivoVoiceApplication {
public static void main(String[] args) {
SpringApplication.run(PlivoVoiceApplication.class, args);
}
// Welcome message, first branch
String WelcomeMessage = "Welcome to the demo. Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative";
// Message for second branch
String RepresentativeBranch = "Press 1 for sales. Press 2 for support";
// Message that Plivo reads when the caller does nothing
String NoInput = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller presses a wrong digit
String WrongInput = "Sorry, that's not a valid input";
@GetMapping(value = "/multilevelivr/", produces = { "application/xml" })
public Response getInput() throws PlivoXmlException {
Response response = new Response().children(
new GetInput().action("https://.ngrok.io/multilevelivr/firstbranch/").method("POST")
.inputType("dtmf").digitEndTimeout(5).redirect(true).children(new Speak(WelcomeMessage)))
.children(new Speak(NoInput));
System.out.println(response.toXmlString());
return response;
}
@RequestMapping(value = "/multilevelivr/firstbranch/", method = RequestMethod.POST, produces = {
"application/xml" })
public Response speak(@RequestParam("Digits") String digit) throws PlivoXmlException {
System.out.println("Digit pressed:" + digit);
Response response = new Response();
if (digit.equals("1")) {
response.children(new Speak("Your account balance is $20"));
} else if (digit.equals("2")) {
response.children(new Speak("Your account status is active"));
} else if (digit.equals("3")) {
response.children(new GetInput().action("https://.ngrok.io/multilevelivr/secondbranch/")
.method("POST").inputType("dtmf").digitEndTimeout(5).redirect(true)
.children(new Speak(RepresentativeBranch))).children(new Speak(NoInput));
} else {
response.children(new Speak(WrongInput));
}
System.out.println(response.toXmlString());
return response;
}
@RequestMapping(value = "/multilevelivr/second/", produces = { "application/xml" }, method = RequestMethod.POST)
public Response callforward(@RequestParam("Digits") String digit, @RequestParam("From") String from_number)
throws PlivoXmlException {
System.out.println("Digit pressed:" + digit);
Response response = new Response();
if (digit.equals("1")) {
response.children(new Dial().action("https://.ngrok.io/multilevelivr/action/").method("POST")
.redirect(false).children(new Number("")));
} else if (digit.equals("2")) {
response.children(new Dial().action("https://.ngrok.io/multilevelivr/action/").method("POST")
.redirect(false).children(new Number("")));
} else {
response.children(new Speak(WrongInput));
}
System.out.println(response.toXmlString());
return response;
}
}
```
### Control the gathering of DTMF inputs
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Code
Edit the PlivoVoiceApplication.java file in the src/main/java/com.example.demo/ folder and paste into it this code.
Note: Again, the demo application name is PlivoVoiceApplication.java because the friendly name we provided in the Spring Initializr was “Plivo Voice.”
```java theme={null}
package com.example.Plivo;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.*;
import com.plivo.api.xml.Number;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class PlivoVoiceApplication {
public static void main(final String[] args) {
SpringApplication.run(PlivoVoiceApplication.class, args);
}
// Welcome message, first branch
String welcomeMessage = "Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative";
// Message that Plivo reads when the caller does nothing
String noInput = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller speaks something unrecognized
String wrongInput = "Sorry, that's not a valid input";
@GetMapping(value = "/ivrspeech/", produces = { "application/xml" })
public Response getInput() throws PlivoXmlException {
final Response response = new Response().children(
new GetInput().action("https://.ngrok.io/ivrspeech/firstbranch/").method("POST")
.interimSpeechResultsCallback("https://.ngrok.io/ivrspeech/firstbranch/")
.interimSpeechResultsCallbackMethod("POST").inputType("speech").redirect(true)
.children(new Speak(welcomeMessage)))
.children(new Speak(noInput));
System.out.println(response.toXmlString());
return response;
}
@RequestMapping(value = "/ivrspeech/firstbranch/", produces = {
"application/xml" }, method = RequestMethod.POST)
public Response callforward(@RequestParam("Speech") final String speech,
@RequestParam("From") final String fromNumber) throws PlivoXmlException {
System.out.println("Speech Input is:" + speech);
final Response response = new Response();
if (speech.equals("sales")) {
response.children(
new Dial().callerId(fromNumber).action("https://.ngrok.io/ivrspeech/action/")
.method("POST").redirect(false).children(new Number("")));
} else if (speech.equals("support")) {
response.children(
new Dial().callerId(fromNumber).action("https://.ngrok.io/ivrspeech/action/")
.method("POST").redirect(false).children(new Number("")));
} else {
response.children(new Speak(wrongInput));
}
System.out.println(response.toXmlString());
return response;
}
}
```
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
## Overview
You can use speech input or dual-tone multi-frequency (DTMF) tones (a.k.a. Touch-Tone) to route callers or otherwise change call flows for applications such as interactive voice response (IVR), virtual assistants, and mobile surveys.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Detect DTMF input
### How it works
This example shows a multilevel IVR phone application that uses digit press input captured using the [GetInput XML](/docs/voice/xml/input#getinput) element. A virtual assistant answers incoming calls and offers the caller three choices: “Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative.” If the caller enters 1 or 2, the application will retrieve the requested information and play the caller a text-to-speech message. If the caller presses 3, the application will redirect the caller to the second branch, which offers two new choices: “Press 1 for sales. Press 2 for support.” The application then connects the caller with the requested department.
### Code
Create a file called `detect_dtmf.go` and paste into it this code.
```go theme={null}
package main
import (
"net/http"
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
m: = martini.Classic()
// Welcome message, first branch
WelcomeMessage: = "Welcome to the demo. Press 1 for your account balance. Press 2 for your account status. Press 3 to speak to a representative"
// Message for second branch
RepresentativeBranch: = "Press 1 for sales. Press 2 for support"
// Message that Plivo reads when the caller does nothing
NoInput: = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller presses a wrong digit
WrongInput: = "Sorry, that's not a valid input"
m.Any("/multilevelivr/", func(w http.ResponseWriter, r * http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response: = xml.ResponseElement {
Contents: [] interface {} {
new(xml.GetInputElement).
SetAction("https://.ngrok.io/multilevelivr/firstbranch/").
SetMethod("POST").
SetInputType("dtmf").
SetDigitEndTimeout(5).
SetRedirect(true).
SetContents([] interface {} {
new(xml.SpeakElement).
AddSpeak(WelcomeMessage).
SetVoice("WOMAN").
SetLanguage("en-US").
SetLoop(1)
}),
new(xml.SpeakElement).
AddSpeak(NoInput),
},
}
return response.String()
})
m.Any("/multilevelivr/firstbranch/", func(w http.ResponseWriter, r * http.Request) string {
w.Header().Set("Content-Type", "application/xml")
digit: = r.FormValue("Digits")
// result := "Digit Input is:" + digit + " "
if digit == "1" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak("Your account balance is $20"),
},
}.String()
} else if digit == "2" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak("Your account status is active"),
},
}.String()
} else if digit == "3" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.GetInputElement).
SetAction("https://.ngrok.io/multilevelivr/secondbranch/").
SetMethod("POST").
SetInputType("dtmf").
SetDigitEndTimeout(5).
SetRedirect(true).
SetContents([] interface {} {
new(xml.SpeakElement).
AddSpeak(RepresentativeBranch).
SetVoice("WOMAN").
SetLanguage("en-US").
SetLoop(1)
}),
new(xml.SpeakElement).
AddSpeak(NoInput),
},
}.String()
} else {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak(WrongInput),
},
}.String()
}
})
m.Any("/multilevelivr/secondbranch/", func(w http.ResponseWriter, r * http.Request) string {
w.Header().Set("Content-Type", "application/xml")
digit: = r.FormValue("Digits")
fromnumber: = r.FormValue("From")
// result := "Digit Input is:" + digit + " "
if digit == "1" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.DialElement).
SetCallerID(fromnumber).
SetContents([] interface {} {
new(xml.NumberElement).
SetContents(""),
}, ),
},
}.String()
} else if digit == "2" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.DialElement).
SetCallerID(fromnumber).
SetContents([] interface {} {
new(xml.NumberElement).
SetContents(""),
}, ),
},
}.String()
} else {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak(WrongInput),
},
}.String()
}
})
m.Run()
}
```
Save the file and run it.
```shell theme={null}
$ go run detect_dtmf.go
```
You should see your application in action at [http://localhost:8080/multilevelivr/](http://localhost:8080/multilevelivr/).
### Control the gathering of DTMF input
You can improve DTMF collection by using attributes available for the GetInput XML element, such as digitEndTimeout, numDigit, finishOnKey, and executionTimeout.
**digitEndTimeout** sets the maximum time interval between successive digit inputs. The default value is `auto` and other allowed values are 2 to 10 seconds. If the user provides no new digits within the digitEndTimeout period, the digits entered to that point will be processed.
**numDigits** sets the maximum number of digits the user can provide on the current call. The default value is 32 and the allowed values are 1 to 32.
If the user provides more digits than the value of numDigits, Plivo will send only the number of digits specified as numDigits to the action URL; additional digit inputs will be ignored. For example, if numDigits is specified as “4” and the user enters five digits, the last digit will be ignored.
**finishOnKey** defines a key that users can press to submit the digits they entered. The default value is # and additional allowed values are 0-9, \*, \, and ”none.” When you set the value to \ or “none,” DTMF input collection ends depending on the digitEndTimeout or the numDigits attribute.
Note: These three attributes apply to input types `dtmf` and `dtmf speech` and do not apply to input type `speech`. If all three of these attributes are specified, the priority is for finishOnKey.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
## Detect speech input
The GetInput XML element can also capture speech input.
### How it works
This example shows how to implement a simple IVR phone tree. A virtual assistant answers the call and offers the caller two choices: “Say sales to talk to a sales representative. Say support to talk to a support representative.”
If the caller says “sales,” the caller will be connected to a sales representative; if the caller says “support,” they will be connected to a support representative.
### Code
Create a file called `detect_speech.go` and paste into it this code.
```go theme={null}
package main
import (
"net/http"
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
m: = martini.Classic()
// Welcome message, first branch
WelcomeMessage: = "Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative"
// Message that Plivo reads when the caller does nothing
NoInput: = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller speaks something unrecognized
WrongInput: = "Sorry, that's not a valid input"
m.Any("/multilevelivr/", func(w http.ResponseWriter, r * http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response: = xml.ResponseElement {
Contents: [] interface {} {
new(xml.GetInputElement).
SetAction("https://.ngrok.io/ivrspeech/firstbranch/").
SetMethod("POST").
SetInputType("speech").
SetInterimSpeechResultsCallback("https://.ngrok.io/ivrspeech/firstbranch/").
SetInterimSpeechResultsCallbackMethod("POST").
SetRedirect(true).
SetContents([] interface {} {
new(xml.SpeakElement).
AddSpeak(WelcomeMessage).
SetVoice("WOMAN").
SetLanguage("en-US").
SetLoop(1)
}),
new(xml.SpeakElement).
AddSpeak(NoInput),
},
}
return response.String()
})
m.Any("/multilevelivr/firstbranch/", func(w http.ResponseWriter, r * http.Request) string {
w.Header().Set("Content-Type", "application/xml")
speech: = r.FormValue("Speech")
fromnumber: = r.FormValue("From")
// result := "Digit Input is:" + digit + " "
if speech == "sales" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.DialElement).
SetCallerID(fromnumber).
SetContents([] interface {} {
new(xml.NumberElement).
SetContents(""),
}, ),
},
}.String()
} else if speech == "support" {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.DialElement).
SetCallerID(fromnumber).
SetContents([] interface {} {
new(xml.NumberElement).
SetContents(""),
}, ),
},
}.String()
} else {
return xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak(WrongInput),
},
}.String()
}
})
m.Run()
}
```
Save the file and run it.
```shell theme={null}
$ go run detect_speech.go
```
You should see your application in action at [http://localhost:8080/ivrspeech/](http://localhost:8080/ivrspeech/).
## Speech recognition attributes
### Speech models
Different applications may benefit from different automatic speech recognition (ASR) models, which you can specify using the the GetInput XML element‘s speechModel attribute. By default, it has a value of `default`, which is suitable for long-form audio, such as dictation, but you can also try `command_and_search` for shorter audio clips, such as when you expect callers to use voice commands or voice search, or `phone_call`, if you want to transcribe audio from a phone call. Explore the models and see which works best for your use case.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Hints
You can use the hints attribute to potentially improve speech transcription results by defining words and phrases that are common in your use case. For example, a call center where callers use voice commands to connect to various departments can use the names of the departments as hints.
* Allowed values: a non-empty string of comma-separated phrases
* Limitations are:
* Phrases per request: 500
* Characters per phrase: 100
* Characters per request: 10,000
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Controlling the gathering of speech input
You can improve the functionality of speech input collection by using GetInput XML attributes such as speechEndTimeout, language, profanityFilter, and executionTimeout.
**speechEndTimeout** sets the time that Plivo waits for more speech input after silence is detected. The default value is `auto`; other allowed values are 2 to 10 seconds. If the user doesn‘t provide new speech input within the speechEndTimeout period, the speech collected to that point will be processed.
**language** specifies the language and national/regional dialect of the audio to be recognized on calls. The default language for speech detection is en-US. You can choose your preferred language from the [list of supported languages](/docs/voice/xml/input#supported-languages).
**profanityFilter:** If a user speaks any profane words, Plivo can filter them out during transcription if you set this attribute to `true`. The profanity filter applies only to single words — it doesn‘t work for a combination of words. The default value is `false`.
Note: These three attributes apply to input types `speech` and `dtmf speech` and do not apply to input type `dtmf`.
**executionTimeout** sets the maximum time during which Plivo detects input. You can use this timeout to tell the application to process the next element in the XML response when a user doesn‘t provide input during the call. The default value is 15 seconds, and allowed values are 5 to 60 seconds.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Real-time speech recognition
You can use the interimSpeechResultsCallback attribute to perform real-time speech recognition. If you specify a URL for your application server to this attribute, you can receive real-time callbacks of the user’s recognized speech while the user is still speaking on the call. Plivo sends the transcribed result to your server URL with attributes such as UnstableSpeech, Stability, StableSpeech, and SequenceNumber.
* **UnstableSpeech** holds the interim transcribed result of the user’s speech, which may be refined when more speech is collected from the user.
* **Stability** is an estimate of the likelihood that the recognizer will not change its guess about the interim UnstableSpeech result. Values range from 0.0 (completely unstable) to 1.0 (completely stable).
* **StableSpeech** holds the stable transcribed result of the user’s speech.
* **SequenceNumber** holds the sequence number of the interim speech callback, which helps you order incoming callback requests.
*Example XML:*
```xml theme={null}
Welcome to the demo. Say sales to talk to a sales representative. Say support to talk to a support representative
Sorry, I didn't catch that. Please hang up and try again later.
```
### Data logging preferences
You can use the GetInput XML element’s log attribute to manage input logging preferences. It defaults to `true`, but if you define it to `false`, logging will be disabled and Plivo will not log digit and speech input.
# Record Calls
Source: https://plivo.com/docs/voice/use-cases/record-a-call
Record voice calls and store recordings using the Plivo Voice API
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a Node.js development environment](/docs/sdk/server/set-up-node-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
Create a file called `record_call.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'action': "https://.com/get_recording/",
'startOnDialAnswer': "true",
'redirect': "false"
};
response.addRecord(params);
var dial = response.addDial();
var number = "";
dial.addNumber(number);
console.log(response.toXML());
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
Create a file called `record_call.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var response = plivo.Response();
var params = {
'record': "true",
'callbackUrl': ".com/confevents/",
'callbackMethod': "POST",
'waitSound': ".com/waitmusic/"
};
var conference_name = "";
response.addConference(conference_name, params);
console.log(response.toXML());
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Create a file called `record_call.js` and paste into it this code.
```js theme={null}
var util = require('util');
var express = require('express');
var app = express();
var plivo = require('plivo');
app.set('port', (process.env.PORT || 5000));
app.all('/record/', function (req, res) {
var r = plivo.Response();
var getinput_action_url, params, getDigits;
getinput_action_url = req.protocol + '://' + req.headers.host + '/record/action/';
params = {
'action': getinput_action_url,
'method': 'POST',
'inputType': 'dtmf',
'digitEndTimeout': '5',
'redirect': 'true',
};
get_input = r.addGetInput(params);
get_input.addSpeak("Press 1 to record this call");
console.log(r.toXML());
res.set({ 'Content-Type': 'text/xml' });
res.send(r.toXML());
});
app.all('/record/action/', function (req, res) {
var digit = req.param('Digits');
var call_uuid = req.param('CallUUID');
console.log("call_uuid is:",call_uuid + "and digit is:",digit)
var client = new plivo.Client("", "");
if (digit === "1") {
var response = client.calls.record(
call_uuid,
)
console.log(response);
} else
console.log("Wrong Input");
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
Create a file called `record_call.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.conferences.record(
"",
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a Ruby development environment](/docs/sdk/server/set-up-ruby-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
Create a file called `record_call.rb` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
action: 'https://.com/get_recording/',
startOnDialAnswer: 'true',
redirect: 'false'
}
response.addRecord(params)
dial = response.addDial()
number = ''
dial.addNumber(number)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
Create a file called `record_call.rb` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo::XML
include Plivo::Exceptions
begin
response = Response.new
params = {
'record' => "true",
'callbackUrl' => "https://.com/confevents/",
'callbackMethod' => "POST",
'waitSound' => "https:/.com/waitmusic/"
}
conference_name = ""
response.addConference(conference_name, params)
xml = PlivoXML.new(response)
puts xml.to_xml
rescue PlivoXMLError => e
puts 'Exception: ' + e.message
end
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Create a file called `record_call.go` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'sinatra'
require 'plivo'
include Plivo
include Plivo::XML
get '/record_api/' do
r = Response.new()
getinput_action_url = "https://.com/record_action/"
params = {
action: getinput_action_url,
method: 'POST',
digitEndTimeout: '5',
inputType:'dtmf',
redirect:'true'
}
getinput = r.addGetInput(params)
getinput.addSpeak("Press 1 to record this call")
xml = PlivoXML.new(r)
content_type "application/xml"
return xml.to_s()
end
get '/record_api_action/' do
digit = params[:Digits]
call_uuid = params[:CallUUID]
puts "call_uuid is %s and digit is %s" % [call_uuid,digit]
api = RestClient.new("","")
if (digit == "1")
response = api.calls.record(call_uuid)
print response
else
print "Invalid input"
end
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
Create a file called `record_call.go` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.conferences.record(
''
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a Python development environment](/docs/sdk/server/set-up-python-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
Create a file called `record_call.py` and paste into it this code.
```py theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(
plivoxml.RecordElement(
action='https://.com/get_recording/',
start_on_dial_answer=True,
redirect=False))
response.add(plivoxml.DialElement().add(plivoxml.NumberElement('')))
print(response.to_string())
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
Create a file called `record_call.py` and paste into it this code.
```py theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(
plivoxml.ConferenceElement(
'',
record=True,
callback_url='https://.com/confevents/',
callback_method='POST',
wait_sound='https://.com/waitmusic/'))
print(response.to_string())
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Create a file called `record_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, Response, request, url_for
from plivo import plivoxml
import plivo
app = Flask(__name__)
@app.route('/record_api/', methods=['POST', 'GET'])
def record_api():
response = plivoxml.ResponseElement()
response.add(plivoxml.GetInputElement().
set_action(url_for('record_action', _external=True)).
set_method('POST').
set_input_type('dtmf').
set_digit_end_timeout(5).
set_redirect(True).add(
plivoxml.SpeakElement('Press 1 to record this call')))
return Response(response.to_string(), mimetype='application/xml')
@app.route('/record_api_action/', methods=['POST', 'GET'])
def record_action():
digit = request.args.get('Digits')
call_uuid = request.args.get('CallUUID')
print("call_uuid is {}, and digit pressed {}".format(call_uuid,digit))
client = plivo.RestClient("", "")
if digit == "1":
response = client.calls.record(
call_uuid=call_uuid, )
else:
print "Invalid input"
response = "Error"
return Response(response.to_string(), mimetype='text/plain')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug='True')
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
Create a file called `record_call.py` and paste into it this code.
**Code**
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.conferences.record(
conference_name='', )
print(response)
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a PHP development environment](/docs/sdk/server/set-up-php-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
Create a file called `record_call.php` and paste into it this code.
```php theme={null}
"https://.com/get_recording/",
'startOnDialAnswer' => "true",
'redirect' => "false"
);
$response->addRecord($params);
$dial = $response->addDial();
$number = "";
$dial->addNumber($number);
Header('Content-type: text/xml');
echo ($response->toXML());
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
Create a file called `record_call.php` and paste into it this code.
```php theme={null}
","");
try
{
$response = $client
->conferences
->startRecording('');
print_r($response);
}
catch(PlivoRestException $ex)
{
print_r($ex);
}
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Change to the project directory and run this command to create a Laravel controller.
```shell theme={null}
$ php artisan make:controller RecordcallController
```
Edit the `RecordcallController.php` file and paste into it this code:
```php theme={null}
.com/recordAction/";
$get_input = $r->addGetInput(['action' => $getinput_action_url, 'method' => "POST", 'digitEndTimeout' => "5", 'inputType' => "dtmf", 'redirect' => "true", ]);
$get_input->addSpeak("Press 1 to record this call");
Header('Content-type: text/xml');
echo $response->toXML();
}
public function recordAction(Request $request)
{
$digit = $request->query('Digits');
$uuid = $request->query('CallUUID');
print_r("digits is: {$digit} and call_uuid is: {$uuid}");
$response = new Response();
$client = new RestClient("","");
if ($digit == "1")
{
$response = $client
->calls
->startRecording($uuid);
print_r($response);
}
else
{
print ("Invalid input");
}
}
}
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
```php theme={null}
"true",
'callbackUrl' => "https://.com/confevents/",
'callbackMethod' => "POST",
'waitSound' => "https://.com/waitmusic/"
);
$conference_name = "";
$response->addConference($conference_name, $params);
Header('Content-type: text/xml');
echo ($response->toXML());
?>
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a .NET development environment](/docs/sdk/server/set-up-dotnet-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
Create an MVC controller and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo {
class MainClass {
public static void Main(string[] args) {
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddRecord(new Dictionary < string, string > () {
{
"action",
"Https://.com/get_recording/"
},
{
"startOnDialAnswer",
"true"
},
{
"redirect",
"false"
}
});
Plivo.XML.Dial dial = new Plivo.XML.Dial(new
Dictionary < string, string > () {});
dial.AddNumber("", new Dictionary < string, string > () {});
resp.Add(dial);
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
Create an MVC controller and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
namespace Plivo {
class MainClass {
public static void Main(string[] args) {
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddConference("", new Dictionary < string, string > () {
{
"record",
"true"
},
{
"recordFileFormat",
"mp3"
},
{
"callbackUrl",
"https://.com/confevents/"
},
{
"callbackMethod",
"POST"
},
{
"waitSound",
"https://.com/waitmusic/"
}
});
var output = resp.ToString();
Console.WriteLine(output);
}
}
}
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Create an MVC controller and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Plivo;
using Plivo.XML;
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace Recordcall.Controllers {
public class RecordController: Controller {
// GET: //
public IActionResult Index() {
var resp = new Response();
Plivo.XML.GetInput get_input = new
Plivo.XML.GetInput("", new Dictionary < string, string > () {
{
"action",
"https://.com/record/action/"
},
{
"method",
"POST"
},
{
"digitEndTimeout",
"5"
},
{
"finishOnKey",
"#"
},
{
"inputType",
"dtmf"
},
{
"redirect",
"false"
},
});
resp.Add(get_input);
get_input.AddSpeak("Press 1 to record this call", new Dictionary < string, string > () {});
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// Action URL
public String Action() {
String digits = Request.Query["Digits"];
String uuid = Request.Query["CallUUID"];
Debug.WriteLine("Digit pressed : {0}, Call UUID : {1}", digits, uuid);
if (digits == "1") {
string auth_id = "";
string auth_token = "";
var api = new PlivoApi(auth_id, auth_token);
var resp = api.Call.StartRecording(
callUuid: uuid);
Debug.WriteLine(resp);
}
else {
Debug.WriteLine("Invalid input");
}
return "OK";
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home).
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using Plivo.Exception;
namespace PlivoExamples {
internal class Program {
public static void Main(string[] args) {
var api = new PlivoApi("","");
try {
var response = api.Conference.StartRecording("");
Console.WriteLine(response);
}
catch(PlivoRestException e) {
Console.WriteLine("Exception: " + e.Message);
}
}
}
}
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a Java development environment](/docs/sdk/server/set-up-java-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
```java theme={null}
package com.plivo.api.xml.samples.record;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Dial;
import com.plivo.api.xml.Number;
import com.plivo.api.xml.Record;
import com.plivo.api.xml.Response;
class RecordACompleteCallSession {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Record("https://.com/get_recording/")
.redirect(false)
.startOnDialAnswer(true),
new Dial()
.children(
new Number("")
)
);
System.out.println(response.toXmlString());
}
}
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
```java theme={null}
// Example for conference
package com.plivo.api.xml.samples.conference;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.xml.Conference;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
class RecordConference {
public static void main(String[] args) throws PlivoXmlException {
Response response = new Response()
.children(
new Speak("You will now be placed into the conference"),
new Conference("")
.record(true)
.callbackMethod("POST")
.callbackUrl("https://.com/confevents/")
.waitSound("https://.com/waitmusic/")
);
System.out.println(response.toXmlString());
}
}
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Locate the file PlivoVoiceApplication.java in the src/main/java/com.example.demo/ folder and paste into it this code.
Note: Here, the demo application name is PlivoVoiceApplication.java because the friendly name provided in the Spring Initializr was “Plivo Voice.”
```java theme={null}
package com.example.demo;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.actions.CallRecordCreateResponse;
import com.plivo.api.xml.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.plivo.api.exceptions.PlivoXmlException;
import java.io.IOException;
@SpringBootApplication
@RestController
public class PlivoVoiceApplication {
public static void main(String[] args) {
SpringApplication.run(PlivoVoiceApplication.class, args);
}
@GetMapping(value = "/record", produces = {
"application/xml"
})
public Response recordCall() throws PlivoXmlException, IOException, PlivoRestException {
Response resp = new Response();
resp.children(
new GetInput()
.action("https://.com/record_action/")
.method("POST")
.inputType("dtmf")
.digitEndTimeout(5)
.redirect(true)
.children(
new Speak("Press 1 to record this call")
));
return resp;
}
@GetMapping(value = "/record_action", produces = {
"application/xml"
})
public String forwardCall(@RequestParam("Digits") String digits, @RequestParam("CallUUID") String callUuid) throws PlivoXmlException, IOException, PlivoRestException {
System.out.println("Digit : " + digits + " Call UUID : " + callUuid);
Response resp = new Response();
Plivo.init("", "");
if (digits.equals("1")) {
CallRecordCreateResponse r = Call.recorder(callUuid)
.record();
System.out.println(r);
} else {
System.out.println("Invalid input");
}
return "ok";
}
}
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
```java theme={null}
package com.plivo.api.samples.conference.record;
import java.io.IOException;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.conference.Conference;
import com.plivo.api.models.conference.ConferenceRecordCreateResponse;
class RecordCreate {
public static void main(String[] args) {
Plivo.init("","");
try {
ConferenceRecordCreateResponse response = Conference.recorder("")
.record();
System.out.println(response);
} catch (PlivoRestException | IOException e) {
e.printStackTrace();
}
}
}
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
## Overview
This guide shows how to initiating call recordings for outbound API calls, Dial XML-connected calls, and conference calls. You can record inbound calls to a Plivo number too when the application associated with the number returns an XML document with a Dial and a Record element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to [set up a Go development environment](/docs/sdk/server/set-up-go-dev-environment-phlo/) and a web server and safely expose that server to the internet.
## Record a complete outbound call using XML
You can record a complete call session using the [Record XML](/docs/voice/xml/record/) element in conjunction with a [Dial](/docs/voice/xml/routing#dial) element response that’s returned by an answer URL. Recording a complete call is useful in applications such as virtual voicemail boxes and automated speech surveys.
The XML might look like this:
```xml theme={null}
12025551234
```
When the number specified in the Dial XML element answers the call, Plivo records the complete call session. Recording details are sent to the action URL as soon as the recording starts. You can use the attributes available in the Record XML element to control the recording behavior.
Create a file called `record_call.go` and paste into it this code.
```go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response: = xml.ResponseElement {
Contents: [] interface {} {
new(xml.RecordElement).
SetAction("https://.com/get_recording/").
SetRedirect(false).
SetStartOnDialAnswer(true),
new(xml.DialElement).
SetContents([] interface {} {
new(xml.NumberElement).
SetContents(""),
}),
},
}
print(response.String())
}
```
Replace the phone number placeholder with an actual phone number (for example, 12025551234).
## Record a complete conference call using XML
You can record a complete conference call initiated using a [Conference XML](/docs/voice/xml/conference/) element by using an XML response like this:
```xml theme={null}
My Room
```
Plivo will record the complete audio of a conference call connected via this XML document. Recording details are sent to the action URL and callback URL as soon as the recording starts. The parameter `ConferenceAction=record` is also sent to the callback URL when the recording starts.
Create a file called `record_call.go` and paste into it this code.
```go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response: = xml.ResponseElement {
Contents: [] interface {} {
new(xml.SpeakElement).
AddSpeak("You will now be placed into the conference"),
new(xml.ConferenceElement).
SetRecord(true).
SetCallbackMethod("POST").
SetCallbackUrl("https://.com/confevents/").
SetWaitSound("https://.com/waitmusic/").
SetContents(" "),
},
}
print(response.String())
}
```
## Start and stop call recording using APIs
You can start and stop voice recordings for outbound API calls, Dial XML-connected calls, and conference calls using the Record API and Record Conference API.
### Record API
To start recording using the Record API, you must use the CallUUID of the particular call that you want to record.
### Retrieve a CallUUID
You can get the CallUUID of a call connected via the Outbound API and Dial XML from any of these arguments:
* ring\_url: Plivo sends a webhook callback to the ring URL used in the call API request as soon as the destination number starts ringing.
* answer\_url: Plivo sends a webhook callback to the answer URL when the destination number answers the call.
* fallback\_url: If you define the fallback URL argument in the API request or the application attached to the Plivo number, and if the application server defined in the answer URL is unavailable, then Plivo will try to retrieve the XML document from the fallback URL to process the call. At that time Plivo will send a webhook callback to the fallback URL.
* callback\_url: If you use the callbackUrl parameter in the Dial XML, Plivo will send a callback to the web server configured in callback URL when the number specified in the Dial XML element answers the call.
### Start recording
Once you have the CallUUID of the call you want to record, you can call the record API and specify the CallUUID in the payload.
For example, if you want to record an outbound API call, you can use the code below to record the call once the destination number answers the call. The recording will stop automatically once the call is completed.
Create a file called `record_call.go` and paste into it this code.
```go theme={null}
package main
import (
"fmt"
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"github.com/plivo/plivo-go/v7"
"net/http"
)
func main() {
m: = martini.Classic()
m.Post("/record/", func(w http.ResponseWriter, r * http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response: = xml.ResponseElement {
Contents: [] interface {} {
new(xml.GetInputElement).
SetAction("https://.com/record/action/").
SetMethod("POST").
SetDigitEndTimeout(5).
SetInputType("dtmf").
SetRedirect(true).
SetContents([] interface {} {
new(xml.SpeakElement).
AddSpeak("Press 1 to record this call"),
}),
},
}
return response.String()
})
m.Post("/record/action/", func(w http.ResponseWriter, r * http.Request) string {
digits: = r.FormValue("Digits")
uuid: = r.FormValue("CallUUID")
fmt.Printf("Digit received: %#v\n", digits)
client,
err: = plivo.NewClient("", "", & plivo.ClientOptions {})
if err != nil {
panic(err)
}
response,
err: = client.Calls.Record(
uuid,
plivo.CallRecordParams {},
)
fmt.Printf("Response: %#v\n", response)
return "ok"
})
m.Run()
}
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a call by using the CallUUID — see our [API reference documentation](/docs/voice/api/calls#record-a-call).
## Start and stop conference call recording using APIs
### Record Conference API
To start recording conference calls using the Record Conference API, use the name of the conference you want to record. If you want to start recording a conference call once a participant has entered the conference room, you can use this code.
Create a file called `record_call.go` and paste into it this code.
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
err: = plivo.NewClient("", "", & plivo.ClientOptions {})
if err != nil {
panic(err)
}
response, err: = client.Conferences.Record(
"",
plivo.ConferenceRecordParams {},
)
if err != nil {
panic(err)
}
fmt.Printf("Response: %#v\n", response)
}
```
Replace the auth placeholders with your authentication credentials from the Plivo console.
### Stop recording
You can stop recording a conference call by using the conference name — see our [API reference documentation](/docs/voice/api/conferences#record-a-conference).
## Recording features
* **File formats**: You can choose the recording file format (WAV or MP3) by using the `file_format` attribute for the Record API and Record Conference API, `recordFileFormat` for the Conference XML element, and `fileFormat` for the Record XML element.
* **Channels**: Plivo makes mono recordings of conference calls and stereo recordings of regular calls.
* **Recording length**: You can set the maximum duration of a recording by using arguments and attributes such as `time_limit` for the Record API and `maxLength` for the Record XML element.
## Managing recordings
* **Fetching recording details**: You can store and retrieve the recording details of the voice calls and conference calls using the HTTP callbacks received on the action and callback URLs. You can also fetch recording details from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
* **Deleting recordings**: You can delete a recording by using the [Delete a Recording API](/docs/voice/api/recordings#delete-a-recording) and specifying a recording ID, which you can retrieve from the HTTP callback details stored in your database. You can also delete recordings from the Voice >[ Recordings](https://cx.plivo.com/logs) page of the Plivo console.
## Authentication for recordings
Recordings hosted on Plivo servers are accessible only via unique, hard to guess, long URLs that Plivo shares in recording callbacks and API responses. By default, we do not enforce authentication on GET recording media requests to allow for easy implementation of use cases that involve playing recordings on a web or mobile front end.
For enhanced security, we recommend enabling basic authentication for retrieving recording media assets in your Plivo account. You can enable Basic Auth for Recording URLs from the Voice >[ Other Settings](https://cx.plivo.com/home) page of the Plivo console.
Note: Only account admins (users with the role Admin) have the required privileges to update the recording authentication preference setting.
# Reject Incoming Calls
Source: https://plivo.com/docs/voice/use-cases/reject-incoming-calls
Reject unwanted incoming calls on your Plivo phone numbers
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an application to reject incoming calls
Create a file called `reject_call.js` and paste into it this code.
```js theme={null}
var express = require('express');
var plivo = require('plivo');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.all('/reject_calls/', function(request, response) {
var response = plivo.Response();
var params = {
'reason': 'rejected'
};
response.addHangup(params);
res.writeHead(200, {'Content-Type': 'text/xml'});
res.end(response.toXML());
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
## Create a Plivo application to reject calls
Associate the code you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to reject incoming calls
Change to the project directory and run this command to create a Rails controller to reject incoming calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This command generates a controller named plivo\_controller in the app/controllers/ directory, and a view will be generated in app/views/plivo directory. We can delete the view as we don’t need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Open the file app/controllers/plivo\_controller.rb and paste this code in the PlivoController class:
```rb theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
def reject
r = Response.new()
params = {
'reason' => 'rejected', # Specify the reason for hangup
}
r.addHangup(params)
xml = Plivo::PlivoXML.new(r)
render xml: xml.to_xml
end
end
```
## Create a Plivo application to reject calls
Associate the Rails controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask server to reject incoming calls
Create a file called `reject_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, Response
from plivo import plivoxml
app = Flask(__name__)
@app.route("/reject_call/", methods=['GET','POST'])
def hangup():
# Generate Hangup XML to reject an incoming call.
response = plivoxml.ResponseElement()
params = {'reason': 'rejected'}
response.add(plivoxml.HangupElement(**params))
return Response(response.to_string(), mimetype='application/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
## Create a Plivo application to reject calls
Associate the Flask server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to reject incoming calls
Change to the project directory and run this command to create a Laravel controller to reject inbound calls.
```shell theme={null}
$ php artisan make:controller VoiceController
```
The command generates a controller named VoiceController in the app/http/controllers/ directory. Edit the app/http/controllers/voiceController.php file and paste into it this code.
```php theme={null}
'rejected', # Specify the reason for hangup
);
$r->addHangup($params);
Header('Content-type: text/xml');
echo $r->toXML();
}
}
```
## Create a Plivo application to reject calls
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to reject incoming calls
In Visual Studio, create a new project. Use the template for Web Application (Model-View-Controller).
Give the project a name — we used `Rejectcall`.
Navigate to the Controllers directory in the Rejectcall project. Create a controller named RejectcallController.cs and paste into it this code.
```cs theme={null}
using System;
using Plivo.XML;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace Rejectcall
{
public class RejectcallController : Controller
{
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
// Add Hangup XML Tag
resp.AddHangup(new Dictionary()
{
{"reason","rejected"}, // Specify the reason for hangup
});
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
## Create a Plivo application to reject calls
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application to reject incoming calls
Create a Java class named `RejectCall` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
public class rejectcall {
public static void main(String[] args) {
post("/reject_calls", (request, response) - > {
response.type("application/xml");
Response resp = new Response()
.children(
new Hangup()
.reason("rejected")
);
// Returns the XML
return resp.toXmlString();
});
}
}
```
## Create a Plivo application to reject calls
Associate the Spark application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
## Overview
When you don’t want to receive incoming calls on your Plivo numbers, follow the instructions in this guide to create an application to reject them.
You can reject incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that rejects incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, Plivo rejects the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to reject incoming calls
Create a file called `reject_call.go` and paste into it this code.
```go theme={null}
package main
import (
"net/http"
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
m := martini.Classic()
m.Get("/reject_call", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.HangupElement).
SetReason("rejected"),
},
}
print(response.String())
return response.String()
})
m.Run()
}
```
## Create a Plivo application to reject calls
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Reject Call`. Enter the server URL you want to use (for example `https://.com/reject_caller/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Reject Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides — in this case, rejecting it.
# Screen Incoming Calls
Source: https://plivo.com/docs/voice/use-cases/screen-incoming-calls
Block calls from specific phone numbers or country codes
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to screen incoming calls
Create a file called `screen_call.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.set('port', (process.env.PORT || 5000));
app.all('/screen_call/', function(request, response) {
var blacklist = [ '', '', ''];
// Get the caller's phone number from the 'From' parameter
var from_number = request.query.From || request.body.From;
var r = plivo.Response();
if (blacklist.indexOf(from_number) === -1){
var body = "Hello, how are you today";
r.addSpeak(body);
} else {
//Specify the reason for hangup
var params = {'reason': "rejected"};
r.addHangup(params);
}
console.log (r.toXML());
response.set({'Content-Type': 'text/xml'});
response.send(r.toXML());
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the Express server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to screen incoming calls
Change to the project directory and run this command to create a Rails controller to screen incoming calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This command generates a controller named plivo\_controller in the app/controllers/ directory, and a view will be generated in app/views/plivo directory. We can delete the view as we don’t need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Open the file app/controllers/plivo\_controller.rb and paste this code in the PlivoController class:
```rb theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
def screen
blacklist = ['', '', '']
from_number = params[:From]
r = Response.new()
if blacklist.include? from_number
# Specify the reason for hangup
params = {
reason: 'rejected'
}
r.addHangup(params)
else
r.addSpeak('Hello, how are you today')
end
xml = Plivo::PlivoXML.new(r)
render xml: xml.to_xml
end
end
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the Rails server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask application to screen incoming calls
Create a file called `screen_call.py` and paste into it this code.
```py theme={null}
from flask import Flask, Response
from flask import request
from plivo import plivoxml
app = Flask(__name__)
@app.route('/screen_call/', methods=['GET', 'POST'])
def screen_call():
blacklist = ['','','']
from_number = request.values.get('From')
response = plivoxml.ResponseElement()
if from_number in blacklist:
params = {'reason': 'rejected'}
response.add(plivoxml.HangupElement(**params))
else:
response.add(plivoxml.SpeakElement('Hello, how are you today'))
return Response(response.to_string(), mimetype='application/xml')
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the Flask application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to screen incoming calls
Change to the project directory and run this command to create a Laravel controller to screen inbound calls.
```shell theme={null}
$ php artisan make:controller VoiceController
```
The command generates a controller named VoiceController in the app/http/controllers/ directory. Edit the app/http/controllers/voiceController.php file and paste into it this code.
```php theme={null}
', '', '');
$r = new Response();
if (in_array($from_number, $blacklist)) {
$params = array('reason' => 'rejected');
$r->addHangup($params);
} else {
$body = "Hello, how are you today";
$r->addSpeak($body);
}
Header('Content-type: text/xml');
echo $r->toXML();
}
}
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the Laravel controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to screen incoming calls
In Visual Studio, create a new project. Use the template for Web Application (Model-View-Controller).
Give the project a name — we used `Screencall`.
Navigate to Controllers directory in the Screencall project. Create a controller named ScreencallController.cs and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo.XML;
using Microsoft.AspNetCore.Mvc;
namespace Screencall.Controllers
{
public class ScreencallController : Controller
{
// GET: //
public IActionResult Index()
{
string[] blacklist = { "", "", "" };
string fromNumber = Request.Query["From"];
Plivo.XML.Response resp = new Plivo.XML.Response();
if (blacklist.Equals(fromNumber))
{
resp.AddHangup(new Dictionary()
{
{"reason","rejected"}, // Specify the reason for hangup
});
}
else
{
resp.AddSpeak("Hello, how are you today", new Dictionary() { });
}
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application to screen incoming calls
Create a Java class named `ScreenCall` and paste into it this code.
```java theme={null}
import java.util.Arrays;
import com.plivo.api.xml.Hangup;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
import static spark.Spark.*;
public class screencalls {
public static void main(String[] args) {
post("/screen_call/", (request, response) -> {
response.type("application/xml");
String fromNumber = request.queryParams("From");
String[] blacklist = { "","", ""};
if (Arrays.asList(blacklist).contains(fromNumber)) {
return new Response()
.children(
new Hangup()
.reason("rejected")
).toXmlString();
} else {
return new Response()
.children(
new Speak("Hello, how are you today")
).toXmlString();
}
});
}
}
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the Spark application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
## Overview
When you don’t want to receive calls from a specific phone number or even a whole country, follow the instructions in this guide to create an application to block phone numbers or country codes associated with incoming calls.
You can screen incoming calls either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use a Plivo XML document that screens incoming calls on a Plivo number.
## How it works
Plivo requests an answer URL when it answers the call (step 2) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. In this example, when an incoming call is received, we check whether the number has been blacklisted. If it has, we reject the call using the [Hangup](/docs/voice/xml/routing#hangup) XML element. If the phone number hasn't been blacklisted, we return a [Speak](/docs/voice/xml/audio-output#speak) XML element that says, “Hello, how are you today.”
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to screen incoming calls
Create a file called `screen_call.go` and paste into it this code.
```go theme={null}
package main
import (
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
m := martini.Classic()
m.Get("/screen_call", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
fromNumber := r.FormValue("From")
blacklist := []string{"", "", ""}
for _, num := range blacklist {
if num == fromNumber {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.HangupElement).
SetReason("rejected"),
},
}.String()
}
}
return xml.ResponseElement{Contents: []interface{}{
new(xml.SpeakElement).
SetLoop(0).
AddSpeak("Hello, how are you today"),
}}.String()
})
m.Run()
}
```
Replace the phone number placeholders with actual phone numbers (for example, 12025551234).
## Create a Plivo application to screen calls
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Screen Call`. Enter the server URL you want to use (for example `https://.com/screen_call/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Screen Call` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number using any phone. Plivo will send a request to the answer URL you provided requesting an XML response and then process the call according to the instructions in the XML document the server provides. If your phone number is not blacklisted, the call will go through and you should hear, “Hello, how are you today.”
# Send SMS Alerts
Source: https://plivo.com/docs/voice/use-cases/supervisor-coaching
Implement supervisor coaching for call center agents using multiparty calls
## Overview
Supervisors in call centers need to coach agents to cultivate an effective team. Coaching involves supervisors listening in on live calls and advising agents without customers’ knowledge. A supervisor can also take over a call and talk to a customer directly. This guide shows how to implement supervisor coaching using Plivo‘s multiparty call (MPC) feature. We’ll look at four tasks:
* Connecting a customer and an agent
* Agent adding supervisor to a call
* Supervisor joining call
* Supervisor taking over call
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Connect customer and agent
Consider the case of a call center where customers call a hotline number to connect with a customer support representative using a web app powered by [Plivo Browser SDK](/docs/voice/sdk/browser/overview). The call flow goes like this:
1. Customer dials in from the browser app to talk to an agent.
2. The customer is added to a multiparty call.
3. The agent is added to the same multiparty call.
Here’s what that process looks in Node.js.
```js theme={null}
var plivo = require('../plivo-node/');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
var musicUrl = "https://s3.amazonaws.com/plivocloud/music.mp3"
var client = new plivo.Client("","");
// Add customer to the MPC
app.all('/add/customer/', function (request, response) {
var r = new plivo.Response();
var mpcName = 'test';
var params = {
"role": "Customer",
"statusCallbackUrl": "https://.ngrok.io/add/agent/",
"statusCallbackMethod": "POST",
"waitMusicUrl": musicUrl,
"waitMusicMethod": "GET",
};
r.addMultiPartyCall(mpcName, params);
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
});
//Add agent to the MPC to talk to the customer
app.all('/add/agent/', function (request, response) {
var mpcEventName = request.query.EventName || request.body.EventName;
var mpcMPCUUID = request.query.MPCUUID || request.body.MPCUUID;
var mpcParticipantCallFrom = request.query.ParticipantCallFrom || request.body.ParticipantCallFrom;
console.log(mpcEventName);
if (mpcEventName == 'MPCInitialized') {
client.multiPartyCalls.addParticipant('Agent', { 'uuid': mpcMPCUUID, 'from': mpcParticipantCallFrom, 'to': 'sip:Testendpoint181116105835@phone.plivo.com', 'status_callback_url': 'https://.ngrok.io/agent/callback/' })
console.log(response);
}
});
// Collect status callback events after agent joins the MPC
app.all('/agent/callback/', function (request, response) {
var mpcMPCUUID = request.query.MPCUUID;
console.log(mpcMPCUUID)
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home).
## Agent adds supervisor to a call
The previous example was a simple case that involved just a customer and an agent. If the call center wants to provide supervisor coaching, agents can add a supervisor to an ongoing multiparty call like this:
1. The agent clicks an Add Supervisor button on the dialer web app on which they’re talking to the customer.
2. The supervisor is added to the multiparty call using Plivo’s [Add Participant API](/docs/voice/api/multiparty-calls#add-a-participant).
3. By default, only the agent will be able to hear the supervisor. You can override this by changing the coachMode parameter to `false`.
Here’s what that process looks like in Node.js.
```js theme={null}
var plivo = require('../plivo-node/');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
var musicUrl = "https://s3.amazonaws.com/plivocloud/music.mp3"
var client = new plivo.Client("","");
// Add customer to the MPC
app.all('/add/customer/', function (request, response) {
...
...
});
//Add agent to the MPC to talk to the customer
app.all('/add/agent/', function (request, response) {
...
...
});
// Collect status callback events after agent joins the MPC
app.all('/agent/callback/', function (request, response) {
...
...
});
// Agent clicks "Add supervisor to the call" option to add them to the ongoing MPC
app.all('/add_supervisor/:mpcMPCUUID', function (request, response) {
var mpcUUID = request.params("mpcMPCUUID");
client.multiPartyCalls.addParticipant('Supervisor', { 'uuid': mpcUUID, 'from': mpcParticipantCallFrom, 'to': 'sip:Testendpoint181116105835@phone.plivo.com', 'status_callback_url': 'https://.ngrok.io/supervisor/callback/' })
console.log(response);
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
## Supervisor joins an ongoing call
Not all supervisor calls are initiated by agents — supervisors can jump in themselves. Here’s how this process — often called call barging — works:
1. An agent is talking to a customer on an ongoing multiparty call.
2. A supervisor, who is monitoring all the live calls on the call center web dashboard, clicks on a Join the Call button next to the longest call in the queue.
3. The supervisor can then listen to the call and coach the agent.
Here’s what that process looks like in Node.js.
```js theme={null}
var plivo = require('../plivo-node/');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
var musicUrl = "https://s3.amazonaws.com/plivocloud/music.mp3"
var client = new plivo.Client("","");
// Add customer to the MPC
app.all('/add/customer/', function (request, response) {
...
...
});
//Add agent to the MPC to talk to the customer
app.all('/add/agent/', function (request, response) {
...
...
});
// Collect status callback events after agent joins the MPC
app.all('/agent/callback/', function (request, response) {
...
...
});
// Agent clicks "Add supervisor to the call" option to add them to the ongoing MPC
app.all('/add_supervisor/:mpcMPCUUID', function (request, response) {
...
...
});
// Supervisor clicks "Join the call" option to be added to the ongoing MPC
app.all('/coach_the_agent/', function (request, response) {
var r = new plivo.Response();
var mpcName = 'test'; // MPC name of the call to which the supervisor wishes to join; you can get this from status_callback_url
var params = {
"role": "Supervisor",
"coach_mode": True, // The supervisor can talk to only the agent.
"status_callback_url": "https://.ngrok.io/supervisor/callback/",
"status_callback_method": "POST",
"enter_sound": "none",
};
r.addMultiPartyCall(mpcName, params);
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
## Supervisor takes over a call
Depending on what they hear, sometimes supervisors want to talk to both the customer and the agent. Here’s how that process might go.
1. An agent is talking to a customer on an ongoing multiparty call.
2. The supervisor is monitoring all live calls on the call center web dashboard.
3. The supervisor clicks on the Take Over the Call button of a specific call, and can then take over the call and talk to both the customer and the agent.
Here’s what that process looks like in Node.js.
```js theme={null}
var plivo = require('../plivo-node/');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
var musicUrl = "https://s3.amazonaws.com/plivocloud/music.mp3"
var client = new plivo.Client("","");
// Add customer to the MPC
app.all('/add/customer/', function (request, response) {
...
...
});
//Add agent to the MPC to talk to the customer
app.all('/add/agent/', function (request, response) {
...
...
});
// Collect status callback events after agent joins the MPC
app.all('/agent/callback/', function (request, response) {
...
...
});
// Agent clicks "Add supervisor to the call" option to add him to the ongoing MPC
app.all('/add_supervisor/:mpcMPCUUID', function (request, response) {
...
...
});
// Supervisor clicks "Join the call" option to add him to the ongoing MPC
app.all('/coach_the_agent/', function (request, response) {
...
...
});
// Supervisor clicks "Join the call" option to be added to the ongoing MPC
app.all('/talk_to_customer/', function (request, response) {
var r = new plivo.Response();
var mpcName = 'test'; // MPC name of the call to which the supervisor wishes to join; you can get this from status_callback_url
var params = {
"role": "Supervisor",
"coach_mode": false, // The supervisor can talk to only the agent
"status_callback_url": "https://.ngrok.io/supervisor/callback/",
"status_callback_method": "POST",
"enter_sound": "none",
};
r.addMultiPartyCall(mpcName, params);
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.end(r.toXML());
});
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
```
As you can see, Plivo makes it easy to set up and manage multiparty calls. With these capabilities, you can run your own call center, manage call transfers, coach agents, and much more. For more details, see our [Multiparty Call API reference](/docs/voice/api/multiparty-calls) page.
## Overview
Supervisors in call centers need to coach agents to cultivate an effective team. Coaching involves supervisors listening in on live calls and advising agents without customers’ knowledge. A supervisor can also take over a call and talk to a customer directly. This guide shows how to implement supervisor coaching using Plivo‘s multiparty call (MPC) feature. We’ll look at four tasks:
* Connecting a customer and an agent
* Agent adding supervisor to a call
* Supervisor joining call
* Supervisor taking over call
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the Numbers API. If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Connect customer and agent
Consider the case of a call center where customers call a hotline number to connect with a customer support representative using a web app powered by [Plivo Browser SDK](/docs/voice/sdk/browser/overview). The call flow goes like this:
1. Customer dials in from the browser app to talk to an agent.
2. The customer is added to a multiparty call.
3. The agent is added to the same multiparty call.
Here’s what that process looks like in Python.
```py theme={null}
from flask import Flask, Response, request, make_response
import plivo
from plivo import plivoxml
app=Flask(__name__)
music_url = "https://s3.amazonaws.com/plivocloud/music.mp3"
client = plivo.RestClient(auth_id="", auth_token="")
# Add customer to the MPC. You can assign this to the Plivo app of the endpoint mapped to the customer in the browser app
@app.route("/add/customer/", methods=["GET", "POST"])
def multipartycall_add_customer():
mpc_name = "test"
mpc_params = {
"content": mpc_name,
"role": "Customer",
"status_callback_url": "https://.ngrok.io/add/agent/",
"status_callback_method": "POST",
"wait_music_url": music_url,
"wait_music_method": "GET",
}
mpc_element = plivoxml.MultiPartyCallElement(**mpc_params)
res = plivoxml.ResponseElement()
res.add(mpc_element)
return Response(res.to_string(), mimetype="application/xml")
# Add agent to the MPC to talk to the customer
@app.route("/customer/callback/", methods=["GET", "POST"])
def multipartycall_add_agent():
mpc_EventName = request.form.get("EventName")
mpc_MPCUUID = request.form.get("MPCUUID")
mpc_ParticipantCallFrom = request.form.get("ParticipantCallFrom")
if mpc_EventName == "MPCInitialized":
call_params = {
'role': "Agent",
'uuid': mpc_MPCUUID,
'start_mpc_on_enter': True,
'from_': mpc_ParticipantCallFrom, # Customer number as caller ID
'to_': "sip:websdk171107061912@phone.plivo.com", #Agent's endpoint username or phone number
'call_status_callback_url': "https://.ngrok.io/agent/callback/",
'call_status_callback_method': 'POST',
"enter_sound": "none"
}
try:
response = client.multi_party_calls.add_participant(**call_params)
except Exception as e:
response = client.multi_party_calls.stop(uuid=mpc_MPCUUID)
return 'ok'
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home).
## Agent adds supervisor to a call
1. The previous example was a simple case that involved just a customer and an agent. If the call center wants to provide supervisor coaching, agents can add a supervisor to an ongoing multiparty call like this:
1. The agent clicks an Add Supervisor button on the dialer web app on which they’re talking to the customer.
2. The supervisor is added to the multiparty call using Plivo’s [Add Participant API](/docs/voice/api/multiparty-calls#add-a-participant).
3. By default, only the agent will be able to hear the supervisor. You can override this by changing the coachMode parameter to `false`.
Here’s what that process looks like in Python.
```py theme={null}
from flask import Flask, Response, request, make_response
import plivo
from plivo import plivoxml
app=Flask(__name__)
music_url = "https://s3.amazonaws.com/plivocloud/music.mp3"
client = plivo.RestClient(auth_id="", auth_token="")
@app.route("/mpc/customer/", methods=["GET", "POST"])
def multipartycall_customer():
....
....
# Add agent to the MPC to talk to the customer
@app.route("/customer/callback/", methods=["GET", "POST"])
def multipartycall_agent():
....
....
# Agent clicks "Add supervisor to the call" option to add them to the ongoing MPC
@app.route("/add_supervisor/", methods=["GET", "POST"])
def add_supervisor(mpc_MPCUUID):
call_params = {
'role': "Supervisor",
'uuid': mpc_MPCUUID, # you can get this from status_callback_url
'dial_music': 'None',
'from_': "", # Agent number as caller ID; you can get this from status_callback_url
'to_': "sip:browsersdkdemo438313651789286059@phone.plivo.com", #Supervisor Phone number goes here
'call_status_callback_url': "https://.ngrok.io/supervisor/callback/",
'call_status_callback_method': 'POST',
}
response = client.multi_party_calls.add_participant(**call_params)
return str(response)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
## Supervisor joins an ongoing call
Not all supervisor calls are initiated by agents — supervisors can jump in themselves. Here’s how this process — often called call barging — works:
1. An agent is talking to a customer on an ongoing multiparty call.
2. A supervisor, who is monitoring all the live calls on the call center web dashboard, clicks on a Join the Call button next to the longest call in the queue.
3. The supervisor can then listen to the call and coach the agent.
Here’s what that process looks like in Python.
```py theme={null}
from flask import Flask, Response, request, make_response
import plivo
from plivo import plivoxml
app=Flask(__name__)
music_url = "https://s3.amazonaws.com/plivocloud/music.mp3"
client = plivo.RestClient(auth_id="", auth_token="")
@app.route("/mpc/customer/", methods=["GET", "POST"])
def multipartycall_customer():
....
....
# Add agent to the MPC to talk to the customer
@app.route("/customer/callback/", methods=["GET", "POST"])
def multipartycall_agent():
....
....
# Agent clicks "Add supervisor to the call" option to add them to the ongoing MPC
@app.route("/add_supervisor/", methods=["GET", "POST"])
def add_supervisor():
....
....
# Supervisor clicks "Join the call" option to be added to the ongoing MPC
@app.route("/coach_the_agent/", methods=["GET", "POST"])
def join_specific_mpc(mpc_MPCUUID):
mpc_name = "test" # MPC name of the call to which the supervisor wishes to join; you can get this from status_callback_url
mpc_params = {
"content": mpc_name,
"role": "Supervisor",
"coach_mode": True, # The supervisor can talk to only the agent.
"status_callback_url": "https://.ngrok.io/supervisor/callback/",
"status_callback_method": "POST",
"enter_sound": "none",
}
mpc_element = plivoxml.MultiPartyCallElement(**mpc_params)
res = plivoxml.ResponseElement()
res.add(mpc_element)
return Response(res.to_string(), mimetype="application/xml")
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
## Supervisor takes over a call
Depending on what they hear, sometimes supervisors want to talk to both the customer and the agent. Here’s how that process might go.
1. An agent is talking to a customer on an ongoing multiparty call.
2. The supervisor is monitoring all live calls on the call center web dashboard.
3. The supervisor clicks on the Take Over the Call button of a specific call, and can then take over the call and talk to both the customer and the agent.
Here’s what that process looks like in Python.
```py theme={null}
from flask import Flask, Response, request, make_response
import plivo
from plivo import plivoxml
app=Flask(__name__)
music_url = "https://s3.amazonaws.com/plivocloud/music.mp3"
client = plivo.RestClient(auth_id="", auth_token="")
@app.route("/mpc/customer/", methods=["GET", "POST"])
def multipartycall_customer():
....
....
# Add agent to the MPC to talk to the customer
@app.route("/customer/callback/", methods=["GET", "POST"])
def multipartycall_agent():
....
....
# Agent clicks "Add supervisor to the call" option to add them to the ongoing MPC
@app.route("/add_supervisor/", methods=["GET", "POST"])
def add_supervisor():
....
....
# Supervisor clicks "Join the call" option to be added to the ongoing MPC
@app.route("/coach_the_agent/", methods=["GET", "POST"])
def join_specific_mpc():
....
....
# Supervisor clicks "Take over the call" option to be added to the ongoing MPC
@app.route("/talk_to_customer/", methods=["GET", "POST"])
def talk_to_customer():
mpc_name = "test" # MPC name of the call to which the supervisor wishes to join; you can get this from status_callback_url
mpc_params = {
"content": mpc_name,
"role": "Supervisor",
"coach_mode": false, # The supervisor can talk to only the agent
"status_callback_url": "https://.ngrok.io/supervisor/callback/",
"status_callback_method": "POST",
"enter_sound": "none",
}
mpc_element = plivoxml.MultiPartyCallElement(**mpc_params)
res = plivoxml.ResponseElement()
res.add(mpc_element)
return Response(res.to_string(), mimetype="application/xml")
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
As you can see, Plivo makes it easy to set up and manage multiparty calls. With these capabilities, you can run your own call center, manage call transfers, coach agents, and much more. For more details, see our [Multiparty Call API reference](/docs/voice/api/multiparty-calls) page.
# Transfer to Human Agent
Source: https://plivo.com/docs/voice/use-cases/transfer-to-human-agent
Route AI-handled calls to a human agent via DID forwarding or authenticated SIP transfer
A common pattern in AI voice agents is handing off a call to a human agent for escalation, complex queries, or fallback. Plivo supports two transfer methods.
***
## How It Works
Your AI agent (Pipecat, LiveKit, etc.) detects an escalation trigger (caller asks for a human, intent unclear, etc.) and signals a transfer.
Your application returns a `` XML response that routes the call to either a phone number or a SIP endpoint.
Plivo bridges the caller to the human agent. For SIP transfers, Plivo handles authentication with the agent's SIP infrastructure if credentials are provided.
The AI is replaced by the human agent. The original caller experiences a seamless handoff.
***
## Two Options
| Option | What It Does | Best For |
| ---------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| **DID forward** | Transfer to a regular phone number | Simple call centers, agents on PSTN phones, no SIP infrastructure |
| **SIP auth forward** (recommended) | Transfer to a SIP endpoint (softphone, contact center, PBX) with credentials | Modern contact centers, softphone-based agents, lower latency |
***
## Option 1: DID Forward
The simplest transfer. Dial a regular phone number using the `` element in your Dial XML.
```xml theme={null}
Connecting you to a human agent now.
+14155551234
```
### How It Works
* Plivo originates an outbound call from your AI agent's leg to the agent's phone number
* When the agent answers, the two legs are bridged
* Caller and agent are connected; AI agent leaves the call
### Trade-offs
* **Pros:** Works with any phone (mobile, landline, softphone with a DID). Simple to set up.
* **Cons:** Outbound call cost. Agents need a real phone number. Less flexibility for agent routing logic.
***
## Option 2: SIP Auth Forward (Recommended)
Most modern contact center software (Five9, Genesys, NICE, Talkdesk, custom WebRTC apps, etc.) accepts inbound SIP calls. Transfer the AI call directly via SIP using the `` element with authentication credentials.
```xml theme={null}
Connecting you to a human agent now.
sip:agent@your-contact-center.example.com
```
### How It Works
* Plivo sends an initial SIP INVITE to your contact center's SIP endpoint **without** credentials
* If the contact center responds with `401 Unauthorized` or `407 Proxy Authentication Required`, the outbound SBC re-sends the INVITE with the supplied `sipAuthUsername` / `sipAuthPassword`
* Contact center validates credentials; call connects
* Caller and agent are bridged
When passing agent IDs, queue IDs, or call context via `sipHeaders`, be aware that headers with reserved prefixes (`PH-`, `Plivo`, `FS-`, `SipAuth`, `ZT-`, `Twilio`) and the name `ClientRegion` are silently dropped. See [SIP Authentication](/docs/voice/concepts/sip-authentication/) for the full list.
### Why SIP Auth Forward Is Recommended
* **Lower cost** - single SIP termination charge, no PSTN minutes
* **Lower latency** - direct SIP, no PSTN intermediary
* **More flexibility** - pass custom SIP headers, route to specific agent IDs or queues
* **Better for AI workflows** - agents are typically already on softphones or contact center software
### Setup
Find the SIP URI provided by your contact center software (e.g., `sip:queue-1@your-cc.example.com`). Most platforms expose this in their admin dashboard.
Most SIP-based contact center software requires digest authentication. Get the username and password from your contact center setup.
When your agent decides to transfer, return a `` XML response with the `` element. Set `sipAuthUsername` and `sipAuthPassword` to the credentials from Step 2. Point the SIP URI to your contact center endpoint.
Trigger a transfer from your AI agent. The call should connect to the human agent. If authentication fails, the call ends with hangup cause `sip_auth_failed` (code `4240`).
***
## Server-Initiated Handoff
Instead of returning Dial XML, you can trigger the transfer programmatically via the [Make Call API](/docs/voice/api/calls/) using `sip_auth_username` and `sip_auth_password`. This is useful for warm transfers where the agent application needs to consult before connecting the caller.
***
## Whitelist Plivo's IPs at Your Contact Center
If your contact center restricts inbound SIP traffic by IP, you need to whitelist Plivo's outbound media server IPs so that transferred calls from Plivo can reach your agents.
If Plivo's IPs are not whitelisted at your contact center, the transfer will fail at the network level before your contact center even sees the call.
For the complete list of Plivo's media server IPs by region (San Jose, Ashburn, Frankfurt, Sao Paulo, Sydney, Singapore, Mumbai), see [Voice Firewall and Network Configuration](/docs/voice/concepts/firewall-network-configuration/).
Whitelist the IPs in the region closest to your contact center deployment. If your contact center has agents distributed globally, whitelist all relevant regions.
***
## Hangup Causes and Dial Status
When a transfer fails, the Dial action URL and hangup callback include specific values:
| HangupCauseName | Code | DialStatus | Meaning |
| ------------------ | ------ | ----------- | ------------------------------------------------------- |
| `sip_auth_failed` | `4240` | `failed` | SIP credentials were rejected by the remote endpoint |
| `sip_auth_timeout` | `4250` | `timeout` | Remote endpoint did not respond to the digest challenge |
| `no-answer` | — | `no-answer` | Agent did not pick up within the dial timeout |
| `busy` | — | `busy` | Agent endpoint is busy |
Your agent application receives `DialStatus` and `DialHangupCause` on the Dial action URL, so it can detect a failed handoff and respond (e.g., retry with a different endpoint, fall back to a phone number, or inform the caller).
***
## Troubleshooting
| Issue | Solution |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Transfer fails with `sip_auth_failed` | Verify the SIP credentials match exactly. Check your contact center's auth realm. |
| Transfer blocked by firewall | Whitelist [Plivo's outbound media server IPs](/docs/voice/concepts/firewall-network-configuration/) in your contact center |
| Agent answers but no audio | Check codec compatibility. Most contact centers support PCMU/PCMA. Plivo defaults to these. |
| Caller hears silence during ring | Use `dialMusic` attribute on `` to play hold music while the agent is being reached |
***
## Full API Reference
* [Dial XML](/docs/voice/xml/routing#dial/) — Complete reference for ``, ``, and `` elements
* [SIP Authentication](/docs/voice/concepts/sip-authentication/) — How outbound SIP auth works
* [Voice Call API](/docs/voice/api/calls/) — `sip_auth_username` and `sip_auth_password` for API-initiated transfers
* [Firewall and Network Configuration](/docs/voice/concepts/firewall-network-configuration/) — Plivo IPs to whitelist
## Related
* [Connect External Phone Numbers](/docs/voice/use-cases/connect-external-numbers/) — Route external numbers into Plivo applications
* [Build with Audio Streaming](/docs/voice-agents/audio-streaming/overview/) — AI voice agent setup
# Voice Alerts
Source: https://plivo.com/docs/voice/use-cases/voice-alerts
Send automated voice call alerts with audio playback and keypress responses
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice alerts.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/alert.xml](https://s3.amazonaws.com/static.plivo.com/alert.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment.
## Create a voice alerts application in Node.js
Create a file called `Makecall.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.create(
"", // from
"", // to
"https://s3.amazonaws.com/static.plivo.com/alert.xml", // answer url
{
answerMethod: "GET",
},
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `process.env` to store environment variables and fetch them while initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ node Makecall.js
```
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice alerts.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/alert.xml](https://s3.amazonaws.com/static.plivo.com/alert.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment.
## Create a voice alerts application in Ruby
Create a file called `make_call.rb` and paste into it this code.
```ruby theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'',
[''],
'https://s3.amazonaws.com/static.plivo.com/alert.xml'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ ruby make_call.rb
```
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice alerts.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment.
## Create a voice alerts application in Python
Create a file called `make_call.py` and paste into it this code.
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from='',
to='',
answer_url='https://s3.amazonaws.com/static.plivo.com/alert.xml',
answer_method='GET', )
print(response)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the os module (`os.environ`) to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ python make_call.py
```
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice alerts.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/alert.xml](https://s3.amazonaws.com/static.plivo.com/alert.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment.
## Create a voice alerts application in PHP
Create a file called `MakeCall.php` and paste into it this code:
```php theme={null}
calls->create('',
[''],
'https://s3.amazonaws.com/static.plivo.com/alert.xml',);
print_r($response);
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `$_ENV` or `putenv/getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ php MakeCall.php
```
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/alert.xml](https://s3.amazonaws.com/static.plivo.com/alert.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Dotnet development environment.
## Create a voice alerts application in C\#
In Visual Studio, open the file in the CS project called `Program.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
namespace testplivo
{
class Program
{
static void Main(string[] args)
{
var api = new PlivoApi("","");
var response = api.Call.Create(
to: new List { "" },
from: "",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/alert.xml"
);
Console.WriteLine(response);
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `Environment.SetEnvironmentVariable` method to store environment variables and `Environment.GetEnvironmentVariable` to fetch them when initializing the client.
## Test
Save the file and run it.
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/alert.xml](https://s3.amazonaws.com/static.plivo.com/alert.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment.
## Create a voice alerts application in Java
Create a Java class in the project called `MakeCall` and paste into it this code.
```java theme={null}
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class MakeCall {
public static void main(String [] args) throws IOException, PlivoRestException {
Plivo.init("","");
CallCreateResponse response = Call.creator("",
Collections.singletonList(""),
"https://s3.amazonaws.com/static.plivo.com/alert.xml")
.answerMethod("GET")
.create();
System.out.println(response);
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use System.getenv() to store environment variables and retrieve them when initializing the client.
## Test
Save the file and run it.
## Overview
This guide shows how to make voice calls to alert customers to critical issues that require immediate attention. You can play recorded audio when the call recipient answers or use text-to-speech. You can then take action based on a dialpad key they press in response. You can set different actions if the call is not answered, if the line is busy, or if you reach voicemail.
You can send voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice alerts.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/answer.xml](https://s3.amazonaws.com/static.plivo.com/answer.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Your database is out of memory. Press 1 to resolve or 2 to escalate.
```
This code instructs Plivo to say, “Your database is out of memory. Press 1 to resolve or 2 to escalate” to the callrecipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment.
## Create a voice alerts application in Go
Create a file called `MakeCall.go` and paste into it this code.
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
client, err := plivo.NewClient("","", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Calls.Create(
plivo.CallCreateParams{
From: "",
To: "",
AnswerURL: "https://s3.amazonaws.com/static.plivo.com/alert.xml",
AnswerMethod: "GET",
},
)
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `os.Setenv` and `os.Getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
go run MakeCall.go
```
# Voice Alerts/Notifications Broadcasting
Source: https://plivo.com/docs/voice/use-cases/voice-broadcasting
Broadcast voice messages to multiple recipients at once
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
Create a file called `Broadcast.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.create(
"", // from
"destination_number1
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `process.env` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
node Broadcast.js
```
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
Create a file called `broadcast.rb` and paste into it this code.
```ruby theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'',
['', ''],
'https://s3.amazonaws.com/static.plivo.com/broadcast.xml'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination numbers may also be SIP endpoints, in which case each destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
ruby broadcast.rb
```
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
Create a file called `broadcast.py` and paste into it this code.
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from='',
to='destination_number1
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `os module(os.environ)` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
python broadcast.py
```
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
Create a file called `broadcast.py` and paste into it this code.
```php theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from='',
to='destination_number1
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `$_ENV` or `putenv/getenv` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
php Broadcast.php
```
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
In Visual Studio, open the file in the CS project called `Program.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
namespace testplivo
{
class Program
{
static void Main(string[] args)
{
var api = new PlivoApi("","");
var response = api.Call.Create(
to: new List { "", "" },
from: "",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/broadcast.xml"
);
Console.WriteLine(response);
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination numbers may also be SIP endpoints, in which case each destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use [Environment.SetEnvironmentVariable Method](https://docs.microsoft.com/en-us/dotnet/api/system.environment.setenvironmentvariable?view=netcore-3.1) to store environment variables and [Environment.GetEnvironmentVariable Method](https://docs.microsoft.com/en-us/dotnet/api/system.environment.getenvironmentvariable?view=netcore-3.1) to fetch them when initializing the client.
## Test
Save the file and run it.
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
Create a Java class in the project called `Broadcast` and paste into it this code.
```java theme={null}
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class MakeCall {
public static void main(String [] args) throws IOException, PlivoRestException {
Plivo.init("","");
CallCreateResponse response = Call.creator("",
Collections.singletonList("", ""),
"https://s3.amazonaws.com/static.plivo.com/broadcast.xml")
.answerMethod("GET")
.create();
System.out.println(response);
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234). Destination numbers may also be SIP endpoints, in which case each destination\_number placeholder must be a valid SIP URI — for example, sip:[john1234@phone.plivo.com](mailto:john1234@phone.plivo.com).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use [System.getenv()](https://docs.oracle.com/javase/tutorial/essential/environment/env.html) to store environment variables and retrieve them when initializing the client.
## Test
Save the file and run it.
## Overview
This guide shows how to broadcast voice messages to multiple recipients at once. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here.
You can use voice broadcasting for use cases such as:
* Bulk voice calling campaigns
* Emergency notifications
* Survey campaigns
* User feedback
* Announcements
* Promotions and special deals
* Reminder campaigns
You can broadcast voice alerts either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to broadcast voice alerts and notifications using XML.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/broadcast.xml](https://s3.amazonaws.com/static.plivo.com/broadcast.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations! You have made your first bulk call.
```
This code instructs Plivo to say, “Congratulations! You have made your first bulk call” to the call recipients. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create voice alert broadcast application
Create a file called `Broadcast.go` and paste into it this code:
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
client, err := plivo.NewClient("","", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Calls.Create(
plivo.CallCreateParams{
From: "",
To: "destination_number1
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, so as to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and it will automatically fetch them from the environment variables. You can use `os.Setenv` and `os.Getenv` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
go run Broadcast.go
```
# Voice Notifications
Source: https://plivo.com/docs/voice/use-cases/voice-notification
Send audio notifications via voice calls with text-to-speech or recordings
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment.
## Create a voice notification application in Node.js
Create a file called `Makecall.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("","");
client.calls.create(
"", // from
"", // to
"https://s3.amazonaws.com/static.plivo.com/notification.xml", // answer url
{
answerMethod: "GET",
},
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});
})();
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `process.env` to store environment variables and fetch them while initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ node Makecall.js
```
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment.
## Create a voice notification application in Ruby
Create a file called `make_call.rb` and paste into it this code.
```rb theme={null}
require 'rubygems'
require 'plivo'
include Plivo
include Plivo::Exceptions
api = RestClient.new("","")
begin
response = api.calls.create(
'',
[''],
'https://s3.amazonaws.com/static.plivo.com/notification.xml'
)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ ruby make_call.rb
```
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment.
## Create a voice notification application in Python
Create a file called `make_call.py` and paste into it this code.
```py theme={null}
import plivo
client = plivo.RestClient('','')
response = client.calls.create(
from='',
to='',
answer_url='https://s3.amazonaws.com/static.plivo.com/notification.xml',
answer_method='GET', )
print(response)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the os module (`os.environ`) to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ python make_call.py
```
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment.
## Create a voice notification application in PHP
Create a file called `MakeCall.php` and paste into it this code:
```php theme={null}
";
$auth_token = "";
$p = new RestClient($auth_id, $auth_token);
$response = $client->calls->create('',
[''],
'https://s3.amazonaws.com/static.plivo.com/notification.xml',);
print_r($response);
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `$_ENV` or `putenv/getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
$ php MakeCall.php
```
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Dotnet development environment.
## Create a voice notification application in C\#
In Visual Studio, open the file in the CS project called `Program.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
namespace testplivo
{
class Program
{
static void Main(string[] args)
{
var api = new PlivoApi("","");
var response = api.Call.Create(
to: new List { "" },
from: "",
answerMethod: "GET",
answerUrl: "https://s3.amazonaws.com/static.plivo.com/notification.xml"
);
Console.WriteLine(response);
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `Environment.SetEnvironmentVariable` method to store environment variables and `Environment.GetEnvironmentVariable` to fetch them when initializing the client.
## Test
Save the file and run it.
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment.
## Create a voice notification application in Java
Create a Java class in the project `MakeCall` and paste into it this code.
```java theme={null}
import java.io.IOException;
import java.util.Collections;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.call.Call;
import com.plivo.api.models.call.CallCreateResponse;
class MakeCall {
public static void main(String [] args) throws IOException, PlivoRestException {
Plivo.init("","");
CallCreateResponse response = Call.creator("",
Collections.singletonList(""),
"https://s3.amazonaws.com/static.plivo.com/notification.xml")
.answerMethod("GET")
.create();
System.out.println(response);
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `System.getenv()` to store environment variables and retrieve them when initializing the client.
## Test
Save the file and run it.
## Overview
This guide shows how to send audio notifications using voice calls. You can play recorded audio when the call recipient answers or use text-to-speech, as we show here, combining static text with dynamic information that Plivo gets from a variable.
You can use voice notification for use cases such as:
* Order notification
* Booking status
* Delivery status
* Flight cancellation/rescheduling
* Two-factor authentication/one-time password
* New offer notification
* Account balance notification
Implement voice notification either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice notifications.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call. To see how this works, you can use [https://s3.amazonaws.com/static.plivo.com/notification.xml](https://s3.amazonaws.com/static.plivo.com/notification.xml) as an answer URL to test your first outgoing call. The file contains this XML code:
```xml theme={null}
Congratulations, your order was successfully placed
```
This code instructs Plivo to say, “Congratulations, your order was successfully placed” to the call recipient. You can find the entire list of valid Plivo XML verbs in our [XML Reference](/docs/voice/xml/overview/) documentation.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment.
## Create a voice notification application in Go
Create a file called `MakeCall.go` and paste into it this code.
```go theme={null}
package main
import "fmt"
import "github.com/plivo/plivo-go/v7"
func main() {
client, err := plivo.NewClient("","", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Calls.Create(
plivo.CallCreateParams{
From: "",
To: "",
AnswerURL: "https://s3.amazonaws.com/static.plivo.com/notification.xml",
AnswerMethod: "GET",
},
)
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `os.Setenv` and `os.Getenv` functions to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it.
```shell theme={null}
go run MakeCall.go
```
# Voice OTP
Source: https://plivo.com/docs/voice/use-cases/voice-otp
Verify phone numbers with voice one-time passwords using text-to-speech
## Overview
This guide shows how to use a voice one-time password (OTP) to verify a mobile number. We first make a call to the phone number to be verified and use text-to-speech to read a random sequence of digits to the call recipients. The user then confirms the digits by entering them using dialpad keypresses. Voice OTP is commonly used to verify new user registrations for an app or website.
You can send a voice OTP either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice OTPs.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment.
## Create a voice OTP application
Create a file called `voiceotp.js` and paste into it this code.
```js theme={null}
const express = require('express');
const app = express();
const redis = require('redis');
const redisClient = redis.createClient();
var plivo = require('plivo');
// Make call to the destination number with OTP
app.get('/dispatch_otp/:number', function(req, res) {
const number = (req.params.number);
const code = Math.floor(100000 + Math.random() * 900000);
var client = new plivo.Client("", "");
var response = client.calls.create(
"", // from
number, // to
"https://.com/answer_url/" + code, // answer url
{
answerMethod: "GET",
},
)
console.log(response)
redisClient.set(`number:${number}:code`, code, 'EX', 60);
res.send(JSON.stringify({
'status': 'success',
'message': 'verification initiated'
}));
});
// Validate the OTP entered by the user
app.get('/verify_otp/:number/:code', function(req, res) {
const number = (req.params.number);
const code = (req.params.code);
redisClient.get(`number:${number}:code`, function(err, OriginalCode) {
if (OriginalCode == code) {
redisClient.del(`number:${number}:code`);
res.send(JSON.stringify({
'status': 'success',
'message': 'Codes match — number verified'
}));
} else if (OriginalCode != code) {
res.send(JSON.stringify({
'status': 'failure',
'message': 'Codes do not match — number not verified'
}));
} else {
res.send(JSON.stringify({
'status': 'failure',
'message': 'Number not found'
}));
}
});
});
app.listen(5000);
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `process.env` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it, and start Redis.
```shell theme={null}
$ node voiceotp.js
$ redis-server
```
You should see your basic server application in action as below:
```
http://localhost:5000/dispatch_otp/?destination_number=
http://localhost:5000/verify_otp/?destination_number=&otp=
```
## Overview
This guide shows how to use a voice one-time password (OTP) to verify a mobile number. We first make a call to the phone number to be verified and use text-to-speech to read a random sequence of digits to the call recipients. The user then confirms the digits by entering them using dialpad keypresses. Voice OTP is commonly used to verify new user registrations for an app or website.
You can send a voice OTP either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice OTPs.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment.
## Create a Rails controller
Change to the project directory and run this command to create a Rails controller for the voice OTP application.
```shell theme={null}
$ rails generate controller Plivo voice
```
It generates a controller named plivo\_controller in the app/controllers/ directory and a respective view in app/views/plivo. We can delete the view as we don‘t need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
## Create a voice OTP application
Edit app/controllers/plivo\_controller.rb file and add this code.
```ruby theme={null}
include Plivo
require 'redis'
require 'json'
include Plivo::Exceptions
class PlivoController < ApplicationController
def dispatch_otp
redis = Redis.new(host: "localhost")
code = rand(999_999)
dst_number = params[:dst_number]
api = RestClient.new("","")
begin
response = api.calls.create(
'',
[dst_number],
"https://.com/answer_url/#{code}"
)
puts response
end
redis.setex(dst_number, 60, code) # Verification code is valid for 1 min
puts JSON.pretty_generate({ :status=> 'success', :message=> 'verification initiated' })
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
def verify_otp
redis = Redis.new(host: "localhost")
code = params[:otp]
number = params[:number]
original_code = redis.get(number)
if original_code == code
redis.del(number) # verification successful, delete the code
puts JSON.pretty_generate( { :status=> 'success', :message=> 'Codes match — number verified'})
elsif original_code != code
puts JSON.pretty_generate({ :status => "failure", :message=> 'Codes do not match — number not verified' })
else
puts JSON.pretty_generate( { :status=> 'rejected', :message=> 'Number not found' })
end
end
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
### Add a route
Edit the file config/routes.rb and change the line:
```shell theme={null}
get 'plivo/voice'
```
to
```shell theme={null}
get 'plivo/verify_otp'
get 'plivo/dispatch_otp'
```
## Test
Start Rails and Redis.
```shell theme={null}
$ rails server
$ redis-server
```
You should see your basic server application in action as below:
```
http://localhost:3000/plivo/dispatch_otp?destination_number=
http://localhost:3000/plivo/verify_otp?destination_number=&otp=
```
## Overview
This guide shows how to use a voice one-time password (OTP) to verify a mobile number. We first make a call to the phone number to be verified and use text-to-speech to read a random sequence of digits to the call recipients. The user then confirms the digits by entering them using dialpad keypresses. Voice OTP is commonly used to verify new user registrations for an app or website.
You can send a voice OTP either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice OTPs.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment.
## Create a voice OTP application
Create a file called `voiceotp.py` and paste into it this code.
```py theme={null}
import plivo
import random
import redis
from flask import Flask, jsonify
app = Flask(__name__)
r = redis.StrictRedis()
def generate_code():
code = random.choice(range(100000, 999999)) # generating 6-digit random code
return code
# Make call to the destination number with OTP
@app.route("/dispatch_otp/")
def dispatch_otp(destination_number):
try:
# generate OTP.
code = generate_code()
# Make a call
client = plivo.RestClient("", "")
response = client.calls.create(
from_="",
to_=destination_number,
answer_url=f"https://.com/answer_url/{code}",
answer_method="GET",
)
print(response)
print(r.setex("number:%s:code" % destination_number, 60, code))
return (
jsonify({"status": "success", "message": "verification initiated"}),
200,
)
except:
return ("Error encountered", 400)
# verify the OTP enetered by the user
@app.route("/verify_otp//")
def check_code(destination_number, code):
"""
check_code(number, code) accepts a number and the code entered by the user and
tells whether the code entered is correct
"""
# fetch the OTP set for the destination number
original_code = r.get("number:%s:code" % destination_number)
if int(original_code) == int(code): # verification successful, delete the code
r.delete("number:%s:code" % destination_number)
return (
jsonify({"status": "success", "message": "Codes match — number verified"}),
200,
)
elif original_code != code:
return (
jsonify(
{
"status": "rejected",
"message": "Codes do not match — number not verified",
}
),
404,
)
else:
return (jsonify({"status": "failed", "message": "Number not found"}), 500)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `os module(os.environ)` to store environment variables and fetch them when initializing the client.
## Test
Save the file and run it, and start Redis.
```shell theme={null}
$ python voiceotp.py
$ redis-server
```
You should see your basic server application in action as below:
```
http://localhost:5000/dispatch_otp/destination_number
http://localhost:5000/verify_otp/destination_number/otp
```
## Overview
This guide shows how to use a voice one-time password (OTP) to verify a mobile number. We first make a call to the phone number to be verified and use text-to-speech to read a random sequence of digits to the call recipients. The user then confirms the digits by entering them using dialpad keypresses. Voice OTP is commonly used to verify new user registrations for an app or website.
You can send a voice OTP either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
asd
## Overview
This guide shows how to use a voice one-time password (OTP) to verify a mobile number. We first make a call to the phone number to be verified and use text-to-speech to read a random sequence of digits to the call recipients. The user then confirms the digits by entering them using dialpad keypresses. Voice OTP is commonly used to verify new user registrations for an app or website.
You can send a voice OTP either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice OTPs.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment.
## Create a voice OTP application
In Visual Studio, create a controller named `otp.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using Plivo;
using StackExchange.Redis;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace otp.Controllers {
public class otp: Controller {
public object dispatch_otp(String destination_number) {
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost: 6379");
IDatabase conn = redis.GetDatabase();
Random r = new Random();
var code = r.Next(999999);
var api = new PlivoApi("", "");
var response = api.Call.Create(
to: new List < String > {
destination_number
},
from: "",
answerMethod: "POST",
answerUrl: "https://.com/answer_url/" + code);
var key = string.Format("number:{0}:code", destination_number);
conn.StringSet(key, code, TimeSpan.FromSeconds(60));
Verification verification = new Verification();
verification.status = "success";
verification.message = "verification initiated";
string output = JsonConvert.SerializeObject(verification);
return output;
}
public string verify_otp(String destination_number, String otp) {
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost: 6379");
IDatabase conn = redis.GetDatabase();
string key = $ "number:{destination_number}:code";
var compare_code = (string) conn.StringGet(key);
if (compare_code == otp) {
conn.KeyDelete(key);
Verification verification = new Verification();
verification.status = "success";
verification.message = "Number verified";
string output = JsonConvert.SerializeObject(verification);
return output;
} else if (compare_code != otp) {
Verification verification = new Verification();
verification.status = "failure";
verification.message = "Number not verified";
string output = JsonConvert.SerializeObject(verification);
return output;
} else {
Verification verification = new Verification();
verification.status = "failure";
verification.message = "Number not found";
string output = JsonConvert.SerializeObject(verification);
return output;
}
}
private class Verification {
public string status {
get;
internal set;
}
public string message {
get;
internal set;
}
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholder with an actual phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `process.env` to store environment variables and fetch them while initializing the client. You can store environment variables using `
Environment.SetEnvironmentVariable Method` and fetch them using `
Environment.GetEnvironmentVariable Method` when initializing the client.
## Test
Save the file and run it, and start Redis.
```shell theme={null}
$ redis-server
```
You should see your basic server application in action as below:
```
https://localhost:5001/dispatch_otp/?destination_number=
https://localhost:5001/verify_otp/?destination_number=&otp=
```
# Voice Surveys
Source: https://plivo.com/docs/voice/use-cases/voice-survey
Automate voice surveys to collect feedback and poll responses via phone
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a voice survey application in PHP
Change to the project directory and run this command to create a Laravel controller.
```shell theme={null}
$ php artisan make:controller SurveyController
```
This generates a controller named SurveyController in the app/http/controllers/ directory. Edit app/http/controllers/SurveyController.php and add this code.
```php theme={null}
.com/firstbranch.php";
$get_input = $r->addGetInput([
'action' => $getinput_action_url,
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($Question1);
$r->addSpeak($NoinputMessage);
Header('Content-type: text/xml');
echo $r->toXML();
}
// Action URL block for DTMF
public function firstBranch(Request $request)
{
$Question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied or 2 to suggest improvements";
// Message that Plivo reads when the recipient provides negative feedback
$NegativeFeedback = "We're sorry about your bad experience, One of our representatives will get in touch with you";
// Message that Plivo reads when the caller does nothing
$NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
$WronginputMessage = "Sorry, that's not a valid entry";
$r = new Response();
$digit = $_REQUEST['Digits'];
if ($digit == '1'){
$getinput_action_url = "https://.com/secondbranch.php";
$get_input = $r->addGetInput([
'action' => $getinput_action_url,
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($Question2);
$r->addSpeak($NoinputMessage);
}
else if ($digit == '2'){
$r->addSpeak($NegativeFeedback);
}
else {
$r->addSpeak($WronginputMessage);
}
Header('Content-type: text/xml');
echo $r->toXML();
}
// Action URL block for Sales and Support branch
public function secondBranch(Request $request)
{
// Message that Plivo reads when the recipient provides negative feedback
$NegativeFeedback = "We're sorry about your bad experience, One of our representatives will get in touch with you";
// Message that Plivo reads when the caller enters a wrong number
$WronginputMessage = "Sorry, that's not a valid entry";
$r = new Response();
$digit = $_REQUEST['Digits'];
if ($digit == '1'){
$body = "Thank you for participating in the survey";
$params = array(
'language' => "en-GB"
);
$r->addSpeak($body,$params);
}
else if ($digit == '2'){
$r->addSpeak($NegativeFeedback);
}
else {
$r->addSpeak($WronginputMessage);
}
Header('Content-type: text/xml');
echo $r->toXML();
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use `$_ENV` or `putenv/getenv` functions to store environment variables and fetch them when initializing the client.
### Add a route
Add a route for the forward function in the SurveyController class. Edit routes/web.php and add these lines.
```shell theme={null}
Route::match(['get', 'post'], '/survey', 'SurveyController@ivrMain');
Route::match(['get', 'post'], '/firstbranch', 'SurveyController@firstBranch');
Route::match(['get', 'post'], '/secondbranch', 'SurveyController@secondBranch');
```
Start the Laravel server.
```shell theme={null}
$ php artisan serve
```
You should see your basic server application in acation at [http://localhost:8000/survey](http://localhost:8000/survey).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## Create a voice survey application in Ruby
Change to the project directory and run this command to create a Rails controller.
```shell theme={null}
$ rails generate controller Plivo voice
```
This generates a controller named plivo\_controller in the app/controllers/ directory and a respective view in app/views/plivo. We can delete the view as we will not need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and add this code in the PlivoController class.
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
# Message that Plivo reads when the call recipient answers
$question1 = "Hi, this is a call from Plivo. How would you rate your overall satisfaction with our services? Press 1 if you're satisfied or 2 to suggest improvements"
$question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied or 2 to suggest improvements"
# Message that Plivo reads when the recipient provides negative feedback
$negative_feedback = "We're sorry about your bad experience. One of our representatives will get in touch with you"
# Message that Plivo reads when the caller does nothing
$noinput_message = "Sorry, I didn't catch that. Please hang up and try again"
# This is the message that Plivo reads when the caller inputs a wrong number.
$wronginput_message = "Sorry, that's not a valid entry"
def survey
r = Response.new()
getinput_action_url = "https://.com/ivr/firstbranch/"
params = {
action: getinput_action_url,
method: 'POST',
digitEndTimeout: '5',
inputType:'dtmf',
redirect:'true'
}
getinput = r.addGetInput(params)
getinput.addSpeak($question1)
r.addSpeak($noinput_message)
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
def firstbranch
digit = params[:Digits]
r = Response.new()
if (digit == "1")
getinput_action_url = "https://.com/ivr/secondbranch/"
params = {
action: getinput_action_url,
method: 'POST',
digitEndTimeout: '5',
inputType:'dtmf',
redirect:'true'
}
getinput = r.addGetInput(params)
getinput.addSpeak($question2)
r.addSpeak($noinput_message)
elsif (digit == "2")
r.addSpeak($negative_feedback)
else
r.addSpeak($wronginput_message)
end
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
def secondbranch
digit = params[:Digits]
r = Response.new()
if (digit == "1")
body = "Thank you for participating in the survey"
params = {
'language'=> "en-GB"
}
r.addSpeak(body,params)
elsif (digit == "2")
r.addSpeak($negative_feedback)
else
r.addSpeak($wronginput_message)
end
xml = PlivoXML.new(r)
render xml: xml.to_xml
end
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `ENV` to store environment variables and fetch them when initializing the client.
### Add a route
Add a route for the inbound function in the PlivoController class. Edit config/routes.rb and add these lines after the inbound route.
```shell theme={null}
get 'plivo/survey'
get 'plivo/firstbranch'
get 'plivo/secondbranch'
```
Start the Rails server.
```shell theme={null}
$ rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/survey/](http://localhost:3000/plivo/survey/).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a voice survey application in PHP
Create a file called `survey.py` and paste into it this code.
```py theme={null}
# -*- coding: utf-8 -*-
from flask import Flask, Response, request, url_for
from plivo import plivoxml
# Message that Plivo reads when the call recipient answers
question1 = "Hi, this is a call from Plivo. How would you rate your overall satisfaction with our services? Press 1 if you're satisfied or 2 to suggest improvements"
question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied or 2 to suggest improvements"
# Message that Plivo reads when the recipient provides negative feedback
negative_feedback = "We're sorry about your bad experience, One of our representatives will get in touch with you"
# Message that Plivo reads when the caller does nothing
noinput_message = "Sorry, I didn't catch that. Please hang up and try again"
# Message that Plivo reads when the caller enters an invalid number
wronginput_message = "Sorry, that's not a valid entry"
app = Flask(__name__)
@app.route('/survey/', methods=['GET','POST'])
def ivr():
response = plivoxml.ResponseElement()
getinput_action_url = "https://.com/firstbranch/"
response.add(plivoxml.GetInputElement().
set_action(getinput_action_url).
set_method('POST').
set_input_type('dtmf').
set_digit_end_timeout(5).
set_redirect(True).add(
plivoxml.SpeakElement(question1)))
response.add(plivoxml.SpeakElement(noinput_message))
return Response(response.to_string(), mimetype='application/xml')
@app.route('/survey/firstbranch/', methods=['GET','POST'])
def firstbranch():
response = plivoxml.ResponseElement()
digit = request.values.get('Digits')
if digit == "1":
# Read out a text.
getinput_action_url = "https://.com/secondbranch/"
response.add(plivoxml.GetInputElement().
set_action(getinput_action_url).
set_method('POST').
set_input_type('dtmf').
set_digit_end_timeout(5).
set_redirect(True).add(
plivoxml.SpeakElement(question2)))
response.add(plivoxml.SpeakElement(noinput_message))
elif digit == "2":
response.add_speak(negative_feedback)
else:
response.add_speak(wronginput_message)
return Response(response.to_string(), mimetype='application/xml')
@app.route('/ivr/secondbranch/', methods=['GET','POST'])
def secondbranch():
response = plivoxml.ResponseElement()
digit = request.values.get('Digits')
if digit == "1":
text = u"Thank you for participating in the survey"
params = {
'language': "en-GB",
}
response.add_speak(text,**params)
elif digit == "2":
response.add_speak(negative_feedback)
else:
response.add_speak(wronginput_message)
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `os module(os.environ)` to store environment variables and fetch them when initializing the client.
Save the file and run it.
```shell theme={null}
python survey.py
```
You should see your basic server application in action at [http://localhost:5000/survey/](http://localhost:5000/survey/).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a voice survey application in PHP
Change to the project directory and run this command to create a Laravel controller.
```shell theme={null}
$ php artisan make:controller SurveyController
```
This generates a controller named SurveyController in the app/http/controllers/ directory. Edit app/http/controllers/SurveyController.php and add this code.
```php theme={null}
.com/firstbranch.php";
$get_input = $r->addGetInput([
'action' => $getinput_action_url,
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($Question1);
$r->addSpeak($NoinputMessage);
Header('Content-type: text/xml');
echo $r->toXML();
}
// Action URL block for DTMF
public function firstBranch(Request $request)
{
$Question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied or 2 to suggest improvements";
// Message that Plivo reads when the recipient provides negative feedback
$NegativeFeedback = "We're sorry about your bad experience, One of our representatives will get in touch with you";
// Message that Plivo reads when the caller does nothing
$NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
$WronginputMessage = "Sorry, that's not a valid entry";
$r = new Response();
$digit = $_REQUEST['Digits'];
if ($digit == '1'){
$getinput_action_url = "https://.com/secondbranch.php";
$get_input = $r->addGetInput([
'action' => $getinput_action_url,
'method' => "POST",
'digitEndTimeout' => "5",
'inputType' => "dtmf",
'redirect' => "true",
]);
$get_input->addSpeak($Question2);
$r->addSpeak($NoinputMessage);
}
else if ($digit == '2'){
$r->addSpeak($NegativeFeedback);
}
else {
$r->addSpeak($WronginputMessage);
}
Header('Content-type: text/xml');
echo $r->toXML();
}
// Action URL block for Sales and Support branch
public function secondBranch(Request $request)
{
// Message that Plivo reads when the recipient provides negative feedback
$NegativeFeedback = "We're sorry about your bad experience, One of our representatives will get in touch with you";
// Message that Plivo reads when the caller enters a wrong number
$WronginputMessage = "Sorry, that's not a valid entry";
$r = new Response();
$digit = $_REQUEST['Digits'];
if ($digit == '1'){
$body = "Thank you for participating in the survey";
$params = array(
'language' => "en-GB"
);
$r->addSpeak($body,$params);
}
else if ($digit == '2'){
$r->addSpeak($NegativeFeedback);
}
else {
$r->addSpeak($WronginputMessage);
}
Header('Content-type: text/xml');
echo $r->toXML();
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch them from the environment variables. You can use `$_ENV` or `putenv/getenv` functions to store environment variables and fetch them when initializing the client.
### Add a route
Add a route for the forward function in the SurveyController class. Edit routes/web.php and add these lines.
```shell theme={null}
Route::match(['get', 'post'], '/survey', 'SurveyController@ivrMain');
Route::match(['get', 'post'], '/firstbranch', 'SurveyController@firstBranch');
Route::match(['get', 'post'], '/secondbranch', 'SurveyController@secondBranch');
```
Start the Laravel server.
```shell theme={null}
$ php artisan serve
```
You should see your basic server application in acation at [http://localhost:8000/survey](http://localhost:8000/survey).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create a voice survey application in C\#
In Visual Studio, create a controller called `SurveyController.cs` and paste into it this code.
```cs theme={null}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Plivo.XML;
namespace Receivecall.Controllers
{
public class SurveyController : Controller
{
// Message that Plivo reads when the call recipient answers
String Question1 = "Hi, this is a call from Plivo. How would you rate your overall satisfaction with our services? Press 1 if you're satisfied. Press 2 to suggest improvements";
String Question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied. Press 2 to suggest improvements";
// Message that Plivo reads when the recipient provides negative feedback
String NegativeFeedback = "We're sorry about your bad experience. One of our representatives will get in touch with you";
// Message that Plivo reads when the caller does nothing
String NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
String WronginputMessage = "Sorry, that's not a valid entry";
// GET: // -12/
public IActionResult Index()
{
var resp = new Response();
Plivo.XML.GetInput get_input = new
Plivo.XML.GetInput("",
new Dictionary()
{
{"action", "https://.com/survey/firstbranch/"},
{"method", "POST"},
{"digitEndTimeout", "5"},
{"inputType", "dtmf"},
{"redirect", "true"},
});
resp.Add(get_input);
get_input.AddSpeak(Question1,
new Dictionary() { });
resp.AddSpeak(NoinputMessage,
new Dictionary() { });
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// First branch of IVR phone tree
public IActionResult FirstBranch()
{
String digit = Request.Query["Digits"];
Debug.WriteLine("Digit pressed : {0}", digit);
var resp = new Response();
if (digit == "1")
{
String getinput_action_url = "https://.com/survey/secondbranch/";
// Add GetInput XML Tag
Plivo.XML.GetInput get_input = new
Plivo.XML.GetInput("",
new Dictionary()
{
{"action", getinput_action_url},
{"method", "POST"},
{"digitEndTimeout", "5"},
{"finishOnKey", "#"},
{"inputType", "dtmf"},
{"redirect", "true"},
});
resp.Add(get_input);
get_input.AddSpeak(Question2,
new Dictionary() { });
resp.AddSpeak(NoinputMessage,
new Dictionary() { });
}
else if (digit == "2")
{
// Add Speak XML Tag
resp.AddSpeak(NegativeFeedback,
new Dictionary() { });
}
else
{
// Add Speak XML Tag
resp.AddSpeak(WronginputMessage,
new Dictionary() { });
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
// Second branch of IVR phone tree
public IActionResult SecondBranch()
{
var resp = new Response();
String digit = Request.Query["Digits"];
Debug.WriteLine("Digit pressed : {0}", digit);
// Add Speak XMLTag
if (digit == "1")
{
resp.AddSpeak("Thank you for participating in the survey",
new Dictionary()
{
{ "language","en-GB"}
});
}
else if (digit == "2")
{
// Add Speak XML Tag
resp.AddSpeak(NegativeFeedback,
new Dictionary() { });
}
else
{
resp.AddSpeak(WronginputMessage,
new Dictionary() { });
}
Debug.WriteLine(resp.ToString());
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use the `Environment.SetEnvironmentVariable` method to store environment variables and `Environment.GetEnvironmentVariable` to fetch them when initializing the client.
Before starting the application, edit Properties/launchSettings.json and set the applicationUrl as
```json theme={null}
"applicationUrl": "http://localhost:5000/"
```
Run the project and you should see your basic server application in action at [http://localhost:5000/survey/](http://localhost:5000/survey/).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a voice survey application in Java
Create a Java class called `Survey` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.GetInput;
import com.plivo.api.xml.Play;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
public class IVR {
public static void main(String[] args) {
// Message that Plivo reads when the call recipient answers
String Question1 = "Hi, this is a call from Plivo. How would you rate your overall satisfaction with our services? Press 1 if you're satisfied or 2 to suggest improvements";
String Question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied or 2 to suggest improvements";
// Message that Plivo reads when the recipient provides negative feedback
String NegativeFeedback = "We're sorry about your bad experience. One of our representatives will get in touch with you";
// Message that Plivo reads when the caller does nothing
String NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again";
// Message that Plivo reads when the caller enters an invalid number
String WronginputMessage = "Sorry, that's not a valid entry";
post("/survey/", (request, response) -> {
response.type("application/xml");
Response resp = new Response();
resp.children(
new GetInput()
.action("https://.com/ivr/firstbranch/")
.method("POST")
.inputType("dtmf")
.digitEndTimeout(5)
.redirect(true)
.children(
new Speak(Question1)
)
);
resp.children(new Speak(NoinputMessage));
return resp.toXmlString();
});
post("/survey/firstbranch/", (request, response) -> {
response.type("application/xml");
String digit = request.queryParams("Digits");
Response resp = new Response();
if (digit.equals("1")){
resp.children(
new GetInput()
.action("https://.com/ivr/secondbranch/")
.method("POST")
.inputType("dtmf")
.digitEndTimeout(5)
.redirect(true)
.children(
new Speak(Question2)
)
);
resp.children(new Speak(NoinputMessage));
}
else if (digit.equals("2")){
resp.children(
new Speak(NegativeFeedback)
);
}
else {
resp.children(
new Speak(WronginputMessage)
);
}
return resp.toXmlString();
});
post("/survey/secondbranch/", (request, response) -> {
response.type("application/xml");
String digit = request.queryParams("Digits");
Response resp = new Response();
if (digit.equals("1")){
resp.children(
new Speak("Thank you for participating in the survey", "MAN","en-GB",1)
);
}
else if (digit.equals("2")){
resp.children(
new Speak(NegativeFeedback)
);
}
else {
resp.children(
new Speak(WronginputMessage)
);
}
return resp.toXmlString();
});
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `System.getenv()` to store environment variables and retrieve them when initializing the client.
Save the file and run it. You should see your basic server application in action at [http://localhost:4567/survey/](http://localhost:4567/survey/).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
## Overview
Plivo lets you automate voice surveys for use cases such as collecting feedback from customers and conducting polling on political issues. You can set up multiple levels of questions and walk users through different paths depending on the keys they press in response to your questions, and save the responses for analysis.
You can implement voice surveys either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to use Plivo APIs and XML to implement voice surveys.
## How it works
Plivo requests an answer URL when the call is answered (step 4) and expects the file at that address to hold a valid XML response from the application with instructions on how to handle the call.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a voice survey application in Go
Create a file called `survey.go` and paste into it this code.
```go theme={null}
package main
import (
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
m := martini.Classic()
const
(
// Message that Plivo reads when the call recipient answers
Question1 = "Hi, this is a call from Plivo. How would you rate your overall satisfaction with our services? Press 1 if you're satisfied or 2 to suggest improvements"
Question2 = "How would you rate your satisfaction with our customer service? Press 1 if you're satisfied or 2 to suggest improvements"
// Message that Plivo reads when the recipient provides negative feedback
NegativeFeedback = "We're sorry about your bad experience. One of our representatives will get in touch with you"
// Message that Plivo reads when the caller does nothing
NoinputMessage = "Sorry, I didn't catch that. Please hang up and try again"
// Message that Plivo reads when the caller enters an invalid number
WronginputMessage = "Sorry, that's not a valid entry"
)
m.Post("/survey/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.GetInputElement).
SetAction("https://.com/ivr/firstbranch/").
SetMethod("POST").
SetDigitEndTimeout(5).
SetInputType("dtmf").
SetRedirect(true).
SetContents([]interface{}{new(xml.SpeakElement).
AddSpeak(Question1),
}),
new(xml.SpeakElement).
AddSpeak(NoInputMessage),
},
}
return response.String()
})
m.Post("/survey/firstbranch/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
digit := r.FormValue("Digits")
if digit == "1" {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.GetInputElement).
SetAction("https://.com/ivr/firstbranch/").
SetMethod("POST").
SetDigitEndTimeout(5).
SetInputType("dtmf").
SetRedirect(true).
SetContents([]interface{}{new(xml.SpeakElement).
AddSpeak(Question2),
}),
new(xml.SpeakElement).
AddSpeak(NoInputMessage),
},
}.String()
} else if digit == "2" {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak(NegativeFeedback),
},
}.String()
} else {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak(WrongInputMessage),
},
}.String()
}
})
m.Post("/survey/secondbranch/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
digit := r.FormValue("Digits")
if digit == "1" {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
SetLanguage("en-GB").
AddSpeak("Thank you for participating in the survey"),
},
}.String()
} else if digit == "2" {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak(NegativeFeedback),
},
}.String()
} else {
return xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak(WrongInputMessage),
},
}.String()
}
})
m.Run()
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note:We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `os.Setenv` and `os.Getenv` functions to store environment variables and fetch them when initializing the client.
Save the file and run it.
```shell theme={null}
go run survey.go
```
You should see your basic server application in action at [http://localhost:8080/survey/](http://localhost:8080/survey/).
Set up ngrok to expose your local server to the internet.
## Test
Make a call to a Plivo phone number and see how the survey application works.
# Voicemail
Source: https://plivo.com/docs/voice/use-cases/voicemail
Set up voicemail to capture caller messages when recipients are unavailable
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to implement voicemail
Create a file called `voicemail.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.set('port', (process.env.PORT || 5000));
app.post('/voicemail/', function(request, response) {
var r = plivo.Response();
var params;
params = {
'action': "https://.com/get_recording/",
'finishOnKey': "*",
'maxLength': "20"
};
r.addRecord(params);
var second_speak_body = "Recording not received";
r.addSpeak(second_speak_body);
console.log(r.toXML());
response.set({'Content-Type': 'text/xml'});
response.send(r.toXML());
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Save the file and run it.
```shell theme={null}
$ node voicemail.js
```
You should see your basic server application in action at [http://localhost:3000/voicemail/](http://localhost:3000/voicemail/).
## Create a Plivo application for voicemail
Associate the Express server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to implement voicemail
Change to the project directory and run this command to create a Rails controller for inbound calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This command generates a controller named plivo\_controller in the app/controllers/ directory and a respective view in app/views/plivo. We can delete the view as we do not need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and paste this code into the PlivoController class.
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
def voicemail
response = Response.new
first_speak_body = 'Please leave a message after the beep. Press the star key when done.'
response.addSpeak(first_speak_body)
params = {
action: 'https://www.foo.com/get_recording/',
maxLength: '30',
finishOnKey: '*'
}
response.addRecord(params)
second_speak_body = 'Recording not received.'
response.addSpeak(second_speak_body)
xml = PlivoXML.new(response)
render xml: xml.to_xml
end
end
```
### Add a route
To add a route for the inbound function in the PlivoController class, edit config/routes.rb and add this line after the inbound route.
```shell theme={null}
get 'plivo/voicemail'
```
Start the Rails server
```shell theme={null}
$ rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/voicemail/](http://localhost:3000/plivo/voicemail/).
## Create a Plivo application for voicemail
Associate the Rails controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask server to implement voicemail
Create a file called `voicemail.py` and paste into it this code.
```py theme={null}
# -*- coding: utf-8 -*-
from flask import Flask, Response, request, url_for
from plivo import plivoxml
app = Flask(__name__)
@app.route('/voicemail/', methods=['GET','POST'])
def voicemail():
response = plivoxml.ResponseElement()
response.add(
plivoxml.SpeakElement(
'Please leave a message. Press the star key when you\'re done'))
response.add(
plivoxml.RecordElement(
action='https://.com/get_recording/',
max_length=30,
finish_on_key='*'))
response.add(plivoxml.SpeakElement('Recording not received'))
return Response(response.to_string(), mimetype='application/xml')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Save the file and run it.
```shell theme={null}
$ python voicemail.py
```
You should see your basic server application in action at [http://localhost:5000/voicemail/](http://localhost:5000/voicemail/).
## Create a Plivo application for voicemail
Associate the Flask server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to implement voicemail
Change to the project directory run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller VoicemailController
```
This generate a controller named VoicemailController in the app/http/controllers/ directory. Edit app/http/controllers/VoicemailController.php and paste into it this code.
```php theme={null}
addSpeak($first_speak_body);
$params = array(
'action' => "https://.com/get_recording/",
'finishOnKey' => "*",
'maxLength' => "20"
);
$response->addRecord($params);
$second_speak_body = "Recording not received";
$response->addSpeak($second_speak_body);
Header('Content-type: text/xml');
echo $r->toXML();
}
}
```
### Add a route
To add a route for the inbound function in the VoicemailController class, edit routes/web.php file and add this line.
```shell theme={null}
Route::match(['get', 'post'], '/voicemail', 'VoicemailController@voicemailMain');
```
Start the Laravel server.
```shell theme={null}
$ php artisan serve
```
You should see your basic server application in action at [http://localhost:8000/voicemail](http://localhost:8000/voicemail).
## Create a Plivo application for voicemail
Associate the Laravel controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to implement voicemail
In Visual Studio, create a controller called `VoicemailController.cs` and paste into it this code.
```cs theme={null}
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace Receivecall.Controllers
{
public class VoicemailController : Controller
{
// GET: //
public IActionResult Index()
{
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddSpeak("Please leave a message. Press the star key when you're done",
new Dictionary() { });
resp.AddRecord(new Dictionary() {
{"action", "https://.com/get_recording/"},
{"finishOnKey", "*"},
{"maxLength", "20"},
{"playBeep", "true"},
{"timeout", "15"}
});
resp.AddSpeak("Recording not received",
new Dictionary() { });
var output = resp.ToString();
return this.Content(output, "text/xml");
}
}
}
```
Save the file. Edit Properties/launchSettings.json and set the applicationUrl.
"applicationUrl": "[http://localhost:5000/](http://localhost:5000/)"
Run the project and you should see your basic server application in action at [http://localhost:5000/voicemail/](http://localhost:5000/voicemail/).
## Create a Plivo application for voicemail
Associate the MVC controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spark application to implement voicemail
Create a Java class called `Voicemail` and paste into it this code.
```java theme={null}
import static spark.Spark.*;
import com.plivo.api.xml.GetInput;
import com.plivo.api.xml.Play;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
public class Voicemail {
public static void main(String[] args) {
post("/voicemail/", (request, response) -> {
response.type("application/xml");
Response response = new Response()
.children(
new Speak("Please leave a message. Press the star key when you're done"),
new Record("https://.com/get_recording/")
.finishOnKey("*")
.maxLength(20),
new Speak("Recording not received")
);
resp.children(new Speak(NoinputMessage));
return resp.toXmlString();
});
}
}
```
Save the project and run it. You should see your basic server application in action at [http://localhost:4567/voicemail/](http://localhost:4567/voicemail/).
## Create a Plivo application for voicemail
Associate the Spark application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
## Overview
You can use voicemail to capture a caller’s message if a call recipient is unavailable. This guide shows how to set up voicemail, either by using our PHLO visual workflow builder or our APIs and XML documents. Follow the instructions in one of the tabs below.
Here’s how to implement voicemail using XML.
## How it works
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice-enabled Plivo phone number to receive incoming calls; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to implement voicemail
Create a file called `voicemail.go` and paste into it this code.
```go theme={null}
package main
import (
"github.com/go-martini/martini"
"github.com/plivo/plivo-go/v7/xml"
"net/http"
)
func main() {
m := martini.Classic()
m.Post("/voicemail/", func(w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak("Please leave a message. Press the star key when you're done"),
new(xml.RecordElement).
SetAction("https://.com/get_recording/").
SetFinishOnKey("*").
SetMaxLength(20),
new(xml.SpeakElement).
AddSpeak("Recording not received"),
},
}
return response.String()
})
m.Run()
}
```
Save the file and run it.
```shell theme={null}
$ go run voicemail.go
```
You should see your basic server application in action at [http://localhost:8080/voicemail/](http://localhost:8080/voicemail/).
## Create a Plivo application for voicemail
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `GET`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message.
# Voicemail Transcription
Source: https://plivo.com/docs/voice/use-cases/voicemail-transcription
Transcribe voicemail messages and deliver transcriptions via SMS
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Node.js development environment and a web server and safely expose that server to the internet.
## Create an Express server to implement voicemail transcription
Create a file called `voicemail.js` and paste into it this code.
```js theme={null}
var plivo = require('plivo');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.set('port', (process.env.PORT || 5000));
app.post('/voicemail/', function(request, response) {
var res = plivo.Response();
res.addSpeak('Please leave a message. Press the star key when you\'re done');
var params = {
'transcriptionType': 'auto',
'transcriptionUrl': request.protocol + '://' + request.headers.host + '/transcription-url/',
'action': request.protocol + '://' + request.headers.host + '/action-url/',
'finishOnKey': "*",
'maxLength': "20"
};
res.addRecord(params);
res.addSpeak('Recording not received');
response.set({
'Content-Type': 'text/xml'
});
response.send(res.toXML());
});
app.post('/transcription-url/', function(request, response) {
console.log(request.body);
var client = new plivo.Client("", "");
client.messages.create(
{
src: "",
dst: "",
text: "You have a new transcription: "+ request.body.transcription,
}).then(function(message_created) {
console.log(message_created)
});
response.status(200).send('OK')
});
app.post('/action-url/', function(request, response) {
console.log(request.body);
response.status(200).send('OK')
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `process.env` to store environment variables and fetch them when initializing the client.
Save the file and run it.
```shell theme={null}
$ node voicemail.js
```
You should see your basic server application in action at [http://localhost:3000/voicemail/](http://localhost:3000/voicemail/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application for voicemail transcription
Associate the Express server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Ruby development environment and a web server and safely expose that server to the internet.
## Create a Rails controller to implement voicemail transcription
Change to the project directory and run this command to create a Rails controller for inbound calls.
```shell theme={null}
$ rails generate controller Plivo voice
```
This command generates a controller named plivo\_controller in the app/controllers/ directory and a respective view in app/views/plivo. We can delete the view as we do not need it.
```shell theme={null}
$ rm app/views/plivo/voice.html.erb
```
Edit app/controllers/plivo\_controller.rb and paste this code into the PlivoController class.
```ruby theme={null}
include Plivo
include Plivo::XML
include Plivo::Exceptions
class PlivoController < ApplicationController
skip_before_action :verify_authenticity_token
def voicemail
response = Response.new
response.addSpeak('Please leave a message after the beep. Press the star key when you\'re done.')
params = {
transcriptionType: 'auto',
transcriptionUrl: url_for(action: 'transcriptionUrl', controller: 'plivo', only_path: false, protocol: 'https'),
action: url_for(action: 'actionUrl', controller: 'plivo', only_path: false, protocol: 'https'),
maxLength: '30',
finishOnKey: '*'
}
response.addRecord(params)
second_speak_body = 'Recording not received.'
response.addSpeak(second_speak_body)
xml = PlivoXML.new(response)
render xml: xml.to_xml
end
def transcriptionUrl
response = params
api = RestClient.new("","")
message_response = api.messages.create(
src: "",
dst: "",
text: "You have a new transcription: "+params[:transcription]
)
puts message_response
puts response
render status: :ok, json: @controller.to_json
end
def actionUrl
response = params
puts response
render status: :ok , json: @controller.to_json
end
end
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
### Add a route
To add a route for the inbound function in the PlivoController class, edit config/routes.rb and add this line after the inbound route.
```shell theme={null}
post 'plivo/voicemail'
post 'plivo/transcriptionUrl'
post 'plivo/actionUrl'
```
Start the Rails server
```shell theme={null}
$ rails server
```
You should see your basic server application in action at [http://localhost:3000/plivo/voicemail/](http://localhost:3000/plivo/voicemail/).
Set up ngrok to expose your local server to the internet.
Note: For ngrok testing, add this line to config/environments/development.rb.
`config.hosts << /[a-z0-9-]+\.ngrok\.io/`
## Create a Plivo application for voicemail transcription
Associate the Rails controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment and a web server and safely expose that server to the internet.
## Create a Flask server to implement voicemail transcription
Create a file called `voicemail.py` and paste into it this code.
```py theme={null}
from flask import Flask, Response, url_for, request
import json
import plivo
from plivo import plivoxml
app = Flask(__name__)
@app.route('/voicemail/', methods=['GET', 'POST'])
def voicemail():
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement("Please leave a message. Press the star key when you\'re done"))
response.add(plivoxml.RecordElement(transcription_type='auto',
transcription_url=url_for('transcription_url',
_external=True), action=url_for('action_url',
_external=True), max_length=30, finish_on_key='*'))
response.add(plivoxml.SpeakElement('Recording not received'))
return Response(response.to_string(), mimetype='application/xml')
@app.route('/transcription-url/', methods=['GET', 'POST'])
def transcription_url():
form_values = json.dumps(request.form, indent=4)
print form_values
client = plivo.RestClient('', '')
response = client.messages.create(src='',
dst='',
text='You have a new transcription: '+ request.form['transcription'])
print response
return ('OK', 200)
@app.route('/action-url/', methods=['GET', 'POST'])
def action_url():
form_values = json.dumps(request.form, indent=4)
print form_values
return ('OK', 200)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `os module(os.environ)` to store environment variables and fetch them when initializing the client.
Save the file and run it.
```shell theme={null}
$ python voicemail.py
```
You should see your basic server application in action at [http://localhost:5000/voicemail/](http://localhost:5000/voicemail/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application for voicemail transcription
Associate the Flask server you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a PHP development environment and a web server and safely expose that server to the internet.
## Create a Laravel controller to implement voicemail transcription
Change to the project directory run this command to create a Laravel controller for inbound calls.
```shell theme={null}
$ php artisan make:controller VoicemailController
```
This generate a controller named VoicemailController in the app/http/controllers/ directory. Edit app/http/controllers/VoicemailController.php and paste into it this code.
```php theme={null}
getHttpHost();
$response = new Response();
$response->addSpeak("Please leave a message. Press the star key when you're done");
$params = array(
'transcriptionType'=>"auto",
'transcriptionUrl'=>"https://".$host."/transcriptionUrl",
'action' => "https://".$host."/actionUrl",
'finishOnKey' => "*",
'maxLength' => "20"
);
$response->addRecord($params);
$second_speak_body = "Recording not received";
$response->addSpeak($second_speak_body);
Header('Content-type: text/xml');
echo ($response->toXML());
}
public function actionUrl(Request $request)
{
return $request->all();
}
public function transcriptionUrl(Request $request)
{
$client = new RestClient("","");
$response = $client->messages->create(
[
"src" => "",
"dst" => "",
"text" =>"You have a new transcription: ".$_REQUEST["transcription"],
]
);
print_r($response);
return $request->all();
}
}
```
### Add a route
To add a route for the inbound function in the VoicemailController class, edit routes/web.php file and add this line.
```shell theme={null}
Route::match(['get', 'post'], '/voicemail', 'App\Http\Controllers\VoicemailController@voicemailMain');
Route::match(['get', 'post'], '/actionUrl', 'App\Http\Controllers\VoicemailController@actionUrl');
Route::match(['get', 'post'], '/transcriptionUrl', 'App\Http\Controllers\VoicemailController@transcriptionUrl');
```
Start the Laravel server.
```shell theme={null}
$ php artisan serve
```
You should see your basic server application in action at [http://localhost:8000/voicemail](http://localhost:8000/voicemail).
Set up ngrok to expose your local server to the internet.
Note: For ngrok test, add this line to mylaravelapp/quickstart/app/Http/Middleware/VerifyCsrfToken.php.
`protected $except = ['*'];`
## Create a Plivo application for voicemail transcription
Associate the Laravel controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a .NET development environment and a web server and safely expose that server to the internet.
## Create an MVC controller to implement voicemail transcription
In Visual Studio, create a controller called `VoicemailController.cs` and paste into it this code.
```cs theme={null}
using System;
using Plivo;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace VoiceApp.Controllers
{
public class Voicemail : Controller
{
public IActionResult Index()
{
var hostName = Request.HttpContext.Request.Host.Value;
Plivo.XML.Response resp = new Plivo.XML.Response();
resp.AddSpeak("Please leave a message. Press the star key when you're done",
new Dictionary() { });
resp.AddRecord(new Dictionary() {
{"transcriptionType","auto" },
{"transcriptionUrl","https://" + hostName + "/Voicemail/TranscriptionUrl/" },
{"action", "https://" + hostName + "/Voicemail/ActionUrl/"},
{"finishOnKey", "*"},
{"maxLength", "20"},
});
resp.AddSpeak("Recording not received",
new Dictionary() { });
var output = resp.ToString();
return this.Content(output, "text/xml");
}
public IActionResult ActionUrl()
{
Console.WriteLine(Request.Form);
return this.Content("OK");
}
public IActionResult TranscriptionUrl()
{
Console.WriteLine(Request.Form);
var api = new PlivoApi("", "");
var response = api.Message.Create(
src: "",
dst: new List { "" },
text: "You have a new transcription: "+ Request.Form["transcription"]
);
Console.WriteLine(response);
return this.Content("OK");
}
}
}
```
Save the file. Edit Properties/launchSettings.json and set the applicationUrl.
```json theme={null}
"applicationUrl": "http://localhost:5000/"
```
Run the project and you should see your basic server application in action at [http://localhost:5000/voicemail/](http://localhost:5000/voicemail/).
## Create a Plivo application for voicemail transcription
Associate the MVC controller you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Java development environment and a web server and safely expose that server to the internet.
## Create a Spring application to implement voicemail transcription
Create a Java class called `VoicemailApplication` and paste into it this code.
```java theme={null}
package com.example.voicemail;
import com.plivo.api.Plivo;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.exceptions.PlivoValidationException;
import com.plivo.api.exceptions.PlivoXmlException;
import com.plivo.api.models.message.Message;
import com.plivo.api.models.message.MessageCreateResponse;
import com.plivo.api.xml.Record;
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@RestController
@SpringBootApplication
public class VoicemailApplication {
public static void main(String[] args) {
SpringApplication.run(VoicemailApplication.class, args);
}
@PostMapping(value = "/voicemail", produces = {"text/xml"})
public String voiceMail(HttpServletRequest request) throws PlivoXmlException, PlivoValidationException {
String hostName = request.getRequestURL().toString();
Response response = new Response()
.children(
new Speak("Please leave a message. Press the star key when you're done"),
new Record(hostName + "action-url")
.transcriptionType("auto")
.transcriptionUrl(hostName + "transcription-url")
.finishOnKey("*")
.maxLength(20));
response.children(new Speak("Recording not received"));
return response.toXmlString();
}
@PostMapping("voicemail/transcription-url")
@ResponseStatus(code = HttpStatus.OK)
public String TranscriptionBody(String call_uuid, String duration, String recording_id, String transcription, String transcription_charge, String transcription_rate) {
System.out.println("callUuid:"+ call_uuid + "\n" + "duration:"+duration + "\n" + "recordingId:"+recording_id +"\n"+ "transcription:"+transcription + "\n" + "transcriptionCharge:"+transcription_charge + "\n" + "transcription_rate:"+transcription_rate + "\n");
Plivo.init("","");
try {
MessageCreateResponse response = Message.creator("", "",
"You have a new transcription: "+transcription)
.create();
System.out.println(response);
}
catch (PlivoRestException | IOException e)
{
e.printStackTrace();
}
return "OK";
}
@PostMapping("voicemail/action-url")
@ResponseStatus(code = HttpStatus.OK)
public String ActionBody(String BillRate,String CallStatus,String CallUUID,String CallerName,String Digits,String Direction,String Event,String From,String ParentAuthID,String RecordFile,String RecordUrl,String RecordingDuration,String RecordingDurationMs,String RecordingEndMs,String RecordingID,String RecordingStartMs,String SessionStart,String To) {
System.out.println("billRate:"+ BillRate+"\n"+"callStatus:"+ CallStatus+"\n"+"callUUID:"+ CallUUID+"\n"+"callerName:"+ CallerName+"\n"+"digits:"+ Digits+"\n"+"direction:"+ Direction+"\n"+"event:"+ Event+"\n"+"From:"+ From+"\n"+"parentAuthID:"+"\n"+ParentAuthID+"\n"+"recordFile:"+ RecordFile+"\n"+"recordUrl:"+ RecordUrl+"\n"+"recordingDuration:"+ RecordingDuration+"\n"+"recordingDurationMs:"+ RecordingDurationMs+"\n"+"recordingEndMs:"+ RecordingEndMs+"\n"+"recordingID:"+ RecordingID+"\n"+"recordingStartMs:"+ RecordingStartMs+"\n"+"sessionStart:"+ SessionStart+"\n"+"To:"+ To);
return "OK";
}
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
Note: We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use [System.getenv()](https://docs.oracle.com/javase/tutorial/essential/environment/env.html) to store environment variables and retrieve them when initializing the client.
Save the project and run it. You should see your basic server application in action at [http://localhost:8080/voicemail/](http://localhost:8080/voicemail/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application for voicemail transcription
Associate the Spring application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
## Overview
This guide shows how to transcribe voicemail and send the transcription via SMS.
## Prerequisites
To get started, you need a Plivo account — [sign up](https://cx.plivo.com/signup) with your work email address if you don’t have one already. You must have a voice- and SMS-enabled Plivo phone number to receive calls and send SMS messages; you can rent numbers from the [Numbers](https://cx.plivo.com/phone-numbers) page of the Plivo console, or by using the [Numbers API](/docs/numbers/). If this is your first time using Plivo APIs, follow our instructions to set up a Go development environment and a web server and safely expose that server to the internet.
## Create a Go server to implement voicemail transcription
Create a file called `voicemail.go` and paste into it this code.
```go theme={null}
package main
import (
"fmt"
"log"
"strings"
"github.com/gin-gonic/gin"
"github.com/plivo/plivo-go"
"github.com/plivo/plivo-go/v7/xml"
)
func main() {
r := gin.Default()
r.POST("/voicemail", func(c *gin.Context) {
c.Header("Content-Type", "application/xml")
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).
AddSpeak("Please leave a message. Press the star key when you're done"),
new(xml.RecordElement).
SetTranscriptionType("auto").
SetTranscriptionUrl("https://" + c.Request.Host + "/transcription-url").
SetAction("https://" + c.Request.Host + "/action-url").
SetFinishOnKey("*").
SetMaxLength(20),
new(xml.SpeakElement).
AddSpeak("Recording not received"),
},
}
c.String(200, response.String())
})
r.POST("/transcription-url", func(c *gin.Context) {
c.Header("Content-Type", "application/xml")
c.MultipartForm()
for key, value := range c.Request.PostForm {
log.Printf("%v = %v \n", key, value)
}
client, err := plivo.NewClient("", "", &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := client.Messages.Create(
plivo.MessageCreateParams{
Src: "",
Dst: "",
Text: strings.Join(c.Request.PostForm["transcription"], "You have a new transcription"),
},
)
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
})
r.POST("/action-url", func(c *gin.Context) {
c.Header("Content-Type", "application/xml")
c.MultipartForm()
for key, value := range c.Request.PostForm {
log.Printf("%v = %v \n", key, value)
}
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
```
Replace the auth placeholders with your authentication credentials from the [Plivo console](https://cx.plivo.com/home). Replace the phone number placeholders with actual phone numbers in [E.164 format](https://en.wikipedia.org/wiki/E.164) (for example, +12025551234).
We recommend that you store your credentials in the `auth_id` and `auth_token` environment variables, to avoid the possibility of accidentally committing them to source control. If you do this, you can initialize the client with no arguments and Plivo will automatically fetch the values from the environment variables. You can use `os.Setenv` and `os.Getenv` functions to store environment variables and fetch them when initializing the client.
Save the file and run it.
```shell theme={null}
$ go run voicemail.go
```
You should see your basic server application in action at [http://localhost:8080/voicemail/](http://localhost:8080/voicemail/).
Set up ngrok to expose your local server to the internet.
## Create a Plivo application for voicemail transcription
Associate the Go application you created with Plivo by creating a Plivo application. Visit Voice > [Applications](https://cx.plivo.com/xml-applications) in the Plivo console and click on **Add New Application**, or use Plivo’s [Application API](/docs/account/api/application/#create-an-application).
Give your application a name — we called ours `Voicemail-Transcription`. Enter the server URL you want to use (for example `https://.com/voicemail/`) in the `Answer URL` field and set the method to `POST`. Click **Create Application** to save your application.
## Assign a Plivo number to your application
Navigate to the [Numbers](https://cx.plivo.com/phone-numbers) page and select the phone number you want to use for this application.
From the Application Type drop-down, select `XML Application`.
From the Plivo Application drop-down, select `Voicemail-Transcription` (the name we gave the application).
Click **Update Number** to save.
## Test
Make a call to your Plivo number and leave yourself a voicemail message. You should receive a text message with the transcription.
Note: If you’re using a Plivo Trial account, you can send SMS messages only to phone numbers that have been verified with Plivo. You can verify (sandbox) a number by going to the console’s Phone Numbers > Sandbox Numbers page.
# Audio Output
Source: https://plivo.com/docs/voice/xml/audio-output
Play audio, text-to-speech, and DTMF tones during calls
This page covers the XML elements for audio output: converting text to speech, playing audio files, and sending DTMF tones.
***
## Speak
The `` element converts text to speech and plays it to the caller. Use it for dynamic messages that can't be prerecorded.
### Basic Usage
```xml theme={null}
Hello! Welcome to our service.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Hello! Welcome to our service.'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak('Hello! Welcome to our service.');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addSpeak('Hello! Welcome to our service.')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak('Hello! Welcome to our service.');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Speak;
Response response = new Response()
.children(new Speak("Hello! Welcome to our service."));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddSpeak("Hello! Welcome to our service.");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).AddSpeak("Hello! Welcome to our service."),
},
}
print(response.String())
}
```
### Speak Attributes
| Attribute | Type | Default | Description |
| ---------- | ------- | ------- | -------------------------------------------------- |
| `voice` | string | `WOMAN` | Voice tone. Allowed: `WOMAN`, `MAN` |
| `language` | string | `en-US` | Language for speech. See supported languages below |
| `loop` | integer | `1` | Number of times to repeat. `0` = infinite |
### Change Voice and Language
```xml theme={null}
Good day! This message uses a British male voice.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement(
'Good day! This message uses a British male voice.',
voice='MAN',
language='en-GB'
))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak('Good day! This message uses a British male voice.', {
voice: 'MAN',
language: 'en-GB'
});
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addSpeak('Good day!', voice: 'MAN', language: 'en-GB')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak('Good day!', ['voice' => 'MAN', 'language' => 'en-GB']);
echo $response->toXML();
```
### Loop a Message
Play a message multiple times:
```xml theme={null}
Please hold. Your call is important to us.
```
Set `loop="0"` to repeat indefinitely until the call ends:
```xml theme={null}
Please wait while we connect you.
```
### Supported Languages
| Language | Code | Woman | Man |
| ---------------------- | ------- | ----- | --- |
| Danish | `da-DK` | Yes | No |
| Dutch | `nl-NL` | Yes | Yes |
| English (Australian) | `en-AU` | Yes | Yes |
| English (British) | `en-GB` | Yes | Yes |
| English (USA) | `en-US` | Yes | Yes |
| French | `fr-FR` | Yes | Yes |
| French (Canadian) | `fr-CA` | Yes | No |
| German | `de-DE` | Yes | Yes |
| Italian | `it-IT` | Yes | Yes |
| Polish | `pl-PL` | Yes | Yes |
| Portuguese | `pt-PT` | No | Yes |
| Portuguese (Brazilian) | `pt-BR` | Yes | Yes |
| Russian | `ru-RU` | Yes | No |
| Spanish | `es-ES` | Yes | Yes |
| Spanish (USA) | `es-US` | Yes | Yes |
| Swedish | `sv-SE` | Yes | No |
### SSML Support
Speech Synthesis Markup Language (SSML) provides fine-grained control over pronunciation, pitch, rate, and pauses. Use Polly voices for SSML support.
```xml theme={null}
Hello and welcome to Plivo.
The word SSML
stands for Speech Synthesis Markup Language.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
speak = plivoxml.SpeakElement(
content="The word",
voice="Polly.Joey",
language="en-US"
)
speak.add_say_as("read", interpret_as="characters")
speak.add_s("may be interpreted as either the present simple form")
speak.add_w("read", role="amazon:VB")
speak.add_s("or the past participle form")
speak.add_w("read", role="amazon:VBD")
response.add(speak)
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const speakElem = response.addSpeak('The word', {
voice: 'Polly.Joey',
language: 'en-US'
});
speakElem.addSayAs('read', { 'interpret-as': 'characters' });
speakElem.addS('may be interpreted differently');
speakElem.addW('read', { role: 'amazon:VB' });
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
speak_elem = response.addSpeak('The word', voice: 'Polly.Joey', language: 'en-US')
speak_elem.addSayAs('read', 'interpret-as' => 'characters')
speak_elem.addS('may be interpreted differently')
speak_elem.addW('read', 'role' => 'amazon:VB')
puts Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak('The word', [
'language' => 'en-US',
'voice' => 'Polly.Joey'
]);
$speak_elem->addSayAs('read', ['interpret-as' => 'characters']);
$speak_elem->addS('may be interpreted differently');
echo $response->toXML();
```
#### Common SSML Tags
| Tag | Description | Example |
| ------------ | -------------------------- | ----------------------------------------------- |
| `` | Add a pause | `` |
| `` | Control pronunciation | `ABC` |
| `` | Modify pitch, rate, volume | `Slowly` |
| `` | Add emphasis | `Important` |
| `` | Paragraph pause | `
First paragraph.
` |
| `` | Sentence pause | `First sentence.` |
### Speak Nesting
`` can be nested inside:
* `` - Play message while collecting input
* `` - Play message while collecting speech/digits
* `` - Play message before answering
```xml theme={null}
Press 1 for sales, press 2 for support.
```
***
## Play
The `` element plays an audio file to the caller. Use it for pre-recorded messages, music, or sound effects.
### Basic Usage
```xml theme={null}
https://example.com/audio/welcome.mp3
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.PlayElement('https://example.com/audio/welcome.mp3'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addPlay('https://example.com/audio/welcome.mp3');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addPlay('https://example.com/audio/welcome.mp3')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addPlay('https://example.com/audio/welcome.mp3');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.Response;
import com.plivo.api.xml.Play;
Response response = new Response()
.children(new Play("https://example.com/audio/welcome.mp3"));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddPlay("https://example.com/audio/welcome.mp3");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.PlayElement).SetContents("https://example.com/audio/welcome.mp3"),
},
}
print(response.String())
}
```
### Play Attributes
| Attribute | Type | Default | Description |
| --------- | ------- | ------- | ------------------------------------------------------ |
| `loop` | integer | `1` | Number of times to play the audio. `0` = infinite loop |
### Loop Audio
Play hold music on repeat:
```xml theme={null}
https://example.com/audio/hold-music.mp3
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.PlayElement(
'https://example.com/audio/hold-music.mp3',
loop=0
))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addPlay('https://example.com/audio/hold-music.mp3', { loop: 0 });
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addPlay('https://example.com/audio/hold-music.mp3', loop: 0)
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addPlay('https://example.com/audio/hold-music.mp3', ['loop' => 0]);
echo $response->toXML();
```
### Supported Formats
| Format | Extension | Notes |
| ------ | --------- | ---------------------------------- |
| MP3 | `.mp3` | Recommended for smaller file sizes |
| WAV | `.wav` | Highest quality, larger files |
**Requirements:**
* Audio must be served over HTTPS
* Maximum file size: 10 MB
* Recommended: 8kHz or 16kHz sample rate, mono
### Combine with Speak
```xml theme={null}
https://example.com/audio/intro-jingle.mp3
Welcome to Acme Corporation. How can we help you today?
```
### Play During IVR
Nest `` inside `` to play audio while collecting input:
```xml theme={null}
https://example.com/audio/menu-options.mp3
We didn't receive any input. Goodbye.
```
### Play Nesting
`` can be nested inside:
* `` - Play while collecting digits
* `` - Play while collecting speech/digits
* `` - Play before answering the call
### Play Best Practices
1. **Use HTTPS** - Audio URLs must use HTTPS
2. **Optimize file size** - Compress audio for faster loading
3. **Host reliably** - Use a CDN for audio file hosting
4. **Test audio quality** - Ensure audio is clear at phone quality (8kHz)
5. **Provide fallback** - Use `` as backup if audio fails to load
***
## DTMF
The `` element sends DTMF (Dual-Tone Multi-Frequency) tones on the current call. Use it to navigate IVR systems, enter PINs, or interact with telephony systems.
### Basic Usage
```xml theme={null}
1234
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.DTMFElement('1234'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addDTMF('1234');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addDTMF('1234')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addDTMF('1234');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(new DTMF("1234"));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddDTMF("1234");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.DTMFElement).SetContents("1234"),
},
}
print(response.String())
}
```
### DTMF Attributes
| Attribute | Type | Default | Description |
| --------- | ------- | ------- | ------------------------------------------------ |
| `async` | boolean | `true` | Send asynchronously and continue to next element |
### Allowed Characters
| Character | Description |
| --------- | ---------------- |
| `0-9` | Digit tones |
| `*` | Star key |
| `#` | Pound/hash key |
| `w` | Wait 0.5 seconds |
| `W` | Wait 1 second |
### With Pauses
Use `w` (0.5s) or `W` (1s) to add delays between tones:
```xml theme={null}
1ww2ww3ww4
```
This sends 1, waits 1 second, sends 2, waits 1 second, etc.
### Navigate External IVR
When dialing an external number with an IVR:
```xml theme={null}
+14155559999
```
This is typically done using the `sendDigits` attribute on `` rather than the `` element.
### Send During Call
Send tones during an active call:
```xml theme={null}
Sending your confirmation code now.
5678
Code sent.
```
### Synchronous vs Asynchronous
**Async (default):** DTMF sends while next element starts
```xml theme={null}
123
Processing...
```
**Sync:** Wait for DTMF to complete before continuing
```xml theme={null}
123
DTMF complete.
```
### DTMF Use Cases
| Scenario | Example |
| ----------------- | ----------------------- |
| Enter PIN | `1234#` |
| Navigate IVR menu | `1` |
| Enter extension | `wwww5678` |
| Star code | `*67` |
### Combined with Dial
When using with ``, prefer `sendDigits` on the `` element:
```xml theme={null}
+14155551234
```
***
## Related
* [Input Collection](/docs/voice/xml/input/) - GetDigits, GetInput
* [Call Routing](/docs/voice/xml/routing/) - Dial, Redirect, Hangup, Wait
* [SSML Concepts](/docs/voice/concepts/ssml/) - Advanced speech control
# Audio Streaming
Source: https://plivo.com/docs/voice/xml/audio-streaming
Stream real-time audio from calls over WebSocket for AI voice applications
The `` element streams raw audio from active calls over a WebSocket connection in near real-time. Use it for real-time speech processing, transcription, or AI voice applications.
***
## Basic Usage
```xml theme={null}
wss://yourserver.example.com/audiostream
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.StreamElement('wss://yourserver.example.com/audiostream'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addStream('wss://yourserver.example.com/audiostream');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addStream('wss://yourserver.example.com/audiostream')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addStream('wss://yourserver.example.com/audiostream');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(new Stream("wss://yourserver.example.com/audiostream"));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
var stream = new Stream("wss://yourserver.example.com/audiostream", new Dictionary() {
{"bidirectional", "false"},
{"audioTrack", "both"}
});
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.StreamElement).SetContents("wss://yourserver.example.com/audiostream"),
},
}
print(response.String())
}
```
***
## Attributes
| Attribute | Type | Default | Description |
| ------------------------ | ------- | ----------------------- | ----------------------------------------------------------------------------------------- |
| `bidirectional` | boolean | `false` | Enable two-way audio (read/write) |
| `audioTrack` | string | `inbound` | Which audio to stream: `inbound`, `outbound`, `both` |
| `streamTimeout` | integer | `86400` | Max stream duration in seconds |
| `contentType` | string | `audio/x-l16;rate=8000` | Audio codec and sample rate |
| `keepCallAlive` | boolean | `false` | Continue call only after stream ends |
| `extraHeaders` | string | - | Custom key-value pairs for WebSocket |
| `statusCallbackUrl` | URL | - | URL for stream status events |
| `statusCallbackMethod` | string | `POST` | HTTP method for callback |
| `noiseCancellation` | string | `"false"` | Enable noise cancellation: `"true"` or `"false"` |
| `noiseCancellationLevel` | integer | `85` | Noise reduction intensity (`60`–`100`). Only applies when `noiseCancellation` is `"true"` |
***
## Audio Formats
| Content Type | Description |
| ------------------------- | -------------------------- |
| `audio/x-l16;rate=8000` | Linear PCM, 8kHz (default) |
| `audio/x-l16;rate=16000` | Linear PCM, 16kHz |
| `audio/x-l16;rate=24000` | Linear PCM, 24kHz |
| `audio/x-mulaw;rate=8000` | G.711 mu-law, 8kHz |
***
## Bidirectional Streaming
Enable two-way audio for voice AI applications:
```xml theme={null}
wss://ai.example.com/voice-agent
```
When `bidirectional="true"`, your WebSocket server can send audio back:
```json theme={null}
{
"event": "playAudio",
"media": {
"contentType": "audio/x-l16",
"sampleRate": "8000",
"payload": ""
}
}
```
When `bidirectional` is `true`, `audioTrack` cannot be `outbound` or `both`.
***
## Stream Both Directions
Capture audio from both parties:
```xml theme={null}
wss://transcription.example.com/stream
This call is being transcribed for quality purposes.
```
***
## Status Callbacks
Monitor stream connection status:
```xml theme={null}
wss://yourserver.example.com/audiostream
```
### Callback Events
Notifications sent when:
* Audio stream is connected
* Audio stream is stopped (intentionally or timeout)
* Audio stream failed or disconnected
### Callback Parameters
| Parameter | Description |
| --------------- | ------------------------------- |
| `bidirectional` | Whether stream is bidirectional |
| `audioTrack` | Which audio tracks are streamed |
| `streamTimeout` | Max stream duration |
| `contentType` | Audio codec used |
| `extraHeaders` | Custom headers sent |
| `keepCallAlive` | Whether call waits for stream |
***
## Custom Headers
Pass metadata to your WebSocket server:
```xml theme={null}
wss://yourserver.example.com/audiostream
```
**Constraints:**
* Max length: 512 bytes
* Allowed characters: `[A-Z]`, `[a-z]`, `[0-9]`
***
## Keep Call Alive
Wait for stream to end before continuing:
```xml theme={null}
wss://ai.example.com/conversation
Thank you for using our AI assistant.
```
When `keepCallAlive="true"`:
* Stream element runs exclusively
* Subsequent XML executes only after stream disconnects
***
## Noise Cancellation
Filter out background noise in real-time to improve voice clarity and transcription accuracy for voice agent applications in noisy environments.
```xml theme={null}
wss://ai.example.com/voice-agent
```
**Choosing a cancellation level:**
| Level Range | Environment | Notes |
| ----------- | ----------------------------- | --------------------------------------------------- |
| `60`–`70` | Quiet (home, office) | Light filtering, preserves voice detail |
| `70`–`85` | Moderate noise | Good balance for most use cases (default: `85`) |
| `85`–`100` | Heavy noise (traffic, crowds) | Aggressive filtering, may introduce minor artifacts |
Start with the default value of `85`. Increase toward `100` for heavy background noise. Decrease toward `60` if you notice audio artifacts or voice distortion.
***
## Use Cases
| Scenario | Configuration |
| ------------------------------ | -------------------------------------------------------------------------- |
| Real-time transcription | `audioTrack="both"`, `contentType="audio/x-l16;rate=16000"` |
| Voice AI agent | `bidirectional="true"`, `keepCallAlive="true"` |
| Voice AI in noisy environments | `bidirectional="true"`, `keepCallAlive="true"`, `noiseCancellation="true"` |
| Call monitoring | `audioTrack="inbound"` |
| Quality analysis | `audioTrack="both"` |
***
## WebSocket Events
Your WebSocket server receives:
| Event | Description |
| -------------- | ----------------------------------------------------------------- |
| **Connection** | Initial metadata about the stream and call |
| **Media** | Base64-encoded audio chunks with contentType, sampleRate, payload |
| **Stop** | Notification when stream ends |
For detailed event protocol, see [Stream Event Protocol](/docs/voice-agents/audio-streaming/concepts/audio-streaming-guide).
***
## Related
* [Audio Streaming Guide](/docs/voice-agents/audio-streaming/concepts/audio-streaming-guide) - Complete audio streaming documentation
* [Stream Event Protocol](/docs/voice-agents/audio-streaming/concepts/audio-streaming-guide) - WebSocket message reference
* [Audio Streams API](/docs/voice/api/audio-streams/) - Control streams via API
# Conference
Source: https://plivo.com/docs/voice/xml/conference
Connect multiple callers in a shared conference room with moderation and recording
The `` element connects a caller to a conference room. Multiple callers joining the same conference name are connected together. Maximum participants per conference: 20.
For role-based multi-party calls with coaching, individual hold/mute, and AI agent support, see [Multi-party Call](/docs/voice/xml/multiparty-call/).
### Basic Usage
```xml theme={null}
my-conference-room
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.ConferenceElement('my-conference-room'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addConference('my-conference-room');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addConference('my-conference-room')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addConference('my-conference-room');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(new Conference("my-conference-room"));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddConference("my-conference-room");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.ConferenceElement).SetContents("my-conference-room"),
},
}
print(response.String())
}
```
***
## Conference Attributes
### Basic Settings
| Attribute | Type | Default | Description |
| -------------- | ------- | ------- | ------------------------------------------ |
| `muted` | boolean | `false` | Join muted (can still hear others) |
| `enterSound` | string | `""` | Sound on entry: `beep:1`, `beep:2`, or URL |
| `exitSound` | string | `""` | Sound on exit: `beep:1`, `beep:2`, or URL |
| `maxMembers` | integer | `20` | Maximum participants (1-20) |
| `timeLimit` | integer | `86400` | Max conference duration in seconds |
| `hangupOnStar` | boolean | `false` | Let member exit by pressing \* |
| `stayAlone` | boolean | `true` | End conference if only one member |
### Moderation
| Attribute | Type | Default | Description |
| ------------------------ | ------- | ------- | --------------------------------------------------- |
| `startConferenceOnEnter` | boolean | `true` | Start conference when this member joins |
| `endConferenceOnExit` | boolean | `false` | End conference when this member leaves |
| `waitSound` | URL | - | Audio to play while waiting for conference to start |
### Recording
| Attribute | Type | Default | Description |
| --------------------- | ------- | ------- | ------------------------------------------------------------------------------------------ |
| `record` | boolean | `false` | Record the conference |
| `recordFileFormat` | string | `mp3` | Recording format (`mp3`, `wav`) |
| `transcriptionType` | string | - | Transcription type. Values: `auto`, `hybrid`, `manual` |
| `transcriptionUrl` | URL | - | URL to receive transcription |
| `transcriptionMethod` | string | `POST` | HTTP method for sending transcription results to `transcriptionUrl`. Values: `GET`, `POST` |
### Callbacks
| Attribute | Type | Default | Description |
| ---------------- | ------- | ------- | ----------------------------- |
| `action` | URL | - | URL called when member leaves |
| `method` | string | `POST` | HTTP method for action |
| `callbackUrl` | URL | - | URL for conference events |
| `callbackMethod` | string | `POST` | HTTP method for callback |
| `redirect` | boolean | `true` | Redirect to action URL |
### DTMF
| Attribute | Type | Default | Description |
| ------------- | ------- | ------- | --------------------------------------- |
| `digitsMatch` | string | - | DTMF patterns to report |
| `floorEvent` | boolean | `false` | Notify when member becomes floor-holder |
| `relayDTMF` | boolean | `true` | Transmit DTMF to all members |
***
## Examples
### Join Muted
Add participants who can listen but not speak:
```xml theme={null}
my-conference-room
```
### Entry/Exit Sounds
Play beeps when participants join or leave:
```xml theme={null}
my-conference-room
```
Use a URL to play custom audio:
```xml theme={null}
my-conference-room
```
The URL must return XML with `Play`, `Speak`, or `Wait` elements.
### Moderated Conference
Create a "waiting room" where participants wait for the moderator:
**Participant XML:**
```xml theme={null}
moderated-meeting
```
**Moderator XML:**
```xml theme={null}
moderated-meeting
```
When the moderator joins, the conference starts. When they leave, everyone is disconnected.
### Record Conference
```xml theme={null}
recorded-meeting
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.ConferenceElement(
'recorded-meeting',
record=True,
record_file_format='mp3',
callback_url='https://example.com/recording-ready/'
))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addConference('recorded-meeting', {
record: true,
recordFileFormat: 'mp3',
callbackUrl: 'https://example.com/recording-ready/'
});
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
response.addConference('recorded-meeting',
record: true,
recordFileFormat: 'mp3',
callbackUrl: 'https://example.com/recording-ready/'
)
puts Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addConference('recorded-meeting', [
'record' => true,
'recordFileFormat' => 'mp3',
'callbackUrl' => 'https://example.com/recording-ready/'
]);
echo $response->toXML();
```
### With Transcription
```xml theme={null}
transcribed-meeting
```
### Exit with Action URL
```xml theme={null}
my-conference
```
### Bridge Two Callers
Use conferences to connect two incoming callers:
**First Caller:**
```xml theme={null}
private-bridge-123
```
**Second Caller:**
```xml theme={null}
private-bridge-123
```
***
## Callback Parameters
### Conference Action URL Parameters
Sent when a member leaves the conference:
| Parameter | Description |
| -------------------- | ----------------------------- |
| `ConferenceName` | Name of the conference |
| `ConferenceUUID` | Unique conference identifier |
| `ConferenceMemberID` | Member's ID in the conference |
| `RecordUrl` | Recording URL (if recorded) |
| `RecordingID` | Recording identifier |
### Conference Callback URL Parameters
Sent for conference events:
| Parameter | Description |
| ----------------------- | ----------------------------------------------- |
| `ConferenceAction` | `enter`, `exit`, `digits`, `floor`, `record` |
| `ConferenceName` | Conference name |
| `ConferenceUUID` | Conference identifier |
| `ConferenceMemberID` | Member ID |
| `CallUUID` | Call identifier |
| `ConferenceDigitsMatch` | Matched digits (when `ConferenceAction=digits`) |
| `RecordUrl` | Recording URL (when `ConferenceAction=record`) |
| `RecordingID` | Recording ID |
| `RecordingDuration` | Duration in seconds |
| `RecordingDurationMs` | Duration in milliseconds |
| `RecordingStartMs` | Start time (epoch ms) |
| `RecordingEndMs` | End time (epoch ms) |
### Transcription URL Parameters
| Parameter | Description |
| ---------------------- | ---------------------- |
| `transcription` | Transcribed text |
| `transcription_charge` | Cost of transcription |
| `transcription_rate` | Rate per minute |
| `duration` | Recording duration |
| `call_uuid` | Call identifier |
| `recording_id` | Recording identifier |
| `error` | Error message (if any) |
***
## Related
* [Multi-party Call](/docs/voice/xml/multiparty-call/) — Role-based calls with coaching, AI agents, and advanced controls
* [Recording](/docs/voice/xml/record/) — Record calls
* [Call Routing](/docs/voice/xml/routing/) — Dial, Redirect, Hangup
# Input Collection
Source: https://plivo.com/docs/voice/xml/input
Collect DTMF digits and speech input from callers
This page covers the XML elements for collecting user input: DTMF digit presses and automatic speech recognition.
***
## GetDigits
The `` element collects DTMF (touch-tone) digits entered by the caller. Use it for IVR menus, PIN entry, and numeric input.
**Recommendation:** Use [GetInput](#getinput) instead of GetDigits for new applications. GetInput supports both speech and digit input.
### Basic Usage
```xml theme={null}
Press 1 for sales, press 2 for support.
We didn't receive any input. Goodbye.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
getdigits = plivoxml.GetDigitsElement(
action='https://example.com/handle-input/',
num_digits=1
)
getdigits.add(plivoxml.SpeakElement('Press 1 for sales, press 2 for support.'))
response.add(getdigits)
response.add(plivoxml.SpeakElement("We didn't receive any input. Goodbye."))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const getDigits = response.addGetDigits({
action: 'https://example.com/handle-input/',
numDigits: 1
});
getDigits.addSpeak('Press 1 for sales, press 2 for support.');
response.addSpeak("We didn't receive any input. Goodbye.");
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
getdigits = response.addGetDigits(
action: 'https://example.com/handle-input/',
numDigits: 1
)
getdigits.addSpeak('Press 1 for sales, press 2 for support.')
response.addSpeak("We didn't receive any input. Goodbye.")
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addGetDigits([
'action' => 'https://example.com/handle-input/',
'numDigits' => 1
]);
$getdigits->addSpeak('Press 1 for sales, press 2 for support.');
$response->addSpeak("We didn't receive any input. Goodbye.");
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new GetDigits()
.action("https://example.com/handle-input/")
.numDigits(1)
.children(new Speak("Press 1 for sales, press 2 for support.")),
new Speak("We didn't receive any input. Goodbye.")
);
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
var getDigits = new GetDigits(new Dictionary() {
{"action", "https://example.com/handle-input/"},
{"numDigits", "1"}
});
getDigits.AddSpeak("Press 1 for sales, press 2 for support.");
response.Add(getDigits);
response.AddSpeak("We didn't receive any input. Goodbye.");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.GetDigitsElement).
Action("https://example.com/handle-input/").
NumDigits(1).
SetContents([]interface{}{
new(xml.SpeakElement).AddSpeak("Press 1 for sales."),
}),
new(xml.SpeakElement).AddSpeak("No input received."),
},
}
print(response.String())
}
```
### GetDigits Attributes
| Attribute | Type | Default | Description |
| -------------------- | ------- | -------------- | --------------------------------------------- |
| `action` | URL | - | URL to receive the digits |
| `method` | string | `POST` | HTTP method (`GET`, `POST`) |
| `numDigits` | integer | `99` | Maximum digits to collect |
| `timeout` | integer | `5` | Seconds to wait for first digit |
| `digitTimeout` | integer | `2` | Seconds between consecutive digits |
| `finishOnKey` | string | `#` | Key to submit input (digit, `#`, `*`, `none`) |
| `retries` | integer | `1` | Retry attempts if no input |
| `redirect` | boolean | `true` | Redirect to action URL |
| `playBeep` | boolean | `false` | Play beep after nested elements |
| `validDigits` | string | `1234567890*#` | Allowed digits |
| `invalidDigitsSound` | URL | - | Audio for invalid digit |
| `log` | boolean | `true` | Log digits (disable for sensitive input) |
### Nested Elements
`` can contain:
* `` - Text-to-speech prompt
* `` - Audio file prompt
Prompts play while waiting for input. Input collection starts as soon as the first digit is pressed.
### Phone Tree (IVR)
```xml theme={null}
Welcome to Acme Corp.
Press 1 for sales.
Press 2 for support.
Press 3 for billing.
Press 0 to speak with an operator.
Sorry, we didn't receive valid input. Goodbye.
```
Handle the input on your server:
```python theme={null}
# Flask example
@app.route('/ivr/', methods=['POST'])
def handle_ivr():
digits = request.form.get('Digits')
response = plivoxml.ResponseElement()
if digits == '1':
response.add(plivoxml.SpeakElement('Connecting you to sales.'))
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155551111'))
response.add(dial)
elif digits == '2':
response.add(plivoxml.SpeakElement('Connecting you to support.'))
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155552222'))
response.add(dial)
elif digits == '3':
response.add(plivoxml.RedirectElement('https://example.com/billing-menu/'))
elif digits == '0':
response.add(plivoxml.SpeakElement('Please hold for an operator.'))
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155550000'))
response.add(dial)
else:
response.add(plivoxml.SpeakElement('Invalid option.'))
response.add(plivoxml.RedirectElement('https://example.com/ivr-start/'))
return Response(response.to_string(), mimetype='application/xml')
```
### PIN Entry
Collect a specific number of digits:
```xml theme={null}
Please enter your 4-digit PIN.
```
**Note:** Set `log="false"` for sensitive input like PINs.
### Variable Length Input
Use `finishOnKey` for variable-length input:
```xml theme={null}
Enter your account number followed by the pound key.
```
### Restrict Valid Digits
Only accept specific digits:
```xml theme={null}
Press 1, 2, or 3.
```
### No Redirect
Collect digits without redirecting (fire and forget):
```xml theme={null}
Press any key to confirm you're listening.
Thank you. Continuing with your call.
```
### GetDigits Action URL Parameters
When digits are collected, these parameters are sent:
| Parameter | Description |
| --------- | -------------------------------------------- |
| `Digits` | The digits entered (excluding `finishOnKey`) |
Plus all standard [request parameters](/docs/voice/xml/overview/#request-parameters).
### GetDigits Flow Behavior
1. Nested `` or `` elements execute
2. If `playBeep="true"`, a beep plays
3. Digit collection starts
4. Collection ends when:
* `numDigits` reached
* `finishOnKey` pressed
* `timeout` or `digitTimeout` expires
5. Digits sent to `action` URL
6. Response XML from `action` URL executes
If no digits are received after `retries` attempts, execution continues to the next element.
***
## GetInput
The `` element collects user input through automatic speech recognition (ASR) or DTMF digit presses. It's the recommended replacement for ``, supporting both speech and digit input.
### Basic Usage
```xml theme={null}
How can I help you today? You can say your request or press 1 for sales, 2 for support.
We didn't receive any input. Please try again.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
getinput = plivoxml.GetInputElement(
action='https://example.com/handle-input/',
input_type='dtmf speech'
)
getinput.add_speak('How can I help you today?')
response.add(getinput)
response.add(plivoxml.SpeakElement("We didn't receive any input."))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const getInput = response.addGetInput({
action: 'https://example.com/handle-input/',
inputType: 'dtmf speech'
});
getInput.addSpeak('How can I help you today?');
response.addSpeak("We didn't receive any input.");
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
get_input = response.addGetInput(
action: 'https://example.com/handle-input/',
inputType: 'dtmf speech'
)
get_input.addSpeak('How can I help you today?')
response.addSpeak("We didn't receive any input.")
puts Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addGetInput([
'action' => 'https://example.com/handle-input/',
'inputType' => 'dtmf speech'
]);
$get_input->addSpeak('How can I help you today?');
$response->addSpeak("We didn't receive any input.");
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new GetInput()
.action("https://example.com/handle-input/")
.inputType("dtmf speech")
.children(new Speak("How can I help you today?")),
new Speak("We didn't receive any input.")
);
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
var getInput = new GetInput(new Dictionary() {
{"action", "https://example.com/handle-input/"},
{"inputType", "dtmf speech"}
});
getInput.AddSpeak("How can I help you today?");
response.Add(getInput);
response.AddSpeak("We didn't receive any input.");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.GetInputElement).
SetAction("https://example.com/handle-input/").
SetInputType("dtmf speech").
SetContents([]interface{}{
new(xml.SpeakElement).AddSpeak("How can I help you today?"),
}),
new(xml.SpeakElement).AddSpeak("We didn't receive any input."),
},
}
print(response.String())
}
```
### GetInput Attributes
#### Core Settings
| Attribute | Type | Default | Description |
| ----------- | ------- | ---------- | ------------------------------------------- |
| `action` | URL | *required* | URL to receive the input |
| `method` | string | `POST` | HTTP method (`GET`, `POST`) |
| `inputType` | string | - | Input type: `dtmf`, `speech`, `dtmf speech` |
| `redirect` | boolean | `true` | Redirect to action URL after input |
| `log` | boolean | `true` | Log input (disable for sensitive data) |
#### Timing
| Attribute | Type | Default | Description |
| ------------------- | ------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `executionTimeout` | integer | `15` | Max seconds to wait for input (5-60) |
| `digitEndTimeout` | string | `auto` | Seconds between digits (2-10, or `auto`) |
| `speechEndTimeout` | string | `auto` | Seconds of silence to end speech (2-10, or `auto`) |
| `startInputTimeout` | integer | - | Seconds to wait for the caller to begin providing input. Distinct from `executionTimeout` (total time), `digitEndTimeout` (between digits), and `speechEndTimeout` (end of speech) |
| `retries` | integer | `1` | Number of times to retry input collection if no valid input is received |
#### DTMF Settings
| Attribute | Type | Default | Description |
| ------------- | ------- | ------- | --------------------------------------------- |
| `numDigits` | integer | `32` | Maximum digits to collect (1-32) |
| `finishOnKey` | string | `#` | Key to submit input (digit, `#`, `*`, `none`) |
#### Speech Settings
| Attribute | Type | Default | Description |
| ----------------- | ------- | --------- | -------------------------------------------------------- |
| `language` | string | `en-US` | Speech recognition language |
| `speechModel` | string | `default` | ASR model: `default`, `command_and_search`, `phone_call` |
| `hints` | string | - | Comma-separated phrases to boost recognition |
| `profanityFilter` | boolean | `false` | Filter profane words |
#### Callbacks
| Attribute | Type | Default | Description |
| ------------------------------------ | ------ | ------- | -------------------------------- |
| `interimSpeechResultsCallback` | URL | - | URL for real-time speech results |
| `interimSpeechResultsCallbackMethod` | string | `POST` | HTTP method for interim callback |
### Input Types
#### DTMF Only
Collect only digit presses:
```xml theme={null}
Enter your 4-digit PIN.
```
#### Speech Only
Collect only speech input:
```xml theme={null}
What city would you like to search?
```
#### Both Speech and DTMF
Accept either input type (first detected wins):
```xml theme={null}
Say your request or press 1 for help.
```
### Speech Recognition Models
| Model | Best For |
| -------------------- | --------------------------------- |
| `default` | General long-form audio |
| `command_and_search` | Short commands and voice search |
| `phone_call` | Phone call audio (varied quality) |
```xml theme={null}
What would you like to do?
```
### Improve Speech Recognition
Use `hints` to boost recognition of specific words:
```xml theme={null}
How can I help you with your account today?
```
**Limits:**
* Max 500 phrases per request
* Max 10,000 characters total
* Max 100 characters per phrase
### Real-Time Speech Results
Get interim transcription results as the user speaks:
```xml theme={null}
Please describe your issue.
```
#### Interim Callback Parameters
| Parameter | Description |
| ---------------- | ------------------------------ |
| `StableSpeech` | Confident transcription so far |
| `UnstableSpeech` | Current guess (may change) |
| `Stability` | Confidence score (0.0-1.0) |
| `SequenceNumber` | Order of callbacks |
### Supported Languages
Common languages include:
| Language | Code |
| ------------------- | ------- |
| English (US) | `en-US` |
| English (UK) | `en-GB` |
| English (Australia) | `en-AU` |
| Spanish (US) | `es-US` |
| Spanish (Spain) | `es-ES` |
| French | `fr-FR` |
| German | `de-DE` |
| Italian | `it-IT` |
| Portuguese (Brazil) | `pt-BR` |
| Japanese | `ja-JP` |
| Chinese (Mandarin) | `zh-CN` |
### GetInput Action URL Parameters
When input is collected:
| Parameter | Description |
| ----------------------- | -------------------------------- |
| `InputType` | `dtmf` or `speech` |
| `Digits` | Digits entered (empty if speech) |
| `Speech` | Transcribed text (empty if DTMF) |
| `SpeechConfidenceScore` | Confidence (0.0-1.0) |
| `BilledAmount` | Transcription cost |
Plus all standard [request parameters](/docs/voice/xml/overview/#request-parameters).
### Handling Input on Your Server
```python theme={null}
# Flask example
@app.route('/handle-input/', methods=['POST'])
def handle_input():
input_type = request.form.get('InputType')
response = plivoxml.ResponseElement()
if input_type == 'dtmf':
digits = request.form.get('Digits')
if digits == '1':
response.add(plivoxml.SpeakElement('Connecting you to sales.'))
# Add dial logic
elif digits == '2':
response.add(plivoxml.SpeakElement('Connecting you to support.'))
# Add dial logic
elif input_type == 'speech':
speech = request.form.get('Speech', '').lower()
confidence = float(request.form.get('SpeechConfidenceScore', 0))
if confidence < 0.5:
response.add(plivoxml.SpeakElement("I didn't catch that. Please try again."))
response.add(plivoxml.RedirectElement('/start/'))
elif 'balance' in speech:
response.add(plivoxml.SpeakElement('Your current balance is $150.'))
elif 'transfer' in speech:
response.add(plivoxml.RedirectElement('/transfer-flow/'))
else:
response.add(plivoxml.SpeakElement("I'm not sure how to help with that."))
return Response(response.to_string(), mimetype='application/xml')
```
### GetInput Nested Elements
`` can contain:
* `` - Voice prompt
* `` - Audio prompt
### Speech Recognition Pricing
Speech recognition is billed per 15-second increment.
***
## Related
* [Audio Output](/docs/voice/xml/audio-output/) - Speak, Play, DTMF
* [Call Routing](/docs/voice/xml/routing/) - Dial, Redirect, Hangup, Wait
# Multi-party Call
Source: https://plivo.com/docs/voice/xml/multiparty-call
Create role-based multi-party calls with coaching, recording controls, and AI agent integration
The `` element creates or joins a multi-party call (MPC) with advanced features like participant roles, coach mode for supervisors, and individual hold/mute controls.
For simple conference bridges without roles, see [Conference](/docs/voice/xml/conference/).
### Basic Usage
```xml theme={null}
my-mpc-name
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.MultiPartyCallElement(
content='my-mpc-name',
role='customer',
max_duration=10000
))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addMultiPartyCall('my-mpc-name', {
role: 'customer',
maxDuration: 10000
});
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
response.addMultiPartyCall('my-mpc-name',
role: 'Agent',
maxDuration: 10000)
puts Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addMultiPartyCall('my-mpc-name', [
'role' => 'Customer',
'maxDuration' => 10000
]);
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
import com.plivo.api.models.multipartycall.MultiPartyCallUtils;
Response response = new Response();
response.children(new MultiPartyCall("my-mpc-name", MultiPartyCallUtils.customer)
.maxDuration(10000));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddMultiPartyCall("my-mpc-name", new Dictionary() {
{"role", "customer"},
{"maxDuration", "10000"}
});
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.MultiPartyCallElement).
SetRole("customer").
SetMaxDuration(10000).
SetContents("my-mpc-name"),
},
}
print(response.String())
}
```
***
## Participant Roles
| Role | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------- |
| `Customer` | The customer being served |
| `Agent` | Customer service representative |
| `Supervisor` | Can monitor/coach agents (coach mode) |
| `ai-agent` | AI agent connected via WebSocket streaming (see [AI Agent Stream Attributes](#ai-agent-stream-attributes)) |
***
## MPC-Level Attributes
These settings apply to the entire multi-party call:
| Attribute | Type | Default | Description |
| --------------------------- | ------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `maxDuration` | integer | `14400` | Max MPC duration in seconds (300-28800) |
| `maxParticipants` | integer | `10` | Maximum participants (2-10) |
| `record` | boolean | `false` | Record the MPC |
| `recordFileFormat` | string | `mp3` | Recording format (`mp3`, `wav`) |
| `recordMinMemberCount` | integer | `1` | Min members to start recording (1 or 2) |
| `waitForAgent` | boolean | `false` | When `true`, the MPC waits for an agent to join before starting. Customer participants hear wait music until an agent arrives |
| `recordCoachVoice` | boolean | - | When `true`, includes the supervisor/coach voice in the call recording. When `false`, only agent and customer voices are recorded |
| `startRecordingAudio` | URL | - | URL to fetch XML instructions for audio to play when recording starts |
| `startRecordingAudioMethod` | string | `GET` | HTTP method for `startRecordingAudio` URL. Values: `GET`, `POST` |
| `stopRecordingAudio` | URL | - | URL to fetch XML instructions for audio to play when recording stops |
| `stopRecordingAudioMethod` | string | `GET` | HTTP method for `stopRecordingAudio` URL. Values: `GET`, `POST` |
### Hold Music
| Attribute | Type | Description |
| ------------------------- | ------ | ----------------------------------------------- |
| `waitMusicUrl` | URL | Music for participants waiting for MPC to start |
| `waitMusicMethod` | string | HTTP method for waitMusicUrl |
| `agentHoldMusicUrl` | URL | Music for agents on hold |
| `agentHoldMusicMethod` | string | HTTP method for agent hold music |
| `customerHoldMusicUrl` | URL | Music for customers on hold |
| `customerHoldMusicMethod` | string | HTTP method for customer hold music |
### Callbacks
| Attribute | Type | Description |
| ------------------------- | ------ | ---------------------------------- |
| `statusCallbackUrl` | URL | URL for MPC events |
| `statusCallbackMethod` | string | HTTP method (`GET`, `POST`) |
| `statusCallbackEvents` | string | Events to receive (see below) |
| `recordingCallbackUrl` | URL | URL for recording events |
| `recordingCallbackMethod` | string | HTTP method for recording callback |
***
## Participant-Level Attributes
These settings apply to individual participants:
| Attribute | Type | Default | Description |
| ----------------- | ------- | ---------- | ---------------------------------------- |
| `role` | string | *required* | `Agent`, `Supervisor`, or `Customer` |
| `mute` | boolean | `false` | Join muted |
| `hold` | boolean | `false` | Join on hold |
| `coachMode` | boolean | `true` | Supervisor coach mode (supervisors only) |
| `stayAlone` | boolean | `false` | Stay if only participant |
| `startMpcOnEnter` | boolean | `true` | Start MPC when joining |
| `endMpcOnExit` | boolean | `false` | End MPC when leaving |
### Entry/Exit Sounds
| Attribute | Type | Default | Description |
| ------------------ | ------ | -------- | -------------------------------------------------- |
| `enterSound` | string | `beep:1` | Sound on entry: `none`, `beep:1`, `beep:2`, or URL |
| `enterSoundMethod` | string | `GET` | HTTP method for enterSound URL |
| `exitSound` | string | `beep:2` | Sound on exit: `none`, `beep:1`, `beep:2`, or URL |
| `exitSoundMethod` | string | `GET` | HTTP method for exitSound URL |
### Actions
| Attribute | Type | Description |
| -------------------- | ------- | ----------------------------------- |
| `onExitActionUrl` | URL | URL called when participant exits |
| `onExitActionMethod` | string | HTTP method (`GET`, `POST`) |
| `relayDTMFInputs` | boolean | Transmit DTMF to other participants |
### AI Agent Stream Attributes
When `role` is set to `ai-agent`, use these attributes to connect an AI agent via WebSocket streaming.
| Attribute | Type | Default | Description |
| ----------------------------------- | ------ | ----------------------- | ------------------------------------------------------------------- |
| `aiAgentStreamServiceUrl` | URL | - | WebSocket URL for the AI agent audio stream service |
| `aiAgentStreamContentType` | string | `audio/x-l16;rate=8000` | Audio content type for the AI agent stream |
| `aiAgentStreamStatusCallbackUrl` | URL | - | URL for receiving AI agent stream status event callbacks |
| `aiAgentStreamStatusCallbackMethod` | string | `POST` | HTTP method for the AI agent status callback. Values: `GET`, `POST` |
| `aiAgentStreamSamplingRate` | string | - | Audio sampling rate for the AI agent stream |
| `aiAgentStreamExtraHeaders` | object | `{}` | Custom headers sent with the AI agent WebSocket connection |
***
## Examples
### Supervisor Coach Mode
Supervisors with `coachMode="true"` can hear everyone but only agents hear them (customers cannot):
**Supervisor joining:**
```xml theme={null}
support-call-123
```
**Agent joining:**
```xml theme={null}
support-call-123
```
**Customer joining:**
```xml theme={null}
support-call-123
```
### MPC Recording
```xml theme={null}
recorded-call
```
#### Recording Events
* `MPCRecordingInitiated`
* `MPCRecordingPaused`
* `MPCRecordingResumed`
* `MPCRecordingCompleted`
* `MPCRecordingFailed`
### On Exit Action
Continue call flow after leaving MPC:
```xml theme={null}
support-call
```
### Custom Hold Music
```xml theme={null}
call-center-mpc
```
Hold music URLs must return XML with `Play`, `Speak`, or `Wait` elements.
***
## Status Callback Events
Configure which events to receive with `statusCallbackEvents`:
| Value | Events Included |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mpc-state-changes` | MPCInitialized, MPCStart, MPCEnd |
| `participant-state-changes` | ParticipantJoin, ParticipantExit, ParticipantMute, ParticipantUnmute, ParticipantHold, ParticipantUnhold, ParticipantCoachModeStart, ParticipantCoachModeStop |
| `participant-speak-events` | ParticipantSpeakStart, ParticipantSpeakStop |
| `participant-digit-input-events` | ParticipantDigitInput |
| `add-participant-api-events` | AddParticipantByAPIActionInitiated, AddParticipantByAPIActionCompleted |
| `participant-audio-events` | ParticipantAudioStart, ParticipantAudioStop — triggered when audio from a participant starts or stops |
```xml theme={null}
my-mpc
```
### Status Callback Parameters
| Parameter | Description |
| ---------------------- | ------------------------------ |
| `EventName` | Event that triggered callback |
| `EventTimestamp` | When the event occurred |
| `MPCUUID` | Unique MPC identifier |
| `MPCName` | Friendly MPC name |
| `MemberID` | Participant identifier |
| `ParticipantRole` | Agent, Supervisor, or Customer |
| `ParticipantCallUUID` | Participant's call UUID |
| `ParticipantCoachMode` | Whether in coach mode |
| `MPCDuration` | Total MPC duration (on end) |
| `MPCBilledDuration` | Billed duration |
| `MPCBilledAmount` | Cost in USD |
### On Exit Parameters
| Parameter | Description |
| --------------------- | ----------------------- |
| `MPCUUID` | MPC identifier |
| `MPCFriendlyName` | MPC name |
| `MemberID` | Participant ID |
| `ParticipantCallUUID` | Call UUID |
| `ParticipantJoinTime` | When participant joined |
| `ParticipantEndTime` | When participant left |
| `ParticipantRole` | Participant's role |
***
## Conference vs Multi-party Call
| Feature | Conference | Multi-party Call |
| -------------------- | --------------- | ------------------------------------------- |
| Max participants | 20 | 10 |
| Participant roles | No | Yes (Agent, Customer, Supervisor, AI Agent) |
| Coach mode | No | Yes |
| Individual hold/mute | No | Yes |
| API control | Limited | Full |
| Use case | Simple meetings | Call centers, support |
***
## Related
* [Conference](/docs/voice/xml/conference/) — Simple conference bridge
* [Recording](/docs/voice/xml/record/) — Record calls
* [Call Routing](/docs/voice/xml/routing/) — Dial, Redirect, Hangup
* [Multi-party Call API](/docs/voice/api/multiparty-calls/) — Control MPCs via API
# Overview
Source: https://plivo.com/docs/voice/xml/overview
Control voice calls with XML instructions for IVR, call routing, recording, and more
Plivo XML is a set of instructions you use to tell Plivo what to do when you receive an incoming call or make an outbound call. When someone calls your Plivo phone number, Plivo looks up the URL associated with that phone number and makes a request to that URL. Your web application returns an XML document with instructions on how to handle the call.
## How XML Works
### Incoming Calls
1. Someone calls your Plivo phone number
2. Plivo sends a request to your Answer URL
3. Your server returns Plivo XML instructions
4. Plivo executes the instructions (speak, play, dial, etc.)
Incoming call
-
Caller
-
Plivo
-
Your ServerAnswer URL
-
XML Response
-
PlivoExecutes
### Outbound Calls
1. You trigger an outbound call via the API with an `answer_url`
2. When the call is answered, Plivo fetches XML from your `answer_url`
3. Plivo executes the instructions
Outbound call
-
Your App
-
Plivo API
-
Call Recipient
-
XMLfrom answer\_url
-
Execute
***
## Basic Structure
Every Plivo XML document starts with a `` element containing one or more instruction elements:
```xml theme={null}
Hello! Welcome to our service.
https://example.com/audio/menu.mp3
```
Elements are executed in order. When one element completes, the next begins.
### Multiple Elements
```xml theme={null}
Please hold while we connect you.
https://example.com/hold-music.mp3
+14155551234
Sorry, no one is available. Goodbye.
```
**Execution flow:**
1. Speak the message
2. Play the audio file
3. Dial the number
4. If dial fails, speak the fallback message
5. Hang up
***
## Generating XML with SDKs
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Hello, world!'))
response.add(plivoxml.HangupElement())
xml_string = response.to_string()
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak('Hello, world!');
response.addHangup();
const xmlString = response.toXML();
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
response.addSpeak('Hello, world!')
response.addHangup()
xml_string = Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
use Plivo\XML\Response;
$response = new Response();
$response->addSpeak('Hello, world!');
$response->addHangup();
$xml_string = $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new Speak("Hello, world!"),
new Hangup()
);
String xmlString = response.toXmlString();
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddSpeak("Hello, world!");
response.AddHangup();
string xmlString = response.ToString();
```
```go Go theme={null}
import "github.com/plivo/plivo-go/v7/xml"
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).AddSpeak("Hello, world!"),
new(xml.HangupElement),
},
}
xmlString := response.String()
```
***
## Available XML Elements
### Audio Output
| Element | Description |
| --------------------------------------- | ---------------------- |
| [Speak](/docs/voice/xml/audio-output/#speak) | Convert text to speech |
| [Play](/docs/voice/xml/audio-output/#play) | Play an audio file |
| [DTMF](/docs/voice/xml/audio-output/#dtmf) | Send DTMF tones |
### Input Collection
| Element | Description |
| ---------------------------------------- | ----------------------------- |
| [GetDigits](/docs/voice/xml/input/#getdigits) | Collect DTMF digit input |
| [GetInput](/docs/voice/xml/input/#getinput) | Collect speech or digit input |
### Call Routing
| Element | Description |
| ---------------------------------------- | ----------------------------------------- |
| [Dial](/docs/voice/xml/routing/#dial) | Connect to another number or SIP endpoint |
| [Redirect](/docs/voice/xml/routing/#redirect) | Transfer call flow to another URL |
| [Hangup](/docs/voice/xml/routing/#hangup) | End the call |
| [Wait](/docs/voice/xml/routing/#wait) | Pause execution |
### Conferencing
| Element | Description |
| --------------------------------------------- | ----------------------------------- |
| [Conference](/docs/voice/xml/conference/) | Connect caller to a conference room |
| [MultiPartyCall](/docs/voice/xml/multiparty-call/) | Advanced multi-party conferencing |
### Recording
| Element | Description |
| ---------------------------- | ---------------------------- |
| [Record](/docs/voice/xml/record/) | Record the call or a message |
### Advanced
| Element | Description |
| ----------------------------------------- | ------------------------------------ |
| [PreAnswer](/docs/voice/xml/routing#preanswer) | Play media before answering |
| [Stream](/docs/voice/xml/audio-streaming) | Stream real-time audio via WebSocket |
***
## Nesting Elements
Some elements can be nested inside others:
```xml theme={null}
Press 1 for sales, 2 for support.
We didn't receive any input. Goodbye.
```
### Nesting Rules
| Parent Element | Allowed Children |
| -------------- | ----------------- |
| Response | All elements |
| GetDigits | Speak, Play |
| GetInput | Speak, Play |
| Dial | Number, User |
| PreAnswer | Speak, Play, Wait |
***
## Request Parameters
When Plivo requests your XML endpoint, it includes these parameters:
### Voice Call Parameters
| Parameter | Description |
| ------------ | -------------------------------------------------- |
| `CallUUID` | Unique identifier for this call |
| `From` | Caller's phone number (with country code) |
| `To` | Called phone number (with country code) |
| `CallStatus` | Call status: `ringing`, `in-progress`, `completed` |
| `Direction` | `inbound` or `outbound` |
### Inbound vs Outbound
**Inbound calls:**
* `From` = Caller's number
* `To` = Your Plivo number
* `Direction` = `inbound`
**Outbound calls (via API):**
* `From` = Caller ID you specified
* `To` = Destination number
* `Direction` = `outbound`
### Outbound Call Parameters
| Parameter | Description |
| ----------------- | ---------------------------- |
| `ALegUUID` | UUID of the first call leg |
| `ALegRequestUUID` | Request UUID returned by API |
### Call Forwarding
| Parameter | Description |
| --------------- | ---------------------------------------------------------- |
| `ForwardedFrom` | Original number (if call was forwarded). Carrier-dependent |
### Completed Call Parameters
| Parameter | Description |
| -------------- | ------------------------------- |
| `HangupCause` | Standard telephony hangup cause |
| `Duration` | Call duration in seconds |
| `BillDuration` | Billed duration in seconds |
| `TotalCost` | Total cost of the call |
### Call Status Values
| Status | Description |
| ------------- | ------------------------------------------- |
| `ringing` | Call is ringing (inbound, not yet answered) |
| `in-progress` | Call is active |
| `completed` | Call ended normally |
| `busy` | Called party was busy (outbound only) |
| `failed` | Call failed to connect (outbound only) |
| `timeout` | No answer within timeout (outbound only) |
| `no-answer` | Called party didn't answer (outbound only) |
### SIP Headers
For SIP calls, custom SIP headers are included with the `X-PH-` prefix:
| Header Format | Description |
| ------------------- | ----------------------- |
| `X-PH-` | Custom SIP header value |
Example: If you send `sipHeaders="CustomId=123"`, the request includes `X-PH-CustomId=123`.
***
## Response Requirements
Your server must return:
* Valid XML document
* Content-Type: `application/xml` or `text/xml`
* Maximum size: 100 KB
### Framework Examples
```python theme={null}
# Flask
from flask import Response
return Response(xml_string, mimetype='application/xml')
```
```javascript theme={null}
// Express
res.set('Content-Type', 'application/xml');
res.send(xmlString);
```
```ruby theme={null}
# Sinatra
content_type 'application/xml'
xml_string
```
```php theme={null}
// PHP
header('Content-Type: application/xml');
echo $xml_string;
```
### Empty Response
An empty `` element hangs up the call:
```xml theme={null}
```
***
## Example: Using Request Parameters
```python theme={null}
from flask import Flask, request, Response
from plivo import plivoxml
app = Flask(__name__)
@app.route('/answer/', methods=['GET', 'POST'])
def answer():
call_uuid = request.values.get('CallUUID')
caller = request.values.get('From')
called = request.values.get('To')
direction = request.values.get('Direction')
response = plivoxml.ResponseElement()
if direction == 'inbound':
# Log the incoming call
print(f"Incoming call from {caller} to {called}, UUID: {call_uuid}")
# Custom greeting based on caller ID
if is_vip_customer(caller):
response.add(plivoxml.SpeakElement('Welcome back, valued customer!'))
else:
response.add(plivoxml.SpeakElement('Thank you for calling.'))
else:
response.add(plivoxml.SpeakElement('Connecting your call.'))
return Response(response.to_string(), mimetype='application/xml')
```
***
## Example: Simple IVR
```xml theme={null}
Welcome to Acme Corp.
Press 1 for sales.
Press 2 for support.
Press 3 to hear our hours.
Sorry, we didn't receive any input. Goodbye.
```
***
## Example: Forward Call
```xml theme={null}
+14155559876
```
***
## Hangup Causes
Common hangup cause values:
| Cause | Description |
| ---------------------- | ------------------------ |
| `NORMAL_CLEARING` | Normal call termination |
| `USER_BUSY` | Called party busy |
| `NO_ANSWER` | No answer within timeout |
| `CALL_REJECTED` | Call was rejected |
| `UNALLOCATED_NUMBER` | Invalid number |
| `NETWORK_OUT_OF_ORDER` | Network issues |
***
## Best Practices
1. **Always return valid XML** - Malformed XML will cause call failures
2. **Use HTTPS** - All callback URLs should use HTTPS
3. **Handle timeouts** - Include fallback behavior for user input
4. **Test thoroughly** - Use ngrok for local development testing
5. **Log callback data** - Store request parameters for debugging
6. **Return quickly** - Plivo has a 15-second timeout for XML responses
***
## Error Handling
If your server returns invalid XML:
* The call may hang up unexpectedly
* Plivo logs the error in your console
**Common issues:**
* Malformed XML (unclosed tags)
* Wrong content type
* Empty response
* Response too large
***
## Related
* [Audio Output](/docs/voice/xml/audio-output/) - Speak, Play, DTMF
* [Input Collection](/docs/voice/xml/input/) - GetDigits, GetInput
* [Call Routing](/docs/voice/xml/routing/) - Dial, Redirect, Hangup, Wait
* [Conference](/docs/voice/xml/conference/) - Conference calls
* [Multi-party Call](/docs/voice/xml/multiparty-call/) - Role-based multi-party calls
* [Recording](/docs/voice/xml/record/) - Record calls and messages
* [Audio Streaming](/docs/voice/xml/audio-streaming) - Stream real-time audio
# Record
Source: https://plivo.com/docs/voice/xml/record
Record calls, voicemails, and conversations
The `` element records audio from the call and returns the URL of the recording file. Use it for voicemail, call logging, or quality monitoring.
## Basic Usage
```xml theme={null}
Please leave a message after the beep.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Please leave a message after the beep.'))
response.add(plivoxml.RecordElement(action='https://example.com/handle-recording/'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak('Please leave a message after the beep.');
response.addRecord({ action: 'https://example.com/handle-recording/' });
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addSpeak('Please leave a message after the beep.')
response.addRecord(action: 'https://example.com/handle-recording/')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak('Please leave a message after the beep.');
$response->addRecord(['action' => 'https://example.com/handle-recording/']);
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new Speak("Please leave a message after the beep."),
new Record().action("https://example.com/handle-recording/")
);
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddSpeak("Please leave a message after the beep.");
response.AddRecord(new Dictionary() {
{"action", "https://example.com/handle-recording/"}
});
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).AddSpeak("Please leave a message after the beep."),
new(xml.RecordElement).Action("https://example.com/handle-recording/"),
},
}
print(response.String())
}
```
***
## Attributes
### Basic Settings
| Attribute | Type | Default | Description |
| ------------ | ------- | ------- | -------------------------------------- |
| `action` | URL | - | URL to receive recording data |
| `method` | string | `POST` | HTTP method for action (`GET`, `POST`) |
| `fileFormat` | string | `mp3` | Recording format (`mp3`, `wav`) |
| `redirect` | boolean | `true` | Redirect to action URL when complete |
### Timing
| Attribute | Type | Default | Description |
| ------------- | ------- | ------- | -------------------------------------------------- |
| `timeout` | integer | `15` | Seconds of silence before stopping |
| `maxLength` | integer | `60` | Maximum recording duration in seconds |
| `finishOnKey` | string | `#` | Key to stop recording (digit, `#`, `*`, or `none`) |
| `playBeep` | boolean | `true` | Play beep before recording |
### Session Recording
| Attribute | Type | Default | Description |
| ------------------- | ------- | -------- | ---------------------------------- |
| `recordSession` | boolean | `false` | Record entire call in background |
| `startOnDialAnswer` | boolean | `false` | Start recording when B-leg answers |
| `recordChannelType` | string | `stereo` | Channel type (`mono`, `stereo`) |
### Transcription
| Attribute | Type | Default | Description |
| ------------------------- | ------ | --------- | ------------------------------------------------------------------------------------------ |
| `transcriptionType` | string | - | Transcription type. Values: `auto`, `hybrid`, `manual` |
| `transcriptionUrl` | URL | - | URL to receive transcription |
| `transcriptionMethod` | string | `POST` | HTTP method for sending transcription results to `transcriptionUrl`. Values: `GET`, `POST` |
| `transcriptionReportType` | string | `compact` | Format of the transcription report. Values: `full`, `compact` |
### Callbacks
| Attribute | Type | Default | Description |
| ---------------- | ------ | ------- | ------------------------------------ |
| `callbackUrl` | URL | - | URL notified when recording is ready |
| `callbackMethod` | string | `POST` | HTTP method for callback |
***
## Voicemail
```xml theme={null}
You've reached John's voicemail.
Leave a message after the beep, press pound when finished.
Thank you for your message. Goodbye.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement(
"You've reached John's voicemail. Leave a message after the beep."
))
response.add(plivoxml.RecordElement(
action='https://example.com/save-voicemail/',
max_length=120,
finish_on_key='#',
play_beep=True
))
response.add(plivoxml.SpeakElement('Thank you for your message. Goodbye.'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak("You've reached John's voicemail. Leave a message after the beep.");
response.addRecord({
action: 'https://example.com/save-voicemail/',
maxLength: 120,
finishOnKey: '#',
playBeep: true
});
response.addSpeak('Thank you for your message. Goodbye.');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
response.addSpeak("You've reached John's voicemail.")
response.addRecord(
action: 'https://example.com/save-voicemail/',
maxLength: 120,
finishOnKey: '#',
playBeep: true
)
response.addSpeak('Thank you for your message.')
puts Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak("You've reached John's voicemail.");
$response->addRecord([
'action' => 'https://example.com/save-voicemail/',
'maxLength' => 120,
'finishOnKey' => '#',
'playBeep' => true
]);
$response->addSpeak('Thank you for your message.');
echo $response->toXML();
```
***
## Record Entire Session
Record the complete call in the background:
```xml theme={null}
This call is being recorded for quality purposes.
+14155551234
```
**Notes:**
* Recording starts immediately and continues until the call ends
* `timeout`, `finishOnKey`, and `playBeep` are ignored
* Recording is sent to `callbackUrl` when complete
***
## Record Dial Conversation
Record both parties after the dial connects:
```xml theme={null}
+14155551234
```
***
## Stereo vs Mono Recording
**Stereo** (default): Each party on separate audio channels - useful for call analytics.
**Mono**: Both parties on single channel - smaller file size.
```xml theme={null}
```
***
## With Transcription
Get automatic speech-to-text:
```xml theme={null}
Please leave your message.
```
**Transcription limits:**
* English only
* Duration: 500ms to 4 hours
* File size: under 2GB
***
## Action URL Parameters
Sent when recording completes:
| Parameter | Description |
| --------------------- | ---------------------------- |
| `RecordUrl` | URL of the recording file |
| `RecordingID` | Unique recording identifier |
| `RecordingDuration` | Duration in seconds |
| `RecordingDurationMs` | Duration in milliseconds |
| `RecordingStartMs` | Start time (epoch ms) |
| `RecordingEndMs` | End time (epoch ms) |
| `Digits` | Key pressed to stop (if any) |
**Note:** When `recordSession` or `startOnDialAnswer` is `true`, duration values are `-1` in the initial request. Final values are sent to `callbackUrl`.
***
## Callback URL Parameters
Sent when recording file is ready:
| Parameter | Description |
| --------------------- | ------------------------- |
| `RecordUrl` | URL of the recording file |
| `RecordingID` | Recording identifier |
| `RecordingDuration` | Duration in seconds |
| `RecordingDurationMs` | Duration in milliseconds |
| `RecordingStartMs` | Start time (epoch ms) |
| `RecordingEndMs` | End time (epoch ms) |
***
## Transcription URL Parameters
| Parameter | Description |
| ---------------------- | ------------------------- |
| `transcription` | Transcribed text |
| `transcription_charge` | Cost of transcription |
| `transcription_rate` | Rate per minute |
| `duration` | Recording duration |
| `call_uuid` | Call identifier |
| `recording_id` | Recording identifier |
| `error` | Error message (if failed) |
***
## Best Practices
1. **Inform callers** - Always notify that the call is being recorded (legal requirement in many jurisdictions)
2. **Set appropriate limits** - Use `maxLength` to prevent very long recordings
3. **Use callbacks** - Use `callbackUrl` for reliable notification when recording is ready
4. **Choose format wisely** - MP3 for smaller files, WAV for highest quality
5. **Handle storage** - Download recordings from Plivo; they're deleted after 30 days
***
## Related
* [Conference](/docs/voice/xml/conference/) - Record conference calls
* [Recordings API](/docs/voice/api/recordings/) - Manage recordings
* [Play](/docs/voice/xml/audio-output#play) - Play recorded audio
# Call Routing
Source: https://plivo.com/docs/voice/xml/routing
Connect calls, transfer flow, end calls, and pause execution
This page covers the XML elements for call routing: connecting to other parties, transferring call flow, ending calls, and pausing execution.
***
## Dial
The `` element connects the current call to another phone number, SIP endpoint, or Plivo user. When the dialed party answers, both parties are connected. When either party hangs up, the connection ends.
### Basic Usage
```xml theme={null}
+14155551234
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155551234'))
response.add(dial)
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const dial = response.addDial();
dial.addNumber('+14155551234');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
dial = response.addDial()
dial.addNumber('+14155551234')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addDial();
$dial->addNumber('+14155551234');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new Dial().children(new Number("+14155551234"))
);
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
var dial = new Dial();
dial.AddNumber("+14155551234");
response.Add(dial);
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.DialElement).SetContents([]interface{}{
new(xml.NumberElement).SetContents("+14155551234"),
}),
},
}
print(response.String())
}
```
### Dial Attributes
| Attribute | Type | Default | Description |
| -------------- | ------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `action` | URL | - | URL to receive dial completion status |
| `method` | string | `POST` | HTTP method for action URL (`GET`, `POST`) |
| `timeout` | integer | - | Seconds to wait for answer |
| `timeLimit` | integer | `14400` | Maximum call duration in seconds |
| `callerId` | string | caller's ID | Caller ID to display |
| `callerName` | string | caller's name | Caller name (max 50 chars) |
| `hangupOnStar` | boolean | `false` | Let caller hang up B-leg by pressing \* |
| `redirect` | boolean | `true` | Redirect to action URL when complete |
| `callType` | string | `voice` | Type of call. Values: `voice`, `whatsapp`. When set to `whatsapp`, the call is placed as a WhatsApp voice call (cannot route to PSTN, does not support machine detection) |
#### Callback Attributes
| Attribute | Type | Description |
| ----------------- | ------- | -------------------------------------------- |
| `callbackUrl` | URL | URL for real-time dial events |
| `callbackMethod` | string | HTTP method for callback (`GET`, `POST`) |
| `confirmSound` | URL | URL returning XML to play when B-leg answers |
| `confirmKey` | string | Key B-leg must press to accept call |
| `confirmTimeout` | integer | Seconds to wait for confirm key |
| `dialMusic` | URL | URL returning XML for ringback, or `real` |
| `digitsMatch` | string | DTMF patterns to report (A-leg) |
| `digitsMatchBLeg` | string | DTMF patterns to report (B-leg) |
| `sipHeaders` | string | Custom SIP headers (key=value,key2=value2) |
### Nested Elements
`` must contain at least one nested element:
#### Number Element
Dial a phone number:
```xml theme={null}
+14155551234
```
**Number Attributes:**
| Attribute | Type | Default | Description |
| ----------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
| `sendDigits` | string | - | DTMF digits to send after answer. Use `w` for 0.5s pause |
| `sendDigitsMode` | string | - | Mode for sending DTMF digits. Values: `rfc2833`. When set, uses RFC 2833 telephone-event packets instead of inband DTMF |
| `sendOnPreanswer` | boolean | `false` | Send digits during early media |
| `sipHeaders` | string | - | Custom SIP headers in `key=value` format, specific to this number within the dial |
#### User Element
Dial a SIP endpoint:
```xml theme={null}
sip:alice@example.com
```
**User Attributes:**
| Attribute | Type | Default | Description |
| ----------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sipHeaders` | string | - | Custom SIP headers in `key=value` format, specific to this user within the dial |
| `sipAuthUsername` | string | - | SIP digest authentication username. Used when calling a SIP endpoint that requires authentication (responds with 401/407 challenge). Must be paired with `sipAuthPassword`. See [SIP Authentication](/docs/voice/concepts/sip-authentication/). |
| `sipAuthPassword` | string | - | SIP digest authentication password (8-128 characters). Required when `sipAuthUsername` is provided. Credentials are stripped before forwarding calls externally. |
Attribute names are camelCase (`sipAuthUsername`, not `sip_auth_username`).
**Authenticated SIP call example:**
```xml theme={null}
sip:endpoint@provider.example.com
```
**Hangup causes on auth failure:**
If outbound SIP authentication fails, the Dial action URL receives these values:
| DialHangupCause | Code | DialStatus | Meaning |
| ------------------ | ------ | ---------- | ----------------------------------------------------- |
| `sip_auth_failed` | `4240` | `failed` | Remote provider rejected the credentials |
| `sip_auth_timeout` | `4250` | `timeout` | Remote provider did not respond to the auth challenge |
**Reserved `sipHeaders` prefixes:**
Customer `sipHeaders` keys with the following prefixes (case-insensitive) are silently dropped: `PH-`, `Plivo`, `FS-`, `SipAuth`, `ZT-`, `Twilio`. The exact name `ClientRegion` is also reserved. See [SIP Authentication](/docs/voice/concepts/sip-authentication/) for details.
**Raw-mode rendering with SIP authentication:**
When the inbound leg used SIP authentication, `sipHeaders` are emitted on the outbound B-leg INVITE without the `X-PH-` prefix (e.g., `CustomerId=123` renders as `X-CustomerId: 123` rather than `X-PH-CustomerId: 123`).
### Simultaneous Dialing
Ring multiple numbers at once. First to answer is connected:
```xml theme={null}
+14155551111
+14155552222
+14155553333
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155551111'))
dial.add(plivoxml.NumberElement('+14155552222'))
dial.add(plivoxml.NumberElement('+14155553333'))
response.add(dial)
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const dial = response.addDial();
dial.addNumber('+14155551111');
dial.addNumber('+14155552222');
dial.addNumber('+14155553333');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
response = Plivo::XML::Response.new
dial = response.addDial()
dial.addNumber('+14155551111')
dial.addNumber('+14155552222')
dial.addNumber('+14155553333')
puts Plivo::XML::PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addDial();
$dial->addNumber('+14155551111');
$dial->addNumber('+14155552222');
$dial->addNumber('+14155553333');
echo $response->toXML();
```
### Sequential Dialing
Try numbers one at a time with timeouts:
```xml theme={null}
+14155551111
+14155552222
Sorry, no one is available. Please try again later.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
# First attempt
dial1 = plivoxml.DialElement(timeout=15, action='/dial-status/')
dial1.add(plivoxml.NumberElement('+14155551111'))
response.add(dial1)
# Second attempt
dial2 = plivoxml.DialElement(timeout=15, action='/dial-status/')
dial2.add(plivoxml.NumberElement('+14155552222'))
response.add(dial2)
response.add(plivoxml.SpeakElement('Sorry, no one is available.'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const dial1 = response.addDial({ timeout: 15, action: '/dial-status/' });
dial1.addNumber('+14155551111');
const dial2 = response.addDial({ timeout: 15, action: '/dial-status/' });
dial2.addNumber('+14155552222');
response.addSpeak('Sorry, no one is available.');
console.log(response.toXML());
```
### Dial with Confirmation
Require the called party to press a key to accept:
```xml theme={null}
+14155551234
```
The `confirmSound` URL should return XML like:
```xml theme={null}
Press 1 to accept this call.
```
### Custom Caller ID
```xml theme={null}
+14155551234
```
### Custom Ringback
Play custom audio instead of the standard ring:
```xml theme={null}
+14155551234
```
Use `dialMusic="real"` to play the actual ringtone from the carrier.
### Dial Extensions
Send DTMF tones after the call connects (useful for extensions):
```xml theme={null}
+14155551234
```
Each `w` adds a 0.5-second pause. This example waits 2 seconds, then dials extension 1234.
### Dial Action URL Parameters
When the dial completes, these parameters are sent to the `action` URL:
| Parameter | Description |
| ----------------- | --------------------------------------------------------------- |
| `DialStatus` | `completed`, `busy`, `failed`, `cancel`, `timeout`, `no-answer` |
| `DialRingStatus` | `true` or `false` - whether the call rang |
| `DialHangupCause` | Standard telephony hangup cause |
| `DialALegUUID` | Call UUID of the A-leg (original caller) |
| `DialBLegUUID` | Call UUID of the B-leg (empty if not answered) |
### Dial Callback URL Parameters
Real-time events sent to `callbackUrl`:
| Parameter | Description |
| ------------------------- | ----------------------------------------- |
| `DialAction` | `answer`, `connected`, `hangup`, `digits` |
| `DialBLegStatus` | B-leg status |
| `DialALegUUID` | A-leg call UUID |
| `DialBLegUUID` | B-leg call UUID |
| `DialBLegDuration` | Call duration (on hangup) |
| `DialBLegBillDuration` | Billed duration (on hangup) |
| `DialBLegFrom` | B-leg caller number |
| `DialBLegTo` | B-leg destination |
| `DialDigitsMatch` | Matched DTMF digits |
| `DialDigitsPressedBy` | `ALeg` or `BLeg` |
| `DialBLegHangupCauseName` | Hangup reason |
| `DialBLegHangupCauseCode` | Hangup code |
| `DialBLegHangupSource` | Who hung up |
| `STIRVerification` | STIR/SHAKEN attestation |
### Dial to SIP
```xml theme={null}
sip:alice@sip.example.com
```
***
## Redirect
The `` element transfers call execution to a different URL. Plivo fetches new XML instructions from the specified URL and continues the call.
### Basic Usage
```xml theme={null}
https://example.com/new-flow/
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.RedirectElement('https://example.com/new-flow/'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addRedirect('https://example.com/new-flow/');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addRedirect('https://example.com/new-flow/')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addRedirect('https://example.com/new-flow/');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(new Redirect("https://example.com/new-flow/"));
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddRedirect("https://example.com/new-flow/");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.RedirectElement).SetContents("https://example.com/new-flow/"),
},
}
print(response.String())
}
```
### Redirect Attributes
| Attribute | Type | Default | Description |
| --------- | ------ | ------- | ---------------------------------- |
| `method` | string | `POST` | HTTP method to use (`GET`, `POST`) |
### Dynamic Routing
Redirect based on conditions:
```python theme={null}
@app.route('/route-call/', methods=['POST'])
def route_call():
caller = request.form.get('From')
response = plivoxml.ResponseElement()
# VIP callers get priority queue
if is_vip(caller):
response.add(plivoxml.RedirectElement('https://example.com/vip-queue/'))
else:
response.add(plivoxml.RedirectElement('https://example.com/standard-queue/'))
return Response(response.to_string(), mimetype='application/xml')
```
### After Dial Failure
Redirect when a dial attempt fails:
```xml theme={null}
+14155551234
https://example.com/voicemail/
```
If the dial fails or times out, the call redirects to voicemail.
### Conditional IVR Flow
```xml theme={null}
Press 1 for English, press 2 for Spanish.
https://example.com/ivr-timeout/
```
### Menu Loop
Create a menu that returns to itself:
```python theme={null}
@app.route('/main-menu/', methods=['POST'])
def main_menu():
digits = request.form.get('Digits', '')
response = plivoxml.ResponseElement()
if digits == '1':
response.add(plivoxml.RedirectElement('https://example.com/sales/'))
elif digits == '2':
response.add(plivoxml.RedirectElement('https://example.com/support/'))
elif digits == '9':
# Repeat menu
getdigits = plivoxml.GetDigitsElement(
action='https://example.com/main-menu/',
numDigits=1
)
getdigits.add(plivoxml.SpeakElement('Press 1 for sales, 2 for support, 9 to repeat.'))
response.add(getdigits)
response.add(plivoxml.RedirectElement('https://example.com/main-menu/'))
else:
response.add(plivoxml.SpeakElement('Invalid option.'))
response.add(plivoxml.RedirectElement('https://example.com/main-menu/'))
return Response(response.to_string(), mimetype='application/xml')
```
### Redirect with GET Method
```xml theme={null}
https://example.com/next-step/?lang=en
```
### Redirect Request Parameters
When Plivo calls the redirect URL, it includes all standard [request parameters](/docs/voice/xml/overview/#request-parameters):
| Parameter | Description |
| ------------ | ----------------------- |
| `CallUUID` | Unique call identifier |
| `From` | Caller's number |
| `To` | Called number |
| `CallStatus` | Current call status |
| `Direction` | `inbound` or `outbound` |
### Redirect Best Practices
1. **Avoid infinite loops** - Ensure redirects eventually lead to an endpoint that doesn't redirect
2. **Handle errors** - Your redirect URL should always return valid XML
3. **Use HTTPS** - All URLs should use HTTPS
4. **Pass context** - Use query parameters to pass state between endpoints
***
## Hangup
The `` element terminates the current call. Use it to gracefully end calls after completing a flow.
### Basic Usage
```xml theme={null}
Thank you for calling. Goodbye!
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Thank you for calling. Goodbye!'))
response.add(plivoxml.HangupElement())
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak('Thank you for calling. Goodbye!');
response.addHangup();
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addSpeak('Thank you for calling. Goodbye!')
response.addHangup()
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak('Thank you for calling. Goodbye!');
$response->addHangup();
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new Speak("Thank you for calling. Goodbye!"),
new Hangup()
);
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddSpeak("Thank you for calling. Goodbye!");
response.AddHangup();
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).AddSpeak("Thank you for calling. Goodbye!"),
new(xml.HangupElement),
},
}
print(response.String())
}
```
### Hangup Attributes
| Attribute | Type | Default | Description |
| ---------- | ------- | ------- | --------------------------------- |
| `reason` | string | - | Hangup reason: `rejected`, `busy` |
| `schedule` | integer | - | Seconds to wait before hanging up |
### Scheduled Hangup
End the call after a delay:
```xml theme={null}
This call will end in 60 seconds.
https://example.com/hold-music.mp3
```
This schedules a hangup while continuing to execute subsequent elements.
### Reject with Reason
Provide a hangup reason to simulate different call states:
```xml theme={null}
```
| Reason | Effect |
| ---------- | --------------------------- |
| `rejected` | Caller hears rejection tone |
| `busy` | Caller hears busy signal |
### After IVR Timeout
```xml theme={null}
Press 1 to continue.
We didn't receive any input. Goodbye.
```
### After Business Hours
```python theme={null}
@app.route('/answer/', methods=['POST'])
def answer():
response = plivoxml.ResponseElement()
if not is_business_hours():
response.add(plivoxml.SpeakElement(
'Our office is currently closed. Please call back during business hours.'
))
response.add(plivoxml.HangupElement())
else:
response.add(plivoxml.SpeakElement('Welcome! Please hold.'))
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155551234'))
response.add(dial)
return Response(response.to_string(), mimetype='application/xml')
```
### Block Spam Callers
```python theme={null}
@app.route('/answer/', methods=['POST'])
def answer():
caller = request.form.get('From')
response = plivoxml.ResponseElement()
if is_blocked(caller):
response.add(plivoxml.HangupElement(reason='rejected'))
else:
response.add(plivoxml.SpeakElement('Hello! How can I help you?'))
# Continue with normal flow
return Response(response.to_string(), mimetype='application/xml')
```
### Implicit Hangup
If your XML doesn't end with ``, the call automatically ends when all elements are executed. However, it's good practice to include it explicitly for clarity.
***
## Wait
The `` element pauses call execution for a specified duration. Use it for hold times, delays, or with answering machine detection.
### Basic Usage
```xml theme={null}
Please hold while we connect you.
Thank you for waiting.
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement('Please hold while we connect you.'))
response.add(plivoxml.WaitElement(length=5))
response.add(plivoxml.SpeakElement('Thank you for waiting.'))
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
response.addSpeak('Please hold while we connect you.');
response.addWait({ length: 5 });
response.addSpeak('Thank you for waiting.');
console.log(response.toXML());
```
```ruby Ruby theme={null}
require 'plivo'
include Plivo::XML
response = Response.new
response.addSpeak('Please hold while we connect you.')
response.addWait(length: 5)
response.addSpeak('Thank you for waiting.')
puts PlivoXML.new(response).to_xml
```
```php PHP theme={null}
addSpeak('Please hold while we connect you.');
$response->addWait(['length' => 5]);
$response->addSpeak('Thank you for waiting.');
echo $response->toXML();
```
```java Java theme={null}
import com.plivo.api.xml.*;
Response response = new Response()
.children(
new Speak("Please hold while we connect you."),
new Wait().length(5),
new Speak("Thank you for waiting.")
);
System.out.println(response.toXmlString());
```
```csharp .NET theme={null}
using Plivo.XML;
var response = new Response();
response.AddSpeak("Please hold while we connect you.");
response.AddWait(new Dictionary() { {"length", "5"} });
response.AddSpeak("Thank you for waiting.");
Console.WriteLine(response.ToString());
```
```go Go theme={null}
package main
import "github.com/plivo/plivo-go/v7/xml"
func main() {
response := xml.ResponseElement{
Contents: []interface{}{
new(xml.SpeakElement).AddSpeak("Please hold."),
new(xml.WaitElement).Length(5),
new(xml.SpeakElement).AddSpeak("Thank you for waiting."),
},
}
print(response.String())
}
```
### Wait Attributes
| Attribute | Type | Default | Description |
| ------------ | ------- | ------- | --------------------------------------- |
| `length` | integer | `1` | Seconds to wait |
| `silence` | boolean | `false` | Play silence (vs default hold music) |
| `minSilence` | integer | - | Minimum silence milliseconds to detect |
| `beep` | string | - | Detect beeps: `true` or beep parameters |
### Silent Wait
By default, `` plays hold music. For silence:
```xml theme={null}
```
### Delayed Call Answer
Use `` to delay answering (useful for screening):
```xml theme={null}
Hello, you've reached Acme Corp.
```
### Answering Machine Detection
Detect answering machines by listening for beeps:
```xml theme={null}
Hello, this is an automated message from Acme Corp.
```
#### Beep Detection Parameters
For fine-grained control, pass beep parameters as a comma-separated string:
```xml theme={null}
```
| Parameter | Default | Description |
| --------------- | ------- | ---------------------------------- |
| `duration` | 300 | Beep duration in ms to match |
| `inter_silence` | 50 | Silence between beeps (ms) |
| `intra_silence` | 500 | Silence after beep to confirm (ms) |
| `threshold` | 256 | Audio level threshold |
### Silence Detection
Detect when the other party stops speaking:
```xml theme={null}
It seems like you're done speaking.
```
`minSilence` is the minimum silence duration in milliseconds to trigger detection.
### Machine Detection Flow
Combine with `` for voicemail drops:
```xml theme={null}
Hello, this is a reminder from Dr. Smith's office
about your appointment tomorrow at 2 PM.
Please call us at 555-1234 to confirm.
```
### Use in PreAnswer
Delay before answering the call:
```xml theme={null}
https://example.com/ring.mp3
Hello, thank you for calling.
```
***
## PreAnswer
The `` element plays audio to the caller before the call is answered. This is useful for custom ringback tones or screening calls. The caller is not billed during this phase.
### Basic Usage
```xml theme={null}
Please wait while we connect your call.
+14155551234
```
```python Python theme={null}
from plivo import plivoxml
response = plivoxml.ResponseElement()
preanswer = plivoxml.PreAnswerElement()
preanswer.add(plivoxml.SpeakElement('Please wait while we connect your call.'))
response.add(preanswer)
dial = plivoxml.DialElement()
dial.add(plivoxml.NumberElement('+14155551234'))
response.add(dial)
print(response.to_string())
```
```javascript Node.js theme={null}
const plivo = require('plivo');
const response = plivo.Response();
const preanswer = response.addPreAnswer();
preanswer.addSpeak('Please wait while we connect your call.');
const dial = response.addDial();
dial.addNumber('+14155551234');
console.log(response.toXML());
```
### Nested Elements
`` can contain:
* `` - Text-to-speech messages
* `` - Audio files
* `` - Pauses
### Custom Ringback
Play music while connecting:
```xml theme={null}
https://example.com/custom-ringback.mp3
+14155551234
```
### Use Cases
| Use Case | Description |
| --------------- | -------------------------------------------- |
| Custom ringback | Replace standard ring with music or branding |
| Legal notices | "This call may be recorded" disclaimers |
| Spam screening | Delay answering to deter robocalls |
| Queue position | "You are caller number 3" before answering |
### Limitations
* Only `Speak`, `Play`, and `Wait` elements are allowed
* Call is not "answered" during PreAnswer, so some carriers may timeout
* Recommended to keep PreAnswer duration under 30 seconds
***
## Related
* [Audio Output](/docs/voice/xml/audio-output/) - Speak, Play, DTMF
* [Input Collection](/docs/voice/xml/input/) - GetDigits, GetInput
* [Conference](/docs/voice/xml/conference/) - Conference calls
* [Multi-party Call](/docs/voice/xml/multiparty-call/) - Role-based multi-party calls
* [Audio Streaming](/docs/voice/xml/audio-streaming/) - Stream real-time audio
# Configure Number Modal
Source: https://plivo.com/docs/whatsapp/console/configure-number
UI reference for the Configure Number side panel — Alias, Configuration Type, Webhook URL, WhatsApp Calling, Answer URL, and Account Mapping
* **Where:** Click a number on the [WhatsApp Numbers page](https://cx.plivo.com/whatsapp/numbers) to open the **Configure Number** side panel
* **Required:** **Webhook URL** (for inbound messages). If you enable WhatsApp Calling, **Answer URL** is also required
* **Optional:** Alias, AI Agents configuration, Account Mapping
* **Critical:** Account Mapping applies to the entire WABA — changing it for one number changes it for every number linked to that WABA
The **Configure Number** side panel is where you wire a WhatsApp number to your application — Webhook URL for inbound messages, Answer URL for voice calls, and the Plivo account that should own the traffic.
***
## Fields
### Number Type and Capabilities
Read-only summary at the top of the panel:
* **Phone number and country** of the WhatsApp number
* **Capabilities** badge — `WhatsApp` indicates the number is WhatsApp-enabled
### Alias
Optional friendly label for the number. Use it to distinguish numbers in lists when you operate multiple WhatsApp numbers — for example, `Support — APAC` or `Sales — EU`.
### Configuration Type
Choose how inbound messages and calls are handled:
| Option | When to use |
| --------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Webhook URL** | You handle inbound messages and calls with your own backend |
| **AI Agents** | You're using a Plivo AI Agent to handle the conversation — see [Voice Agents](/docs/voice-agents/audio-streaming/overview) |
### Webhook URL
Required when Configuration Type is **Webhook URL**. The endpoint that receives inbound message events (text, media, replies, status updates) from your WhatsApp number.
* Must be a valid HTTPS URL — for example, `https://yourdomain.com/whatsapp/webhook`
* Must respond with `200 OK` to acknowledge receipt
* See [Inbound Messages](/docs/messaging/use-cases/whatsapp/getting-started/inbound-message/inbound-message) for payload details
### Enable WhatsApp Calling
Toggle to enable voice calling on the number. When on, users see a call button next to your WhatsApp number in the WhatsApp app, and you can place outbound calls using `callType: whatsapp` in the [Dial XML element](/docs/voice/xml/routing#dial).
When the toggle is on, the **Answer URL** field below becomes required.
### Answer URL
Required when **Enable WhatsApp Calling** is on. The endpoint that handles inbound voice calls — Plivo POSTs to this URL when a call arrives, and your endpoint must return [Plivo XML](/docs/voice/xml/overview/) instructions.
* Must be a valid HTTPS URL — for example, `https://yourdomain.com/whatsapp/answer`
* Must return valid Plivo XML
* See [WhatsApp Calling](/docs/messaging/concepts/whatsapp/whatsapp-calling) for the full call-flow guide
### Account Mapping
Choose which Plivo account owns the WhatsApp traffic and billing:
* **Main Account** — default; the WABA reports to your main account
* **Subaccount** — route the WABA to a specific subaccount (useful for multi-team or multi-tenant setups)
**Account Mapping applies to the entire WhatsApp Business Account.** It affects every number linked to this WABA, not just the number you're configuring. Changing this setting for one number changes it for all numbers under the same WABA.
***
## Actions
### Save changes
Click **Save changes** to apply your configuration. Plivo validates URLs and stores the configuration immediately — no propagation delay.
### Disconnect number
Click **Disconnect number** in the bottom left to remove the number from your Plivo account. The number stays with Meta — only the Plivo connection is severed. Disconnecting stops inbound webhook delivery and disables outbound API access for that number.
**Disconnecting is reversible but disruptive.** You can reconnect the number later, but any in-flight conversations break and you'll need to reconfigure Webhook URL, Answer URL, and Account Mapping from scratch.
***
## Related
* [WhatsApp Numbers Page](/docs/whatsapp/console/numbers-page)
* [Connect WhatsApp Number](/docs/whatsapp/console/connect-number)
* [WhatsApp Calling](/docs/messaging/concepts/whatsapp/whatsapp-calling)
* [Inbound Messages tutorial](/docs/messaging/use-cases/whatsapp/getting-started/inbound-message/inbound-message)
* [Plivo XML Reference](/docs/voice/xml/overview/)
# Connect WhatsApp Number
Source: https://plivo.com/docs/whatsapp/console/connect-number
Choose how to onboard a WhatsApp number with Plivo — connect a WhatsApp Business app, bring your own number, or use a Plivo number
* **Where:** Click **Connect WhatsApp Number** on the [WhatsApp Numbers page](https://cx.plivo.com/whatsapp/numbers)
* **Three onboarding paths:**
1. **Connect your WhatsApp Business app** — link the WhatsApp Business app you already use on your phone
2. **Connect your own Number** — share an existing WhatsApp Business account with Plivo while keeping your own access
3. **Connect your Plivo Number** — use an existing Plivo number (or buy a new one) to set up a fresh WhatsApp Business Account
When you click **Connect WhatsApp Number** on the [WhatsApp Numbers page](https://cx.plivo.com/whatsapp/numbers), Plivo asks how you want to onboard. Pick the path that matches the number you're bringing.
***
## Option 1: Connect your WhatsApp Business app
Link the WhatsApp Business app you already use on your phone. You continue to use the app as usual — Plivo connects to the same number so you can send and receive messages via API in addition to the app.
**Choose this when:** You run your business on the WhatsApp Business mobile app today and want to add API access without changing how you use the app.
***
## Option 2: Connect your own Number
Share your existing WhatsApp Business account with Plivo. You retain full access to your WhatsApp Business app and Meta Business Manager — Plivo is added as a Business Solution Provider (BSP) so you can use the API alongside your existing setup.
**Choose this when:** You already have a WABA with another BSP or directly with Meta, and you want to use Plivo's API without migrating away from your current setup.
***
## Option 3: Connect your Plivo Number
Use an existing Plivo number — or buy a new one — to create a fresh WhatsApp Business Account through Plivo. Plivo handles WABA creation and number registration through Meta's Embedded Signup.
**Choose this when:** You're starting fresh on WhatsApp and want Plivo to set up the WABA end-to-end.
***
## Next steps
After picking an option, follow the on-screen flow to complete onboarding. Once your number appears on the [Numbers page](/docs/whatsapp/console/numbers-page) with status **Connected**, open the [Configure Number](/docs/whatsapp/console/configure-number) panel to set your Webhook URL and (optionally) enable WhatsApp Calling.
***
## Related
* [WhatsApp Numbers Page](/docs/whatsapp/console/numbers-page)
* [Configure Number](/docs/whatsapp/console/configure-number)
* [WABA Onboarding](/docs/messaging/concepts/whatsapp/waba-onboarding)
* [Prerequisites](/docs/messaging/concepts/whatsapp/prerequisites)
# WhatsApp Numbers Page
Source: https://plivo.com/docs/whatsapp/console/numbers-page
UI reference for the WhatsApp Numbers tab in the Plivo console — view status, name approval, quality rating, and configuration for every WhatsApp number
* **Where:** [WhatsApp → Numbers](https://cx.plivo.com/whatsapp/numbers) in the Plivo console
* **What:** Lists every WhatsApp number connected to your account with its WABA, status, name approval, quality rating, and configuration type
* **Key actions:** Click a row to open the [Configure Number](/docs/whatsapp/console/configure-number) panel, click **Sync Numbers** to refresh from Meta, click **Connect WhatsApp Number** to onboard a new number
The Numbers tab is your control surface for every WhatsApp number connected to your Plivo account. Open it at [cx.plivo.com/whatsapp/numbers](https://cx.plivo.com/whatsapp/numbers).
***
## Columns
| Column | What it shows |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Phone Number** | The WhatsApp-enabled number, with a country flag. An **External Number** badge marks numbers brought to Plivo from a different BSP. |
| **WA Business Account** | The WhatsApp Business Account (WABA) the number is linked to |
| **Status** | Connection status with Plivo — **Connected** (live) or **Pending** (still being provisioned) |
| **Name Status** | Meta's review state for your display name — **Approved**, **Declined**, or **Available Without Review** |
| **Quality Rating** | Meta's quality score for the number — **Green** (high), **Yellow** (medium), **Red** (low), or **Unknown** if not yet rated |
| **Configuration** | Shows whether the number is connected to an **Agent** (with the agent name) or a Webhook URL. Pending numbers may show no configuration. |
***
## Actions
### Connect WhatsApp Number
Click **Connect WhatsApp Number** in the top right to onboard a new number. You're prompted to choose between three paths — see [Connect WhatsApp Number](/docs/whatsapp/console/connect-number) for the full walkthrough.
### Sync Numbers
Click **Sync Numbers** to pull the latest state from Meta. Run a sync after any change in WhatsApp Manager (name update, quality rating change, number addition) to bring the Plivo console up to date.
### Configure a number
Click any row to open the **Configure Number** side panel. Set the Webhook URL, enable WhatsApp Calling, set the Answer URL, and choose Account Mapping. See [Configure Number](/docs/whatsapp/console/configure-number) for the full UI reference.
### Search and filter
* **Search** by number or WABA name using the search bar
* **Filter by status** using the **Status** filter
***
## Related
* [Connect WhatsApp Number](/docs/whatsapp/console/connect-number)
* [Configure Number](/docs/whatsapp/console/configure-number)
* [WABA Onboarding](/docs/messaging/concepts/whatsapp/waba-onboarding)
* [WhatsApp Calling](/docs/messaging/concepts/whatsapp/whatsapp-calling)
# WhatsApp Templates Page
Source: https://plivo.com/docs/whatsapp/console/templates-page
UI reference for the WhatsApp Templates tab — browse approved templates, sync from Meta, and create new templates with a live preview
* **Where:** [WhatsApp → Templates](https://cx.plivo.com/whatsapp/templates) in the Plivo console
* **What:** Browse every template across your WABAs, filter by status and category, sync from Meta, and create new templates with a side-by-side WhatsApp preview
* **Approval:** Meta reviews new templates — approval typically takes minutes but can take up to 24 hours
The Templates tab is where you manage every WhatsApp message template across your WhatsApp Business Accounts. Open it at [cx.plivo.com/whatsapp/templates](https://cx.plivo.com/whatsapp/templates).
For deeper context on what templates are, how Meta categorizes them, and how they're billed, see [Manage Templates](/docs/messaging/concepts/whatsapp/manage-templates).
***
## Template list
Each row in the table represents one template, with these columns:
| Column | What it shows |
| -------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Template Name** | The Meta-approved template name (used as `template_name` in the [Templates API](/docs/messaging/api/whatsapp-templates)) |
| **Status** | Review state — **Approved**, **Pending**, **Rejected**, **Disabled**, or **Paused** |
| **Category** | Meta category — **Marketing**, **Utility**, or **Authentication** |
| **Language** | Template language (for example, `English`, `Spanish`) |
| **Business Account** | The WABA this template belongs to |
### Filters and search
* **Search by name** — narrow the list to templates matching a name fragment
* **Status filter** — filter by Approved, Pending, Rejected, Disabled, or Paused
* **Category filter** — filter by Marketing, Utility, or Authentication
### Sync Templates
Click **Sync Templates** to pull the latest template state from Meta. Run a sync after creating or editing templates in WhatsApp Manager so the Plivo console reflects current approval status.
***
## Create Template
Click **Create Template** to open the **Create WhatsApp Template** modal. The modal has two panes — a configuration form on the left and a live WhatsApp preview on the right (with Light mode and Dark mode tabs).
### Template configuration
| Field | Required | What it sets |
| ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Name** | Yes | Internal name used to reference the template in the API. Must be unique within the WABA — lowercase letters, numbers, and underscores only |
| **WhatsApp Business Account** | Yes | The WABA the template will live in |
| **Category** | Yes | **Utility**, **Marketing**, or **Authentication** — drives Meta's review path and conversation pricing |
| **Language** | Yes | The template language — defaults to **English** |
### Template content
| Field | What it sets |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Header Type** | Optional header — **None**, **Text**, **Image**, **Video**, **Document**, or **Location** |
| **Body** | The main message text — up to 1,024 characters. Use `{{1}}`, `{{2}}`, ... as variable placeholders, and the toolbar to add **bold**, *italic*, ~~strikethrough~~, and emoji |
The preview pane on the right renders your template as it will appear in the WhatsApp chat, with variables shown as `{{1}}`, `{{2}}` placeholders.
### Actions
| Button | Result |
| ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Cancel** | Closes the modal without saving |
| **Save as Draft** | Saves the template locally on Plivo without submitting to Meta — pick it up later to finish and submit |
| **Send for Verification** | Submits the template to Meta for approval. The template's Status remains **Pending** until Meta reviews it |
Meta typically approves new templates within minutes but can take up to 24 hours. Follow [Meta's template guidelines](https://developers.facebook.com/docs/whatsapp/message-templates/guidelines/) for the fastest turnaround.
***
## Related
* [Manage Templates](/docs/messaging/concepts/whatsapp/manage-templates) — Conceptual overview of WhatsApp templates
* [WhatsApp Templates API](/docs/messaging/api/whatsapp-templates) — Create and manage templates programmatically
* [Send Templated Messages](/docs/messaging/use-cases/whatsapp/getting-started/templated-message/send-whatsapp-template/send-whatsapp-template) — Send a template message