The following document describes the Call Control- and Notify-API by Placetel.
This API is part of our PROFI product line and comes in two operating modes:
- a simple notification API, which notifies your API endpoint about new incoming and outgoing calls, when calls are accepted (only for incoming calls) and when a call ends
- an advanced call control mechanism, set up in the routing of each number, which asks your API endpoint how to handle an incoming call
To enable both APIs, go to Settings → External APIs in the Placetel Webportal and provide the URL of your API endpoint.
Call notifications are activated per phone number. Use the checkboxes on Settings → Exsternal APIs or the the Checkbox in the Miscellaneous-tab in the routing settings of each number.
Outgoing calls are only notified if the caller ID of the used SIP user is set and the number is enabled for notifications.
Change the routing of your number to External API. The amount of retries to contact your API can be raised up to 10, we wait for 100ms after each retry.
Select a backup routing plan, which will be used in case of an error and an announcement, which will be played before processing your response.
We will send a POST
request with an application/x-www-form-urlencoded
payload to your API endpoint for every event.
Each event will have an call id to identify the call it belongs to. This call id will be a hex presentation of a SHA256
hash.
In order to verify the authenticity of our request on your side, we're using an HMAC with SHA256.
You can configure the shared secret in your external api settings. After that, every request will have the HTTP Header X-PLACETEL-SIGNATURE
.
You can calculate the signature and compare it to our signature in X-PLACETEL-SIGNATURE
:
require 'openssl'
secret = 'THE_SECRET'
payload = 'POSTED_PAYLOAD'
digest = OpenSSL::Digest.new('sha256')
signature = OpenSSL::HMAC.hexdigest(digest, secret, payload)
For example a secret 12345
with a given payload call_id=4a4cbb39578170aed9a2761a7bec8c7e704a541f52291ef603d6f5f152980c3c&event=CallAccepted&from=0123456789&to=0987654321
will result in:
2.5.1 :005 > digest = OpenSSL::Digest.new('sha256')
=> #<OpenSSL::Digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855>
2.5.1 :006 > signature = OpenSSL::HMAC.hexdigest(digest, secret, payload)
=> "c4f823c5b8806432fe2b83b1fc2ee714422e0cdfb4b5129152a7d0bbcd7792d0"
In order to restrict access to your API endpoint, you may use a simple basic-auth in the URL defined in your external api settings: https://admin:[email protected]/callback
.
Depending on the type of request our payload contains the following parameters:
Parameter | Description |
---|---|
event |
"IncomingCall" |
from |
The calling number (e.g. "022129191999" or "anonymous" ) |
to |
The called number (e.g. "022129191999" ) |
call_id |
The ID of the call, sha256 in hex presentation, e.g. "f4591ba315d81671d7a06c2a3b4f963dafd119de39cb26edd8a6476676b2f447" |
direction |
"in" |
Parameter | Description |
---|---|
event |
"OutgoingCall" |
from |
The caller id of the calling party (anonymous calls are not notified) |
to |
The called number (e.g. "022129191999" , or "23" ) |
peer |
The calling SIP user (e.g. "[email protected]" ) |
call_id |
The ID of the call, sha256 in hex presentation, e.g. "f4591ba315d81671d7a06c2a3b4f963dafd119de39cb26edd8a6476676b2f447" |
direction |
"out" |
Only for incoming calls.
Parameter | Description |
---|---|
event |
"CallAccepted" |
from |
The calling number (e.g. "022129191999" or "anonymous" ) |
to |
The called number (e.g. "022129191999" ) |
call_id |
The ID of the call, sha256 in hex presentation, e.g. "f4591ba315d81671d7a06c2a3b4f963dafd119de39cb26edd8a6476676b2f447" |
peer |
The SIP peer which answered the call, e.g. "[email protected]" |
direction |
"in" |
Parameter | Description |
---|---|
event |
"HungUp" |
from |
The calling number (e.g. "022129191999" or "anonymous" ) |
to |
The called number (e.g. "022129191999" ) |
call_id |
The ID of the call, sha256 in hex presentation, e.g. "f4591ba315d81671d7a06c2a3b4f963dafd119de39cb26edd8a6476676b2f447" |
type |
The cause of the hangup (see table below) |
duration |
Duration of accepted call in seconds, 0 for not accepted calls |
direction |
"in" or "out" |
from
and to
for outgoing internal calls are the SIP IDs of caller and callee.
Type | Description |
---|---|
voicemail |
The call was sent to voicemail |
missed |
Nobody picked up the call |
blocked |
The call was blocked |
accepted |
The call was accepted and ended by hangup |
busy |
The called number was busy |
canceled |
The call was canceled by the caller |
unavailable |
Destination is offline / unavailable |
congestion |
There was a problem |
busy
, canceled
, unavailable
and congestion
are limited to outbound calls.
Your XML response is used to determine what to do with the incoming call.
We only process your response when the routing for your number is set to External API.
Make sure your response's Content-Type
header is set to application/xml
.
Currently, we support the following responses for incoming calls:
Action | Description |
---|---|
Forward | Forward call to one or multiple destinations (SIP users, external numbers) |
Reject | Reject call or pretend to be busy |
Hangup | A normal Hang up |
Queue | Send call to a Contact Center Queue* |
* Only available with Contact Center option booked.
Forward to one or multiple targets. Attributes for Forward
are
Attribute | Description |
---|---|
music_on_hold |
Play music on hold instead of standard ringtone? Default is false |
voicemail |
Send call to voicemail if no routing target answered? Default is true |
voicemail_announcement |
ID of mailbox announcement / prompt, e.g. 1234 |
voicemail_as_attachment |
Send voicemail as MP3 attachment? Default is false |
forward_announcement |
Play selected announcement and transfer to targets, see voicemail_announcement |
Attributes for each Target
.
Attribute | Description |
---|---|
ringtime |
Ringtime in seconds, optional, default is 60 |
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Forward>
<Target>
<Number>022129191999</Number>
</Target>
</Forward>
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Forward>
<Target>
<Number>[email protected]</Number>
</Target>
</Forward>
</Response>
Find the SIP username and server on the settings page of your SIP destination.
Ringing the same time.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Forward>
<Target>
<Number>[email protected]</Number>
<Number>022129191999</Number>
</Target>
</Forward>
</Response>
Ringing 30 sec on the first two destinations and 45 sec on the second three destinations.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Forward>
<Target ringtime="30">
<Number>[email protected]</Number>
<Number>022129191999</Number>
</Target>
<Target ringtime="45">
<Number>[email protected]</Number>
<Number>[email protected]</Number>
<Number>022199998560</Number>
</Target>
</Forward>
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Forward music_on_hold="true" forward_announcement="7684">
<Target>
<Number>[email protected]</Number>
</Target>
</Forward>
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Forward voicemail="true" voicemail_announcement="4"/>
</Response>
Reject an unwanted call or pretend to be busy.
Attribute | Description |
---|---|
reason |
The reject reason for the call, for now: "busy" |
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Reject />
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Reject reason="busy" />
</Response>
A simple hangup.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Hangup />
</Response>
Send call to a Contact Center Queue.
Attribute | Description |
---|---|
queue_id |
The ID of the queue, required, e.g. 123 |
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Queue queue_id="123" />
</Response>
Want to add your example? Open a pull request!
For HTTP Basic Authentication include your username and passwort within your API URL. For example: https://username:[email protected]
.
You will find the ID in the edit form of each record in the Placetel Webportal. In addition, you can use the new Placetel API.
The API itself is provided free of charge; the usual connection fees may apply.
For improvements, feature requests or bug reports, please use GitHub Issues or send us a pull request.