Register
Prerequisites
Overview
This API enables PBX/TAS (Private Branch Exchange/Telephony Application Server) providers to plug their (SIP-enabled) endpoint into the call path.
It enables a SIP integration between Working Group Two's core and a PBX/TAS for a given MSISDN.
Virtual SIP Registrations are used to alter default call behavior and involve PBX/TAS into the SIP signaling path. When using user tokens
the registration created per single MSISDN linked to the OAuth 2.0 round trip, while when using client tokens
the registration is created for the provided MSISDN in the request.
Authentication
This API requires you to use a OAuth 2.0 token obtained via either:
Note
The field phone_number
is required if using the Client Credentials Flow
.
Why?
For the Client Credentials Flow
, the access token authenticates the product itself. So phone_number
must be provided in requests to identify the subscription.
If you are using Authorization Code Flow
, the token belongs to a specific subscription. So the scope is not needed for identification in the request.
Required scope
call.routing:write
The API
The API is implemented as a gRPC service described below.
There are two methods supported by this API:
UpsertRegistration
DeleteRegistration
To register a (PBX/TAS-bound) MSISDN with our core, use UpsertRegistration
. The same method is used if you want to update an existing registration.
Use DeleteRegistration
when an existing registration is no longer needed.
Messages
Both methods receive RegistrationRequest
and return RegistrationResponse
message.
RegistrationRequest
is a structure containing the URI of the endpoint you host + some additional details related to the connected MSISDN.RegistrationResponse
is a simple structure conveying the status of method invocation (success/error)
You may find the proto definition of the service + the definition of the messages exchanged here.
Registration types
There are three types of registrations: Fork
, Loop
and Fallback
. It is the registration type that decides how the calls will be handled by our core.
Fork/Loop
If a registration of one of these types is registered on an MSISDN, all the SIP signalling from/to that MSISDN will be replicated to the endpoint specified in the registration.
Loop: leg 4 is created only after the call comes back as leg 3
Please note that PBX/TAS is not obliged to create leg 3 as it can answer or reject leg 2 directly.
Fork: legs 2 and 3 are created simultaneously.
Typically, you use
Fork/Loop
to implement your logic during a call.
Fallback
The core will action upon a Fallback
registration if and only if:
- somebody calls the related MSISDN
- the MSISDN is either busy or no answer detected within the timeout (30s)
In such case, the core will replicate the INVITE to the endpoint specified during the registration.
Typically, you use
Fallback
to implement the likes of voice mail, call forwarding etc.
Example code
The examples below demonstrate how to consume this API.
TIP
You can test our APIs without authorization by targetting sandbox.api.wgtwo.com
instead of api.wgtwo.com
and removing any authorization from the request/code sample.
Download proto definitions
curl -sL 'https://github.com/working-group-two/wgtwoapis/blob/master/image.bin?raw=true' -o wgtwo.bin
export ACCESS_TOKEN="my_access_token"
grpcurl -protoset wgtwo.bin \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '
{
"registration": {
"mobileOriginatingPrefix": "11",
"mobileTerminatingPrefix": "22",
"sipUri": "sips:example.com:8888",
"routeType": "ROUTE_TYPE_LOOP",
"phoneNumber": {
"e164": "+4799990000"
}
}
}
' \
api.wgtwo.com:443 \
wgtwo.sipbreakout.v1.SipBreakoutService/UpsertRegistration
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Example result
Success
{
"statusCode": "STATUS_CODE_OK"
}
2
3
Error
{
"statusCode": "STATUS_CODE_NOT_ACCEPTABLE",
"errorMessage": "Secure SIP domain name required"
}
2
3
4
Install dependencies
Maven
<dependency>
<groupId>com.wgtwo.api.v1.grpc</groupId>
<artifactId>sipbreakout</artifactId>
<version>1.10.1</version>
</dependency>
package com.example.sipbreakout
import com.wgtwo.api.v1.sipbreakout.DeleteRegistrationRequest
import com.wgtwo.api.v1.sipbreakout.Registration
import com.wgtwo.api.v1.sipbreakout.RouteType
import com.wgtwo.api.v1.sipbreakout.SipBreakoutServiceGrpc
import com.wgtwo.api.v1.sipbreakout.UpsertRegistrationRequest
import com.wgtwo.auth.BearerTokenCallCredentials
import io.grpc.ManagedChannelBuilder
/** Use the sandbox environment for testing without authentication */
private val environment = Environment.SANDBOX
private val endpoint = when (environment) {
Environment.SANDBOX -> "sandbox.api.wgtwo.com"
Environment.PRODUCTION -> "api.wgtwo.com"
}
private val channel = ManagedChannelBuilder.forAddress(endpoint, 443).build()
private val stub = SipBreakoutServiceGrpc.newBlockingStub(channel).apply {
/**
* If you are not using the sandbox, you need to add credentials.
* The BearerTokenCallCredentials class can be found in our auth library.
*/
if (environment == Environment.PRODUCTION) {
this.withCallCredentials(BearerTokenCallCredentials { "MY_CLIENT_ACCESS_TOKEN" })
}
}
fun main() {
val registration = Registration.newBuilder().apply {
sipUri = "sips:example.com:8888"
mobileOriginatingPrefix = "11"
mobileTerminatingPrefix = "22"
routeType = RouteType.ROUTE_TYPE_LOOP
}.build()
val upsertRequest = UpsertRegistrationRequest.newBuilder()
.setRegistration(registration)
.build()
println("upsert request:\n$upsertRequest")
val upsertResponse = stub.upsertRegistration(upsertRequest)
println("upsert response:\n$upsertResponse")
val deleteRequest = DeleteRegistrationRequest.newBuilder()
.setRegistration(registration)
.build()
println("delete request:\n$deleteRequest")
val deleteResponse = stub.deleteRegistration(deleteRequest)
println("delete response:\n$deleteResponse")
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Example result
Success
status_code: STATUS_CODE_OK
Error
statusCode: STATUS_CODE_NOT_ACCEPTABLE
errorMessage: Secure SIP domain name required
2