
Good day. Earlier
RingCloud announced the launch of the REST API, which will allow our product to integrate with various CRM systems. And although its development is still ongoing, we are pleased to present to you the first version. Under the cat, we consider the general architecture of this service, its principle of operation, as well as analyze usage examples.
When we were just planning our service, we set goals to make it as convenient as possible for integration, and such tasks cannot be solved without a decent API. Therefore, it was decided to give this service as much attention as possible, having built it as reliable and convenient as possible.
API key management
To use the API, you need a unique
API Key and password to it, for this we go to your personal account and in the corresponding
section create a key
')

The key is generated automatically, it consists of a prefix with your account number and the key's body itself, in order to copy the key you just need to click on the line with the key. The password is also automatically generated and to change it, if it seems too simple to you, you need to click on the icon on the right. For each key, you must specify the access rights, this is done to delimit the privileges between your applications. Access levels operate on the “RO / RW” principle and allow differentiation of permitted actions.
Description of the RingCloud API functions currently available can be found on
the documentation page.Architecture
This service is based on the cluster principle, with load balancing between the nodes processing the requests. Since the service uses HTTPS, it was decided to shift this task to the balancer. The nodes, having processed the requests, turn to the system kernel that includes the VoIP server, database, and Redis-based cache.
I must say that
Redis is very widely used in all RingCloud nodes, we are very pleased with it in terms of convenience and speed.
As a balancer and WEB interface servers, we use
Nginx because it completely suits us in terms of functionality and performance, the balancing functionality is perfectly implemented on it, it works fine with HTTPS, it has a very convenient configuration.

Examples of using
We develop our API based on the
REST methodology to make it as easy to use as possible.
Let's look at the principle of forming the request. All API URLs are:
https://api.ringcloud.ru/<<url>>?api_key=API_KEY&hash=HASH
here:
- url - the address corresponding to the called API function
- api_key - API key
- hash - hash - calculated as md5 from the API key and password
In case of successful execution of any request (with the exception of downloading the call record file - in this case the file itself will be returned) the response from the server looks like:
{"status": "success", "message": null, "data": "some_data"}
In case of an error (except for an error when loading the conversation recording file - in this case, an empty string will be returned) the response from the server is:
{"status": "error", "message": "some_error", "data": null}
Each response from the server contains an HTTP status code. The table below lists the most frequently used ones.
Commonly used status codesHTTP status code | Description |
---|
200 | Function completed successfully |
400 | Incorrectly passed parameters. For example, when updating data, a non-existent user was specified. |
403 | API key or hash is not specified, API key does not exist or hash is calculated incorrectly. |
404 | Requested url or file not found |
405 | The method is not supported - instead of GET a POST request is used or vice versa. |
429 | Too many requests - the limit on the frequency of requests to the API has been reached. |
500 | Internal error. Ideally, should never return. |
Currently, it is possible to work with two objects (resources in REST terminology): “Users” and “Challenges”. With the first you can create users, get information about them and change their data. The second object is designed to work with calls. With it, you can make a call, as well as get information about active and perfect calls. Further, there are certain restrictions on the frequency of calls to our API. Let's explain the model we use. First, restrictions are counted separately for each key. Secondly, within the framework of a single key there are restrictions on the same type of requests, i.e. requests with completely identical URLs. For example, if you have only one API key, and you send two requests for changing the extension number from the same user per minute, then only the first request will be successfully processed. But to change the internal numbers for two different users is quite possible.
Functions of the object "Users" and time constraintsTitle | Url | Restriction |
---|
Getting a list of account users | /v1/users | 1 request per second |
Getting information for a specific user | /v1/users/<username> | 1 request per second |
change Password | /v1/users/<username>/update_password | 1 request per second |
Internal number change | /v1/users/<username>/update_extension_number | 1 request in 5 seconds |
Change email | /v1/users/<username>/update_email | 1 request in 5 seconds |
Enable Voice Box | /v1/users/<username>/voice_mail_box_on | 1 request in 5 seconds |
Turning off the voice box | /v1/users/<username>/voice_mail_box_off | 1 request in 5 seconds |
Create user | /v1/users/create | 1 request in 60 seconds |
Getting the list of records | /v1/users/<username>/records | 1 request in 5 seconds |
download conversation recording | /v1/users/<username>/records/<filename> | 1 request per second |
Functions of the “Challenges” object and time constraintsTitle | Url | Restriction |
---|
Getting a list of channels for context | /v1/calls/channels | 1 request in 2 seconds |
Getting information on the channel | /v1/calls/channels/<channel> | 1 request in 2 seconds |
Call origin | /v1/calls | 1 request in 5 seconds |
Getting a list of calls made | /v1/calls/complite | 1 request in 5 seconds |
Get a list of current calls | /v1/calls/active | 1 request in 5 seconds |
How call origination worksIn order to make a call you will need an employee who has connected via SIP to the RingCloud server using a “softphone” or a stationary SIP phone, and we will call the number. When sending a request to the API, the system first calls the employee (let's call his subscriber A), and then, only when the employee answers, dials the number to which we plan to make a call, so we originate the call between subscriber A and subscriber B

Consider a small example of a Python call to our API. Here's how to call from the internal number assigned to the employee with the name 1679728441 to the number 7910123456:
And the same thing in PHP: <?php $apiKey = 'YOUR_API_KEY'; $password = 'YOUR_PASS'; $hash = md5($apiKey . $password); $apiUrl = 'https://api.ringcloud.ru/v1/calls?api_key=' . $apiKey . '&hash=' . $hash; $callData = [ 'params' => [ 'num' => '7910123456', 'user' => '1679728441' ] ]; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($callData)); $result = curl_exec($ch); echo $result; ?>
Also, in parallel with the RingCloud API development project, we are developing libraries that allow us to start using it as quickly as possible in our applications and services. While only the first version of the PHP library is ready it is
here.Well, it seems that everything we wanted to share with you. The current version of the documentation on our API can be found
here . In the near future - creating a
complete package for Python to work with our API and, of course, expanding the functionality. Thanks for attention.