The Call API is a front-end for SIP Proxies (such as OpenSIPS), aiming to simplify the management of more advanced SIP call flows. Combining built-in SIP scenarios (such as the ones from RFC 5359) with real-time notifications as the call commands take place, the API is meant to help VoIP system developers build complex SIP services with ease, altogether while providing live reporting for such services.
The API listens for WebSocket connections on ws://localhost:5059/call-api
and talks JSON-RPC 2.0 over them.
The Call API tool is using go modules, introduced in go 1.13, but the tool was developed based on go version 1.14. We recommend you install at least go 1.14 using your distribution's repositories, or from the official Golang repository.
go get github.com/OpenSIPS/call-api
cd ${GOPATH:-$HOME/go}/src/github.com/OpenSIPS/call-api
make build
bin/call-api
The following steps will build all the project's tools in the bin/
folder of the current directory.
In order to make a complete install of the project, you can follow these steps:
make install
export PATH=$PATH:${GOBIN:-${GOPATH:-$HOME/go}/bin}
call-api
Each tool uses a configuration file that defaults to tool-name.yml
(ex: call-api.yml
or call-cmd.yml
). This file is automatically searched in the following folders: config/
, /etc
and /etc/call-api
, in this specific order. A custom path can be specified using the -config cfg_file.yml
parameter when starting the tool (ex: call-api -config /etc/custom-config.yml
Examples of configuration files can be found in the config directory.
Below are the API's commands available for building your JSON-RPC requests. Read the documentation of each command for a listing of its input parameters and their accepted values:
- CallStart - start a call between two participants
- CallBlindTransfer - perform an unattended call transfer (see RFC 5359 example)
- CallAttendedTransfer - perform an attended call transfer (see RFC 5359 example)
- CallHold - put one or both participants on hold
- CallUnHold - resume an on-hold call
- CallEnd - terminate an ongoing call
By default, the API listens on ws://localhost:5059/call-api
. Below is an example way of launching a CallStart
command using an API client written in Go:
go run cmd/call-api-client/main.go \
-method CallStart \
-params '{"caller": "sip:alice@localhost", "callee": "sip:bob@localhost"}'
Once a WebSocket channel is established between the client and the API, communication will take place strictly using JSON messages which follow the JSON-RPC 2.0 request/response/notification protocol. Note that API clients are expected to process notifications from the API, while their launched commands are being handled asynchronously.
- "caller" (string, mandatory)
- "callee" (string, mandatory)
1) WS client ----------> API
{
"method": "CallStart",
"params": {
"caller": "sip:[email protected]",
"callee": "sip:[email protected]"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
2) WS client <---------- API
{
"result": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"status": "Started"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
3) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_ANSWER"
}
"jsonrpc": "2.0"
}
4) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "TRANSFER_ACCEPT"
}
"jsonrpc": "2.0"
}
5) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_START"
}
"jsonrpc": "2.0"
}
6) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_ANSWER"
}
"jsonrpc": "2.0"
}
7) WS client <---------- API
{
"method": "Ended",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178"
}
"jsonrpc": "2.0"
}
- "callid" (string, mandatory) - the SIP Call-ID of the targeted dialog
- "leg" (string, mandatory) - which party to transfer. Possible values: "caller", "callee"
- "destination" (string, mandatory) - SIP URI of the blind transfer target
# 1) WS client ----------> API
{
"method": "CallBlindTransfer",
"params": {
"callid": "[email protected]",
"leg": "callee",
"destination": "sip:[email protected]"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 2) WS client <---------- API
{
"result": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"status": "Started"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 3) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "TRANSFER_ACCEPT"
}
"jsonrpc": "2.0"
}
# 4) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_START"
}
"jsonrpc": "2.0"
}
# 5) WS client <---------- API
{
"method": "Ended",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178"
}
"jsonrpc": "2.0"
}
- "callid_a" (string, mandatory) - the SIP Call-ID of the dialog #1
- "leg_a" (string, mandatory) - which party to transfer from dialog #1. Possible values: "caller", "callee"
- "callid_b" (string, mandatory) - the SIP Call-ID of the dialog #2
- "leg_b" (string, mandatory) - which party to transfer from dialog #2. Possible values: "caller", "callee"
- "destination" (string, mandatory) - SIP URI of the attended transfer's destination
# 1) WS client ----------> API
{
"method": "CallAttendedTransfer",
"params": {
"callid_a": "[email protected]",
"leg_a": "caller",
"callid_b": "0ba2cf53-9a78-41de-8fe6-f2e5bb4d1a1e",
"leg_b": "callee",
"destination": "sip:[email protected]"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 2) WS client <---------- API
{
"result": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"status": "Started"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 3) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "TRANSFER_ACCEPT"
}
"jsonrpc": "2.0"
}
# 4) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_START"
}
"jsonrpc": "2.0"
}
# 5) WS client <---------- API
{
"method": "Ended",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178"
}
"jsonrpc": "2.0"
}
- "callid" (string, mandatory) - the SIP Call-ID of the target dialog
- "leg" (string, optional) - party to put on hold ("caller" or "callee"). If missing, both call participants will be put on hold
# 1) WS client ----------> API
{
"method": "CallHold",
"params": {
"callid": "[email protected]",
"leg": "caller"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 2) WS client <---------- API
{
"result": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"status": "Started"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 3) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_HOLD"
}
"jsonrpc": "2.0"
}
# 4) WS client <---------- API
{
"method": "Ended",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178"
}
"jsonrpc": "2.0"
}
- "callid" (string, mandatory) - the SIP Call-ID of the target dialog
# 1) WS client ----------> API
{
"method": "CallUnHold",
"params": {
"callid": "[email protected]"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 2) WS client <---------- API
{
"result": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"status": "Started"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 3) WS client <---------- API
{
"method": "Event",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"data": "CALL_UNHOLD"
}
"jsonrpc": "2.0"
}
# 4) WS client <---------- API
{
"method": "Ended",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178"
}
"jsonrpc": "2.0"
}
- "callid" (string, mandatory) - the SIP Call-ID of the target dialog
# 1) WS client ----------> API
{
"method": "CallEnd",
"params": {
"callid": "[email protected]"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 2) WS client <---------- API
{
"result": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178",
"status": "Started"
}
"id": "831717ed97e5",
"jsonrpc": "2.0"
}
# 3) WS client <---------- API
{
"method": "Ended",
"params": {
"cmd_id": "b8179f1e-b4e4-4ac7-9990-4bf64f084178"
}
"jsonrpc": "2.0"
}