RingPlan API
Scroll down for code samples, example requests and responses.
Welcome to documentation for RingPlan API.
The current API URL is https://ssp-backend.ringplan.com
.
RingPlan API is built upon REST
and each request is based on the HTTP methods of GET
, PUT
, POST
, PATCH
and DELETE
.
All you need to have in order to access the API is an HTTP client capable of using these methods,
setting HTTP headers as well as sending JSON payloads.
In addition, RingPlan provides a WebSocket API.
Example Python snippets using the requests
library
are provided for you in the column on the right.
WebSocket examples are given in JavaScript using the Socket.IO library.
This document is structured in the following main sections:
Overview, which you are reading right now, explaining the structure of the document.
Guides, containing tutorials and walkthroughs for common use-cases of this API.
REST, for descriptions of REST API endpoints with examples.
WebSocket, for descriptions of WebSocket API endpoints with examples.
Objects, where fields and uses of internal objects are described.
Guide
Example request headers for a specific contact
API_KEY = 'secret_string'
headers = {
'Authorization': 'Bearer ' + API_KEY
'X-User-Id': '60190ce750fe88ed1a544a7a'
}
Example request headers for the primary contact
API_KEY = 'secret_string'
headers = {
'Authorization': 'Bearer ' + API_KEY
'X-User-Id': 'primary'
}
RingPlan REST API supports OAuth-based authentication,
using the Authorization
header, whose value must be Bearer
followed by the company's API key.
API keys can be obtained from the Self Service Portal.
Each API key is tied to a single company.
The user sending the request provides their contact
id with the X-User-Id
header.
Each company has a special user with administrator permissions named primary
.
Any user in the company (including the primary
user) can be impersonated with the X-User-Id
header.
REST
Constant values for examples
import requests
API_URL = 'https://ssp-backend.ringplan.com'
API_KEY = 'secret string'
USER_ID = 'id of acting user'
headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + API_KEY,
'X-User-Id': USER_ID
}
Each endpoint supplies status codes in conformance with RFC 7231.
Endpoint return values are described in the Responses section. If they return ad hoc objects, the fields are described separately under said section.
Error messages are always in the following format:
Field | Type | Description | Example |
---|---|---|---|
detail |
string | Error message | "The requested URL was not found on the server." |
status |
integer | Status code | 404 |
title |
string | Status message | "Not Found" |
type |
string | Miscellaneous information | "about:blank" |
All methods will return 401 Unauthorized for failed authorization due to
invalid or missing API_KEY
or X-User-Id
headers.
Company
company
endpoints
Get company information
Get the current company
request = requests.get(API_URL + '/system/company', headers = headers)
print(request.json())
GET /system/company
Return the company
object of the company the given user belongs to.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | company object successfully returned. |
Update company
Update the current company
headers['X-User-Id'] = 'primary'
body = {
'name': 'New Company',
'email': 'new@example.net'
}
request = requests.patch(API_URL + '/company', headers = headers, json = body)
print(request.json())
PATCH /company
Partially update the company
the current user belongs to.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | company object |
true | Partial or full company object |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | company successfully updated and returned. |
403 | Forbidden | Requesting user is not the company owner. |
Users
contact
endpoints
Get users in company
Return users in current company with given work email
query = {
'work_email': 'sales@example.com'
}
request = requests.get(API_URL + '/system/company/contacts', headers = headers, params = query)
print(request.json())
GET /system/company/contacts
Return the list of users that share the same company
as the current user,
optionally filtered and sorted by query parameters.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
first_name |
query | string | false | Filter by first_name |
work_email |
query | string | false | Filter by work_email |
items_per_page |
query | integer | false | Number of contact s per page |
page |
query | integer | false | Index of the page of contacts (default 1) |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of contact s successfully returned. |
204 | No Content | There are no contact s with provided query filters. |
400 | Bad Request | Invalid parameter provided. |
Add user to company
Add new user to current company
headers['X-User-Id'] = 'primary'
body = {
'first_name': 'Jane',
'contacts': {
'email': 'janedoe@example.com'
}
}
request = requests.post(API_URL + '/company/contacts', headers = headers, json = body)
print(request.json())
POST /company/contacts
Create a new user, add it to the current company and return the contact
object.
Only the company owner, i.e the primary
user, is allowed to create new users.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | contact object |
true | contact to be added to the company |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | A contact was successfully created and returned. |
400 | Bad Request | Provided user information could not be validated. |
403 | Forbidden | User is not the owner of this company. |
Update user
Updating a user's details
contact_id = '60190ce750fe88ed1a544a7a'
headers['X-User-Id'] = contact_id
body = {
'emergency_contact_number': '15554441234',
'last_name': 'Smith'
}
request = requests.patch(API_URL + '/company/contacts/' + contact_id, headers = headers, json = body)
print(request.json())
PATCH /company/contacts/{contact_id}
Partially update contact
with the provided contact_id
and return the updated contact
object.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
contact_id |
path | contact id string |
true | ID of the contact to be updated |
body | body | contact object |
true | Partial or full contact object |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | contact successfully updated and returned. |
400 | Bad Request | Invalid parameters in the payload. |
403 | Forbidden | Requesting user is neither the one being updated nor the company owner. |
404 | Not Found | contact with the given ID does not exist. |
Delete user
Deleting a user from the company
contact_id = '60190ce750fe88ed1a544a7a'
headers['X-User-Id'] = 'primary'
request = requests.delete(API_URL + '/company/contacts/' + contact_id, headers = headers)
print(request.json())
DELETE /company/contacts/{contact_id}
Delete the given user in the current company
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
contact_id |
path | contact id string |
true | contact to be deleted. |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | contact successfully deleted. |
403 | Forbidden | Requesting user is not the company owner. |
404 | Not Found | contact with the given ID does not exist. |
Locations
location
endpoints
Get company locations
Get the list of locations belonging to the company
request = requests.get(API_URL + '/company/locations', headers = headers)
print(request.json())
GET /company/locations
Return the list of locations for the current company.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of location s successfully returned. |
Add location to company
Add a second location to the company
body = {
'name': 'Second Location',
'country': 'United States',
'state': 'California',
'city': 'Carlsbad',
'zip': '92008',
'company_id': '611ced1255c44a89f8df7cc0'
}
headers['X-User-Id'] = 'primary'
request = requests.post(API_URL + '/company/locations', headers = headers, json = body)
print(request.json())
POST /company/locations
Create a new location
, add it to the current company
and return it.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | location object |
true | location to be added to the company |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | A location was successfully created and returned. |
400 | Bad Request | Provided location information could not be validated. |
403 | Forbidden | Requesting user is not the company owner. |
Update company locations
Partially update a company location
location_id = '61254e7ecbe793d0e26c7996'
headers['X-User-Id'] = 'primary'
body = {
'name': 'Old Location'
}
request = requests.patch(API_URL + '/company/locations/' + location_id, \
headers = headers, json = body)
print(request.json())
PATCH /company/locations/{location_id}
Partially update the given location
with the provided request body data.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
location_id |
path | location id string |
true | ID of the location to be updated |
body | body | location object |
true | Partial or full location object |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | location successfully updated and returned. |
400 | Bad Request | Some of the provided fields are not valid. |
403 | Forbidden | User has no permission to edit this location. |
404 | Not Found | location with the given ID does not exist. |
Delete location
Delete a location from the company
location_id = '61254e7ecbe793d0e26c7996'
headers['X-User-Id'] = 'primary'
request = requests.delete(API_URL + '/company/locations/' + location_id, headers = headers)
print(request.json())
DELETE /company/locations/{location_id}
Delete the given location
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
location_id |
path | location id string |
true | ID of the location to be deleted |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | location successfully deleted. |
403 | Forbidden | Requesting user is not the company owner. |
404 | Not Found | location with the given ID does not exist. |
Instances
instance
endpoints
Get instances
Get the list of all instances in the company
request = requests.get(API_URL + '/instances', headers = headers)
print(request.json())
GET /instances
Return the list of PBX instance
s available to the company
.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of instance s successfully returned. |
Extensions
extension
endpoints.
Get extensions
Get the third page of an instance's softphone extensions, sorted by user names
instance_uuid = '279951a6-4f51-5019-a897-0e7624828abf'
query = {
'by_user': 'on',
'filter_by': 'softphone',
'page': 3
}
request = requests.get(API_URL + '/instances/' + instance_uuid + '/bulks/extensions', \
headers = headers, params = query)
print(request.json())
GET /instances/{instance_uuid}/bulks/extensions
Return the list of extension
s by PBX ID.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instance_uuid |
path | instance uuid string |
true | UUID of the instance |
filter_by |
query | enum string | false | Query filter |
by_user |
query | enum string | false | Whether to sort by user |
search |
query | string | false | Search query |
page |
query | integer | false | Index of the page of extension s |
page_size |
query | integer | false | Number of extension s per page |
Enumerated Values
Parameter | Value |
---|---|
filter_by |
unassigned |
filter_by |
softphone |
by_user |
on |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of extension s successfully returned. |
404 | Not Found | extension s by this PBX do not exist or instance by the given ID does not exist. |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of extension s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of extension s per page |
Add new extensions
Add a new extension to an instance
instance_uuid = '79951a6-4f51-5019-a897-0e7624828abf'
body = {
'data': {
'id': 1123,
'name': 'Test',
'description': null,
'voicemail_email': 'voice@example.com',
'outboundcid': null
},
'location_id': '60190fb650fe88ed1a544a85',
'purpose': 'mobile-app'
}
request = requests.post(API_URL + '/instances/' + instance_uuid + '/bulks/extensions', \
headers = headers, json = body)
print(request.json())
POST /instances/{instance_uuid}/bulks/extensions
Add a new extension
to the given PBX instance
and the database.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instance_uuid |
path | instance uuid string |
true | UUID of the instance to add the extension to |
body | body | extension object |
true | extension to be added |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | New extension has been successfully created and returned. |
400 | Bad Request | extension provided contains invalid values. |
502 | Bad Gateway | FreePBX response with error returned. |
Get all extensions assigned to a user
Get all softphone extensions assigned to a user
contact_id = '60190ce750fe88ed1a544a7a'
query = {
'purpose': 'softphone'
}
request = requests.get(API_URL + '/account/' + contact_id + '/extensions', \
headers = headers, params = query)
print(request.json())
GET /account/{contact_id}/extensions
Get the list of extension
s assigned to the given user.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
contact_id |
path | contact id string |
true | ID of the target user |
purpose |
query | enum string | false | Purpose of the extension |
Enumerated Values
Parameter | Value |
---|---|
purpose |
softphone |
purpose |
unassigned |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of extension s successfully returned. |
404 | Not Found | contact with the given ID does not exist. |
Find extensions
Find the fifth page of unassigned extensions on an instance
instance_uuid = '79951a6-4f51-5019-a897-0e7624828abf'
query = {
'filter_by': 'unassigned',
'page': 5
}
request = requests.get(API_URL + '/instances/' + instance_uuid + '/extensions', \
headers = headers, params = query)
print(request.json())
GET /instances/{instance_uuid}/extensions
Return the list of extension
s, optionally filtered and sorted by query parameters.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instance_uuid |
path | instance uuid string |
true | UUID of the target instance |
filter_by |
query | enum string | false | Type of extension to filter by |
by_user |
query | enum string | false | Whether to filter by user instead |
search |
query | string | false | Search query |
page |
query | integer | false | Current page number |
page_size |
query | integer | false | Size of each page |
Enumerated Values
Parameter | Value |
---|---|
filter_by |
unassigned |
filter_by |
softphone |
by_user |
on |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of extension s successfully returned. |
404 | Not Found | extension s by this PBX do not exist. |
Check user extension assignments
Check for duplicate extensions on a given user
instance_uuid = '79951a6-4f51-5019-a897-0e7624828abf'
body = {
'email': 'john@example.com',
'id': 1001
}
request = requests.post(API_URL + '/instances/' + instance_uuid + '/bulks/extensions/check', \
headers = headers, json = body)
print(request.json())
POST /instances/{instance_uuid}/bulks/extensions/check
Check possible duplicate assignments for extension
s.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instance_uuid |
path | instance uuid string |
true | UUID of the target instance |
body | body | object | true | Payload |
» email |
body | string | true | Email address of the user to be assigned |
» id |
body | integer | true | Extension number |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | User has no assignments. |
400 | Bad Request | There are existing extension assignments or payload not provided. |
404 | Not Found | instance with the given ID does not exist. |
Update extension
Replace an extension
body = new_extension
instance_uuid = '79951a6-4f51-5019-a897-0e7624828abf'
extension_id = '61254e7f884ca03e99ba0dfe'
request = requests.put(API_URL + '/instances/' + instance_uuid + '/bulks/extensions/' + extension_id, \
headers = headers, json = body)
print(request.json())
PUT /instances/{instance_uuid}/bulks/extensions/{extension_id}
Update details for the given extension
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instance_uuid |
path | instance uuid string |
true | UUID of the instance the extension belongs to |
extension_id |
path | extension id string |
true | ID of the target extension |
body | body | extension object |
true | Replacement extension |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | extension successfully updated and returned. |
400 | Bad Request | extension provided contains invalid values. |
404 | Not Found | extension with the given ID or instance with the given ID does not exist. |
502 | Bad Gateway | FreePBX response with error returned. |
Delete extension
Delete an extension from a given instance
instance_uuid = '79951a6-4f51-5019-a897-0e7624828abf'
extension_id = '61254e7f884ca03e99ba0dfe'
request = requests.delete(API_URL + '/instances/' + instance_uuid + '/bulks/extensions/' + extension_id, \
headers = headers)
print(request.json())
DELETE /instances/{instance_uuid}/bulks/extensions/{extension_id}
Delete the given extension
from the PBX instance
and the database.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instance_uuid |
path | instance uuid string |
true | UUID of the instance the extension belongs to |
extension_id |
path | extension id string |
true | ID of the target extension |
Responses
Status | Meaning | Description |
---|---|---|
204 | No Content | extension successfully deleted. |
404 | Not Found | extension with the given ID or instance with the given UUID does not exist. |
502 | Bad Gateway | FreePBX response with error returned. |
Get extension configuration by ID
Get extension configuration
query = {
'instance_uuid': '79951a6-4f51-5019-a897-0e7624828abf',
'extension_id': '61254e7f884ca03e99ba0dfe'
}
request = requests.get(API_URL + '/phones/qr-config/advanced', headers = headers, params = query)
print(request.json())
GET /phones/qr-config/advanced
You can use that configuration to connect extension with any VoIP softphone
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
extension_id |
query | extension id string |
true | ID of the target extension |
instance_uuid |
query | instance uuid string |
true | UUID of the instance the extension belongs to |
Texting - Conversations
conversation
endpoints.
Get all conversations
Get conversations
request = requests.get(API_URL + '/texting/conversations, headers = headers)
print(request.json())
GET /texting/conversations
Get all conversation
s in the company.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
page |
query | integer | false | Index of the page of conversation s |
per_page |
query | integer | false | Number of conversation s per page |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of conversation s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of conversation s per page |
Search conversations
Search for text within conversations
query = {
'text': 'Development Talks'
}
request = requests.get(API_URL + '/texting/conversations/search', headers = headers, params = query)
print(request.json())
GET /texting/conversations/search
Get messages from all conversation
s in the company by text search.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
text |
query | string | false | Search query |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of conversation objects successfully returned. |
Create new conversations
Create a conversation
body = {
'contact_id': '615717df4b8fa06267cd2f6f',
'from_number': '1235551234'
}
request = requests.post(API_URL + '/texting/conversations', headers = headers, json = body)
print(request.json())
POST /texting/conversations
Create a new conversation
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | conversation object |
true | conversation to be created |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | A conversation already exists for the provided source and destination numbers. |
201 | Created | New conversation was successfully created and returned. |
Delete conversations
Delete a conversation
conversation_id = '616566b94b8fa0626751ef96'
request = requests.delete(API_URL + '/texting/conversations/` + conversation_id, headers = headers)
print(request.json())
DELETE /texting/conversations/{conversation_id}
Delete the given conversation
with all the message
s in it.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
conversation_id |
path | conversation id string |
true | ID of the target conversation |
Responses
Status | Meaning | Description |
---|---|---|
204 | No Content | conversation and message s were successfully deleted. |
404 | Not Found | conversation with the given ID does not exist. |
Texting - Messages
message
endpoints
Get messages from conversation
Fetch the third page of messages from a conversation
conversation_id = '616566b94b8fa0626751ef96'
query = {
'page': 3
}
request = requests.get(API_URL + '/texting/conversations/' + conversation_id + '/messages', \
headers = headers, params = query)
print(request.json())
GET /texting/conversations/{conversation_id}/messages
Get message
s from a given conversation
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
page |
query | integer | false | Index of the page of message s |
per_page |
query | integer | false | Number of message s per page |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of message s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of message s per page |
Mark message as read
Mark a specific message in a conversation as seen
body = {
'is_read': True
}
conversation_id = '615717df4b8fa06267cd2f73'
message_id = '615717dfaea77fef6ace1bbf'
request = requests.patch(API_URL + '/texting/conversations/' + conversation_id + '/messages/' + message_id, \
headers = headers, json = body)
print(request.json())
PATCH /texting/conversations/{conversation_id}/messages/{message_id}
Update a message
in a conversation
as read.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
message_id |
path | message id string |
true | ID of the message being updated |
conversation_id |
path | conversation id string |
true | ID of the conversation the message belongs to |
body | body | object | true | Payload |
» is_read |
body | boolean | true | Whether the message should be marked as read |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | message successfully updated and returned. |
400 | Bad Request | Payload contains invalid values. |
404 | Not Found | A message of the given ID does not exist. |
Send outbound message
Send a message
conversation_id = '615717df4b8fa06267cd2f73'
body = {
'text': 'Hello world!'
}
request = requests.post(API_URL + '/texting/conversations/' + conversation_id + '/messages/publish', \
headers = headers, json = body)
print(request.json())
POST /texting/conversations/{conversation_id}/messages/publish
Send an SMS or MMS message.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
conversation_id |
path | conversation id string |
true | ID of the target conversation |
body | body | message object |
true | message to be sent |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | message was successfully sent. |
Get messages in conversation
Get the ten latest messages in a conversation
query = {
'per_page': 10,
'page': 1
}
conversation_id = '615717df4b8fa06267cd2f73'
request = requests.get(API_URL + '/texting/conversations/' + conversation_id + '/messages', \
headers = headers, params = query)
print(request.json())
GET /texting/conversations/{conversation_id}/messages
Return the list of message
s in the given conversation
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
conversation_id |
path | conversation id string |
true | ID of the conversation being queried |
page |
query | integer | false | Index of the page of message s |
per_page |
query | integer | false | Number of message s per page |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of message s in conversation successfully returned. |
404 | Not Found | conversation with the given ID does not exist. |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of message s in conversation |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of message s per page |
Delete messages in conversation
Delete two specific messages in a conversation
query = {
'ids': ['61656c90730737f190ed288a', '615717dfaea77fef6ace1bbf']
}
conversation_id = '615717df4b8fa06267cd2f73'
request = requests.delete(API_URL + '/texting/conversations/' + conversation_id + '/messages', \
headers = headers)
print(request.json())
DELETE /texting/conversations/{conversation_id}/messages
Delete multiple message
s in given conversation
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
ids |
query | [message id string] |
false | IDs of message s to be deleted |
conversation_id |
path | conversation id string |
true | conversation the message s belong to |
Responses
Status | Meaning | Description |
---|---|---|
204 | No Content | message s in the conversation were successfully deleted. |
404 | Not Found | message s with the given IDs or conversation with the given ID do not exist. |
Texting - Contacts
texting contact
endpoints
Create texting contact
Create a new contact for texting
body = {
'number': '+12340009999'
}
request = requests.post(API_URL + '/texting/contacts', headers = headers, json = body)
print(request.json())
POST /texting/contacts
Create a texting contact
. A company_id
field will be added automatically.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | texting contact object |
true | texting contact to create |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Given texting contact already exists for this company. |
201 | Created | texting contact successfully created and returned. |
Get texting contacts
Find texting contacts named Jane
query = {
'search': 'Jane'
}
request = requests.get(API_URL + '/texting/contacts', headers = headers, params = query)
print(request.json())
GET /texting/contacts
Return the list of texting contact
s.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
search |
query | string | false | Search query |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of texting contact s successfully returned. |
404 | Not Found | texting contact with the given ID does not exist. |
Get texting contact by ID
Get a texting contact
texting_contact_id = '61254ea54b8fa062670a3fb1'
request = requests.get(API_URL + '/texting/contacts/' + texting_contact_id, headers = headers)
print(request.json())
GET /texting/contacts/{texting_contact_id}
Get texting contact
by ID.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
texting_contact_id |
path | texting contact id string |
true | ID of the texting contact to be returned |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | texting contact successfully returned. |
404 | Not Found | texting contact with the given ID does not exist. |
Update texting contact
Replace a texting contact
texting_contact_id = '61254ea54b8fa062670a3fb1'
body = {
'number': '11235554321'
}
request = requests.put(API_URL + '/texting/contacts/' + texting_contact_id, \
headers = headers, json = body)
print(request.json())
PUT /texting/contacts/{texting_contact_id}
Update texting contact
. company_id
parameter will be added automatically.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
texting_contact_id |
path | texting contact id string |
true | ID of the texting contact to be updated |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | texting contact successfully updated. |
404 | Not Found | texting contact with the given ID does not exist. |
Texting - Numbers
texting number
endpoints
Get texting numbers
Get available texting numbers
query = {
'numformat': 'international'
}
request = requests.get(API_URL + '/texting/numbers', headers = headers, params = query)
print(request.json())
GET /texting/numbers
Return texting number
s owned by the current user.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
numformat |
query | enum string | false | Telephone number format for the response string. |
Enumerated Values
Parameter | Value |
---|---|
numformat |
international |
numformat |
national |
Example response
[
{
"company_id": "611ced1255c44a89f8df7cc0",
"id": "61254e814b8fa062670a3e14",
"number": "+18273717273",
"ownership": [
"janedoe@example.com"
]
}
]
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of texting number s successfully returned. |
Update number ownership
Assign two email addresses to a texting number
number = '3215551234'
body = ['janedoe@example.com', 'johnsmith@example.com']
request = requests.put(API_URL + '/texting/numbers/' + number, headers = headers, json = body)
print(request.json())
PUT /texting/numbers/{number}
Update the owner emails of the texting number
for the given number.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
number |
path | string | true | Number of the texting number to be updated |
body | body | [string] | true | Array of emails to assign texting number ownership to |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | texting number successfully updated and returned. |
404 | Not Found | texting number with the given number does not exist. |
Voicemails
voicemail
endpoints
Get voicemails
Get the third page of voicemails from extensions 1001 to 1002
query = {
'extension_source': 1001,
'extension_destination': 1002,
'page': 3
}
request = requests.get(API_URL + '/voicemail/messages/', headers = headers, params = query)
print(request.json())
GET /voicemail/messages
Return the list of all available voicemail
s, optionally filtered and sorted with query parameters.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
from_date |
query | date string | false | Starting date |
to_date |
query | date string | false | Ending date |
page |
query | integer | false | Index of the page of voicemail s |
per_page |
query | integer | false | Number of voicemail s per page |
sort |
query | [string] | false | Fields to sort by |
extension_source |
query | integer | false | Number of the sending extension |
extension_destination |
query | integer | false | Number of the receiving extension |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of voicemail s successfully returned. |
400 | Bad Request | Invalid parameter provided. |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of voicemail s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of voicemail s per page |
Fax - Destinations
destination
endpoints
Create fax destination
Create new destination
body = {'emails': ['myfax@example.com']}
request = requests.post(API_URL + '/fax/destinations', headers = headers, json = body)
print(request.json())
POST /fax/destinations
Create a new destination
for fax message
s.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | destination object |
true | destination to create |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Given destination already exists for this company. |
201 | Created | destination successfully created and returned. |
Fax - Messages
fax message
endpoints
Get inbound fax messages
Get messages from a specific sender with a specific subject between certain dates
query = {
'name': 'Alyssa',
'subject': 'Payment Details',
'start_date': '2021-11-01T18:00:00',
'end_date': '2021-06-01T09:00:00'
}
request = requests.get(API_URL + '/fax/messages/inbound', headers = headers, params = query)
print(request.json())
GET /fax/messages/inbound
Return the list of inbound fax message
s, optionally filtered and sorted by paremeters.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
page |
query | integer | false | Index of the page of fax message s |
per_page |
query | integer | false | Number of fax message s per page |
sort |
query | [string] | false | Fields to sort by |
start_date |
query | date string | false | Starting date |
end_date |
query | date string | false | Ending date |
number |
query | string | false | Source fax number |
name |
query | string | false | Sender name |
is_read |
query | boolean | false | Read status |
undefined |
query | boolean | false | Whether to show messages from anonymous/undefined senders |
subject |
query | string | false | Message subject |
search |
query | string | false | Search string |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of fax message s successfully returned. |
400 | Bad Request | Invalid parameter provided. |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of fax message s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of fax message s per page |
Delete an inbound fax message
Delete an inbound message
fax_message_id = 'a8f3260b07657b92121973fc'
request = requests.delete(API_URL + '/fax/messages/inbound/' + fax_message_id, headers = headers)
print(request.json())
DELETE /fax/messages/inbound/{fax_message_id}
Delete the given fax message
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fax_message_id |
path | fax message id string |
true | ID of the fax message to be deleted |
Responses
Status | Meaning | Description |
---|---|---|
204 | No Content | fax message successfully deleted. |
404 | Not Found | fax message with the given ID does not exist. |
Update an inbound fax message
Partially update an inbound fax message
body = {
'to_name': 'Alice'
}
fax_message_id = 'a8f3260b07657b92121973fc'
request = requests.patch(API_URL + '/fax/messages/inbound/' + fax_message_id, \
headers = headers, json = body)
print(request.json())
PATCH /fax/messages/inbound/{fax_message_id}
Partially update the given inbound fax message
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fax_message_id |
path | fax message id string |
true | ID of the fax message to be updated |
body | body | fax message object |
true | Partial or full fax message object |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | fax message successfully updated and returned. |
400 | Bad Request | Payload contains invalid values. |
404 | Not Found | fax message with the given ID does not exist. |
Get outbound fax messages
Get messages to a specific recipient with a specific subject between certain dates
query = {
'name': 'Bob',
'subject': 'Status Update',
'start_date': '2021-11-01T18:00:00',
'end_date': '2021-06-01T09:00:00'
}
request = requests.get(API_URL + '/fax/messages/outbound', headers = headers, params = query)
print(request.json())
GET /fax/messages/outbound
Return the list of outbound fax message
s, optionally filtered and sorted by paremeters.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
page |
query | integer | false | Index of the page of fax message s |
per_page |
query | integer | false | Number of fax message s per page |
sort |
query | [string] | false | Fields to sort by |
start_date |
query | date string | false | Starting date |
end_date |
query | date string | false | Ending date |
number |
query | string | false | Destination fax number |
name |
query | string | false | Recipient name |
subject |
query | string | false | Message subject |
search |
query | string | false | Search string |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of fax message s successfully returned. |
400 | Bad Request | Invalid parameter provided. |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of fax message s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of fax message s per page |
Send a new fax message
Create an outbound message
body = {
'emails': 'bob@example.com',
'file': {'id': '30b19a2ff4cb9e50ac109eae'},
'from': '2052726012',
'from_name': 'Alice',
'subject': 'Update my contact details',
'to': '8584375000',
'to_name': 'Bob'
}
request = requests.post(API_URL + '/fax/messages/outbound', headers = headers, json = body)
print(request.json())
POST /fax/messages/outbound
Create a new outbound fax message
and send it.
Parameters
Name | In | Type | Description |
---|---|---|---|
body | body | fax message object |
fax message to be created and sent |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | fax message successfully created and sent. |
400 | Bad Request | Payload contains invalid values. |
Delete an outbound fax message locally
Delete an outbound message
fax_message_id = 'a8f3260b07657b92121973fc'
request = requests.delete(API_URL + '/fax/messages/outbound/' + fax_message_id, headers = headers)
print(request.json())
DELETE /fax/messages/outbound/{fax_message_id}
Delete the local data for the given outbound fax message
.
Parameters
Name | In | Type | Description |
---|---|---|---|
fax_message_id |
path | fax message id string |
ID of the fax message to be deleted |
Responses
Status | Meaning | Description |
---|---|---|
204 | No Content | fax message successfully deleted. |
404 | Not Found | fax message with the given ID does not exist. |
Update a failed fax message
Update an outbound message before it is resent
body = {
'to': '8584375001'
}
fax_message_id = 'a8f3260b07657b92121973fc'
request = requests.put(API_URL + '/fax/messages/outbound/' + fax_message_id, \
headers = headers, json = body)
print(request.json())
PUT /fax/messages/outbound/{fax_message_id}
Update an outbound fax message
that has failed.
Parameters
Name | In | Type | Description |
---|---|---|---|
fax_message_id |
path | fax message id string |
ID of the fax message to be updated |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | fax message successfully updated and returned. |
400 | Bad Request | Payload contains invalid values. |
404 | Not Found | fax message with the given ID does not exist. |
406 | Not Acceptable | This operation is only available for failed outbound fax message s. |
Retry a failed fax message
Resend outbound message
fax_message_id = 'a8f3260b07657b92121973fc'
request = requests.post(API_URL + '/fax/messages/outbound/' + fax_message_id + '/retry', \
headers = headers)
print(request.json())
POST /fax/messages/outbound/{fax_message_id}/retry
Resend an outbound fax message
that has failed.
Parameters
Name | In | Type | Description |
---|---|---|---|
fax_message_id |
path | fax message id string |
ID of the fax message to be resent |
Responses
Status | Meaning | Description |
---|---|---|
202 | Accepted | fax message accepted for resending and returned. |
404 | Not Found | fax message with the given ID does not exist. |
406 | Not Acceptable | This operation is only available for failed outbound fax message s. |
Get scheduled fax messages
Get scheduled messages to a specific number created before a certain date
query = {
'number': '3215551234',
'end_date': '2021-06-01T09:00:00'
}
request = requests.get(API_URL + '/fax/messages/scheduled', headers = headers, params = query)
print(request.json())
GET /fax/messages/scheduled
Return the list of fax message
s scheduled for sending, optionally filtered and sorted by paremeters.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
page |
query | integer | false | Index of the page of fax message s |
per_page |
query | integer | false | Number of fax message s per page |
sort |
query | [string] | false | Fields to sort by |
start_date |
query | date string | false | Starting date |
end_date |
query | date string | false | Ending date |
number |
query | string | false | Destination fax number |
name |
query | string | false | Recipient name |
subject |
query | string | false | Message subject |
search |
query | string | false | Search string |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of fax message s successfully returned. |
400 | Bad Request | Invalid parameter provided. |
Response Headers
Status | Header | Type | Description |
---|---|---|---|
200 | X-Pagination-Total-Count |
integer | Total number of fax message s |
200 | X-Pagination-Page-Count |
integer | Number of pages |
200 | X-Pagination-Current-Page |
integer | Index of the current page |
200 | X-Pagination-Per-Page |
integer | Number of fax message s per page |
Schedule a new fax message
Create new message to be sent at a given date
body = {
'emails': 'bob@example.com',
'file': {'id': '30b19a2ff4cb9e50ac109eae'},
'from': '2052726012',
'from_name': 'Alice',
'subject': 'Remember to update my contact details',
'to': '8584375000',
'to_name': 'Bob',
'send_at': '2021-11-15T09:00:00' # Time of schedule
}
request = requests.post(API_URL + '/fax/messages/scheduled', headers = headers, json = body)
print(request.json())
POST /fax/messages/scheduled
Create a new outbound fax message
and schedule it for sending.
Parameters
Name | In | Type | Description |
---|---|---|---|
body | body | fax message object |
fax message to be created and scheduled |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | fax message successfully created and scheduled. |
400 | Bad Request | Payload contains invalid values. |
Cancel a scheduled fax message
Delete a scheduled message
fax_message_id = '7081e68fcebe251d6b612fb2'
request = requests.delete(API_URL + '/fax/messages/scheduled/' + fax_message_id, headers = headers)
print(request.json())
DELETE /fax/messages/scheduled/{fax_message_id}
Delete a scheduled fax message
before it could be sent.
Parameters
Name | In | Type | Description |
---|---|---|---|
fax_message_id |
path | fax message id string |
ID of the fax message to be deleted |
Responses
Status | Meaning | Description |
---|---|---|
204 | No Content | fax message successfully deleted. |
404 | Not Found | fax message with the given ID does not exist. |
Update a scheduled fax message
Update a message before it can be sent
body = {
'subject': 'Update my contact details (important!)'
}
fax_message_id = 'a8f3260b07657b92121973fc'
request = requests.put(API_URL + '/fax/messages/scheduled/' + fax_message_id, \
headers = headers, json = body)
print(request.json())
PUT /fax/messages/scheduled/{fax_message_id}
Update a scheduled fax message
.
Parameters
Name | In | Type | Description |
---|---|---|---|
fax_message_id |
path | fax message id string |
ID of the fax message to be updated |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | fax message successfully updated and returned. |
400 | Bad Request | Payload contains invalid values. |
404 | Not Found | fax message with the given ID does not exist. |
Get fax statistics
Get fax message statistics for the company
request = requests.get(API_URL + '/fax/statistics', headers = headers)
print(request.json())
GET /fax/statistics
Return the numbers of total fax message
s in the company.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An object of fax message numbers successfully returned. |
On 200 OK:
Field | Type | Description | Example |
---|---|---|---|
inbound |
integer | Number of inbound messages | 10 |
inbound_hidden |
integer | Number of hidden inbound messages | 3 |
outbound |
integer | Number of outbound messages | 5 |
Fax - Numbers
Get fax numbers
Get all fax numbers
request = requests.get(API_URL + '/fax/numbers', headers = headers)
print(request.json())
GET /fax/numbers
Return the list of all fax numbers available in the company.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of fax number strings successfully returned. |
Meet - Authentication
Get calendar for current user
Get calendar
request = requests.get(API_URL + '/meet/app/calendar', headers = headers)
print(request.json())
GET /meet/app/calendar
Return the Google Calendar details for the current contact
.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Calendar description object successfully returned. |
404 | Not Found | There is no calendar for this contact . |
On 200 OK:
Field | Type | Description | Example |
---|---|---|---|
calendar |
string | Calendar link | |
update |
date string | Date of last update | "2021-12-12" |
user_id |
contact id string |
ID of the contact |
"60190ce750fe88ed1a544a7a" |
Get meeting link
Get URL for specified meeting
meeting_id = '214824405'
request = requests.get(API_URL + '/meet/app/calendar/events/get-link/' + meeting_id, \
headers = headers)
print(request.json())
GET /meet/app/calendar/events/get-link/{meeting_id}
Return a meeting URL object for the given meeting ID.
Parameters
Name | In | Type | Description |
---|---|---|---|
meeting_id |
path | id string | ID of the meeting |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Meeting link object successfully returned. |
404 | Not Found | Invalid meeting ID. |
On 200 OK:
Field | Type | Description | Example |
---|---|---|---|
full_link |
string | URL of the meeting | "https://meet.ringplan.com/..." |
Get Google Calendar authentication link
Get Google Calendar OAuth2 link
request = requests.get(API_URL + '/meet/app/calendar/get-auth-url', headers = headers)
print(request.json())
GET /meet/app/calendar/get-auth-url
Return the Google Calendar OAuth2 authentication URL object for the current contact
.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | OAuth2 URL successfully returned. |
On 200 OK:
Field | Type | Description | Example |
---|---|---|---|
auth_url |
string | Google Calendar OAuth2 URL | "https://accounts.google.com/o/oauth2/auth?..." |
Get Outlook Calendar authentication link
Get Outlook Calendar OAuth2 link
request = requests.get(API_URL + '/meet/app/outlook/get-auth-url', headers = headers)
print(request.json())
GET /meet/app/outlook/get-auth-url
Return the Outlook Calendar OAuth2 authentication URL object for the current contact
.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | OAuth2 URL successfully returned. |
On 200 OK:
Field | Type | Description | Example |
---|---|---|---|
auth_url |
string | Outlook Calendar OAuth2 URL | "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?..." |
Revoke Google Calendar authentication
Revoke Google Calendar authentication
body = {
'calendar': 'example@gmail.com'
}
request = requests.post(API_URL + '/meet/google/revoke, headers = headers, json = body)
print(request.json())
POST /meet/google/revoke
Revoke Google Calendar OAuth2 authentication for the current contact
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | object | true | Payload |
» calendar |
body | string | true | Gmail address |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Authentication successfully revoked. |
400 | Bad Request | Failed to revoke authentication. |
On 200 OK or 400 Bad Request:
Field | Type | Description | Example |
---|---|---|---|
result |
boolean | Result | true |
Revoke Outlook Calendar authentication
Revoke Outlook Calendar authentication
body = {
'calendar': 'example@outlook.com'
}
request = requests.post(API_URL + '/meet/outlook/revoke, headers = headers, json = body)
print(request.json())
POST /meet/outlook/revoke
Revoke Outlook Calendar OAuth2 authentication for the current contact
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | object | true | Payload |
» calendar |
body | string | true | Outlook address |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Authentication successfully revoked. |
400 | Bad Request | Failed to revoke authentication. |
On 200 OK or 400 Bad Request:
Field | Type | Description | Example |
---|---|---|---|
result |
boolean | Result | true |
Meet - Events
Webhooks
webhook url
and webhook event
endpoints
Get webhook callback URL
Get webhook callback URL
request = requests.get(API_URL + '/webhooks/callbacks/url', headers = headers)
print(request.json())
GET /webhooks/callbacks/url
Return the webhook url
for the current company
.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | webhook url successfully returned. |
Update webhook callback URL
Update callback URL of a webhook
body = {
'url': 'https://www.example.com'
}
request = requests.put(API_URL + '/webhooks/callbacks/url', headers = headers, json = body)
print(request.json())
PUT /webhooks/callbacks/url
Update the webhook url
s for the current company
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | webhook url object |
true | The webhook url object to update the current one with |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | webhook url successfully updated and returned. |
Get subscribed webhook events
Get webhook callback events
request = requests.get(API_URL + '/webhooks/callbacks', headers = headers)
print(request.json())
GET /webhooks/callbacks
Get the subscribed webhook event
s.
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | An array of webhook event s successfully returned. |
Subscribe to webhook event
Subscribe to a webhook event
body = {
'type': 'texting.message.inbound'
}
request = requests.post(API_URL + '/webhooks/callbacks', headers = headers, json = body)
print(request.json())
POST /webhooks/callbacks
Subscribe to a webhook event
.
The event type is one of
dial.action.started
dial.action.completed
call.action.hangup
texting.message.inbound
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | webhook event object |
true | Replacement webhook event |
Responses
Status | Meaning | Description |
---|---|---|
201 | Created | A webhook event was successfully created and returned. |
Unsubscribe from webhook event
Delete a subscribed webhook event
webhook_event_id = '6165732029a740a320e8031f'
request = requests.delete(API_URL + '/webhooks/callbacks/' + webhook_event_id, headers = headers)
print(request.json())
DELETE /webhooks/callbacks/{webhook_event_id}
Unsubscribe from webhook event
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
webhook_event_id |
path | webhook event id string |
true | webhook event to unsubscribe from |
Responses
Status | Meaning | Description |
---|---|---|
200 | OK | Successfully unsubscribed from webhook event . |
WebSocket
RingPlan websocket API works through the same URI as the one used for HTTP requests and is available on every environment. The details are generally uniform with the HTTP API unless noted otherwise.
Socket initialization in JavaScript
import { io } from 'socket.io-client';
const socket = io('https://ssp-backend.ringplan.com', {
path: '/ws',
transports: ['websocket'],
secure: true,
autoConnect: false,
reconnectionDelay: 1500
});
Socket initialization in Python
import socketio
if __name__ == '__main__':
sio.connect('http://ssp-backend.ringplan.com', socketio_path='/ws/')
sio.wait()
The server will emit three types of events:
Server event | Description |
---|---|
connect |
Connection successful. |
authenticated |
Authentication successful. |
unauthorized |
Client attempted to send data without authenticating. |
Custom handler
if __name__ == '__main__':
# It is possible to override `trigger_event()` and write a custom handler.
class MyCustomNamespace(socketio.ClientNamespace):
# To catch all events:
def trigger_event(self, event_name, sid, *args):
print(f"{event_name=}, {sid=}")
if args:
print(f"data is {args[0]}")
sio.register_namespace(MyCustomNamespace())
sio.connect('http://ssp-backend.ringplan.com', socketio_path='/ws/')
sio.wait()
In turn, the client can emit the following event:
Client event | Description |
---|---|
authenticate |
Sending authentication token. |
After initializing the socket, the client should listen for the connect
event,
then reply with an authenticate
event containing the authentication token.
Socket authentication in JavaScript
socket.connect()
socket.once('connect', function(socket) {
socket.emit('authenticate', { token: API_KEY });
socket.once('authenticated', function(socket) {
console.log('Authentication successful.');
});
Socket authentication and event handling in Python
@sio.event
def connect():
sio.emit('authenticate', {'token': API_KEY, 'user_email': USER_EMAIL})
print('Connected.')
@sio.event
def disconnect():
print('Disconnected.')
@sio.on('authenticated')
def authenticated(data):
print('Authentication successful.')
@sio.on('unauthorized')
def unauthorized(data):
print('Unauthorized!')
The socket is ready to use once the client receives the authenticated
event.
Messages - Client
Message events the client emits to the server and the other clients.
Mark messages as read
texting.message.markAsRead
Mark the given message
s as read.
Name | Type | Description |
---|---|---|
conversation_id |
conversation id string |
ID of the conversation the message s belong to |
messagesIds |
[message id string] |
Array of IDs of message s to be marked as read |
Messages - Server
Message events the server emits to the clients.
New message
texting.message.new
A new message
has arrived.
The server will yield a message
object.
Message deletion
texting.message.delete
A message
has been deleted.
Name | Type | Description |
---|---|---|
id |
message id string |
ID of the deleted message |
conversation_id |
conversation id string |
ID of the conversation |
Message marked read
texting.message.markAsRead
The message
s have been marked as read.
Name | Type | Description |
---|---|---|
conversation_id |
conversation id string |
ID of the conversation the message s belong to |
messagesIds |
[message id string] |
Array of IDs of message s marked as read |
timezone |
string | Timezone of the sender |
Chats - Server
Chat events the server emits to the clients.
Chat creation
Handle new message
@sio.on('texting.message.new')
def msg_new(data):
print('texting.message.new', data)
texting.chat.new
A new conversation
has been created.
The server will yield a conversation
object.
Chat deletion
Handle message deletion
@sio.on('texting.message.delete')
def msg_delete(data):
print('texting.message.delete', data)
texting.chat.delete
The conversation
has been deleted.
Name | Type | Description |
---|---|---|
id |
conversation id string |
ID of the deleted conversation |
User status - Server
user_status_updated
A texting contact
's status has changed.
Name | Type | Description |
---|---|---|
company_id |
company id string |
ID of the texting contact 's company |
user_id |
texting contact id string |
ID of the texting contact |
user_email |
string | Email address |
status |
object | - |
» status |
string | Actual status string |
» action_type |
string | Method the status was set |
id |
id string | Status ID |
created_at |
date string | Date the status was set |
updated_at |
date string | Date the status was updated |
deleted_at |
date string | Date the status was unset |
Objects
RingPlan API uses multiple different objects for internal representation.
Descriptions of object fields are provided below in alphabetical order, following the ID field.
Address
Address has fields that describe individual parts of a company or a user's physical address. Address objects do not have ID fields because they are user provided and are not necessarily unique.
Field | Type | Description | Example |
---|---|---|---|
address2 |
string | Secondary address line | |
city |
string | City of residence | "San Diego" |
country |
string | Country of residence | "United States" |
number |
string | Building number | |
state |
string | State code (if applicable) | "CA" |
street |
object | Street details | - |
» name |
string | Street name | "Foo Lane" |
» number |
integer | Street number | 23 |
» type |
string | Street type | "Avenue" |
zip |
string | US ZIP code (if applicable) | "12345" |
Company
Company holds the information for each individual company. The company object forms the core of the object relations in RingPlan API.
Field | Type | Description | Example |
---|---|---|---|
id |
company id string |
Internal ID | "611ced1255c44a89f8df7cc0" |
address |
address object |
Physical address | see Address |
affiliate |
boolean | Participating in partner invite program | false |
billing_email |
string | Email address for invoices | "billing@example.com" |
created |
date string | Date of account creation | "2021-08-18T14:20:50.837000+0100" |
description |
string | Additional information | |
email |
string | Email address | "contact@example.com" |
emergency_contact_number |
string | Emergency contact number | "15554441234" |
employees |
integer | Number of users | 5 |
fax |
string | Fax number | "13235551234" |
name |
string | Formal name | "Example Corp" |
onboarding |
boolean | Onboarding successfully completed | true |
partner_id |
id string | Partner invite program ID | |
phone |
string | Regular contact number | "15555554321" |
revenue |
integer | Recognised revenue | |
status |
string | Current status | "active" |
updated |
date string | Date of last update | "2021-08-25T02:53:44.016000+0100" |
website |
string | Homepage URL | "https://example.com" |
Contact
Contact describes a user within a company. Each user belongs to a company.
Field | Type | Description | Example |
---|---|---|---|
id |
contact id string |
Internal ID | "611ced1355c44a89f8df7cc3" |
activated |
boolean | Whether the user is enabled | true |
address |
address object |
Physical address of the user | see Address |
birthdate |
date string | Date of birth | |
company_id |
company id string |
ID of the company the user belongs to | "611ced1255c44a89f8df7cc0" |
contacts |
object | Contact numbers and addresses | - |
» email |
string | Email address | "janedoe@example.com" |
» fax |
string | Fax number | |
» phones |
object | Phone numbers | - |
» » home |
string | Home number | |
» » mobile |
string | Mobile number | |
» » other |
string | Miscellaneous numbers | |
» » work |
string | Work number | |
created |
date string | Account creation date | "2021-08-18T11:20:51.510000Z" |
description |
string | Additional information | |
extension |
object | Extension number | - |
» id |
id string | Internal ID | "61254e7f884ca03e99ba0dfe" |
» description |
string | Information about extension |
"Megacorp Accountancy Department" |
» name |
string | Name of the extension |
"MC Acc Dpt" |
» number |
integer | extension number |
1001 |
first_name |
string | Forename | "Jane" |
invitation |
object | User creation invitation information | - |
» accepted_at |
date string | Invitation link acceptance date | |
» expired_at |
date string | Invitation link expiry date | |
» issued_at |
date string | Invitation link creation date | |
» status |
string | Invitation link status | "accepted" |
last_enter |
date string | Date of last login | "2021-08-24T19:46:12Z" |
last_name |
string | Surname | "Doe" |
primary_agent |
contact id string |
Primary agent ID if user is in an agent group | |
timezone |
string | Preferred timezone | "UTC" |
title |
string | Honorary title | "Ms" |
updated |
date string | Date of last update | "2021-08-25T00:05:44.201000Z", |
Conversation
Conversation represents the communication between a texting contact and phone numbers. Each conversation contains messages.
Field | Type | Description | Example |
---|---|---|---|
id |
conversation id string |
Internal ID | "615717df4b8fa06267cd2f73" |
company_id |
company id string |
company ID |
"611ced1255c44a89f8df7cc0" |
contact_id |
texting contact id string |
texting contact ID |
"615717df4b8fa06267cd2f6f" |
contactinfo |
texting contact object |
texting contact details |
see Texting Contact |
contactsinfo |
[texting contact object] |
All texting contact s in the conversation |
see Texting Contact |
conversation_type |
string | Type of the conversation |
"direct" |
countunreadmessages |
integer | Number of unread message s in the conversation |
1 |
from_number |
string | Source number | "9513360234" |
has_direct_msg |
boolean | Is the message direct? |
true |
has_hidden_msg |
boolean | Is the message hidden? |
false |
last_message_created_at |
date string | Date of last message 's creation |
"2021-10-01T17:14:55.591000+0300" |
lastmessage |
message object |
Last message sent |
|
recipients |
[texting contact id string] |
List of recipient texting contact s |
"615717df4b8fa06267cd2f6f" |
timezone |
string | Timezone of the sender | "Europe/Kiev" |
unread_msg_count |
integer | Same as countunreadmessages |
1 |
updated_at |
date string | Date of last update | "2022-08-10T12:31:37.164696" |
Destination
Destination represents the end-point for a fax message.
Field | Type | Description | Example |
---|---|---|---|
id |
destination id string |
Internal ID | "3a677c59dbaca83454fe1db4" |
company |
company id string |
company ID |
"17472b4c9e4fb15f01977c32" |
emails |
[string] | Email addresses | ["user1@company.org","user2@company.org"] |
reprname |
string | Email addresses' representation | "user1@company.org, user2@company.org" |
Extension
Extension represents the internal phone number extensions within a location.
Field | Type | Description | Example |
---|---|---|---|
_id |
string | Internal ID | "61254e7f884ca03e99ba0dfe" |
data |
object | - | |
» id |
id integer | 1001 |
|
» accountcode |
string | ||
» allow |
string | ||
» answermode |
string | "disabled" |
|
» avpf |
string | "no" |
|
» bundle |
string | "no" |
|
» busy_cid |
string | ||
» busy_dest |
string | ||
» callerid |
string | "John Smith <1001>" |
|
» callwaiting_enable |
string | "ENABLED" |
|
» chanunavail_cid |
string | ||
» chanunavail_dest |
string | ||
» cid_masquerade |
string | "1001" |
|
» concurrency_limit |
integer | 3 |
|
» context |
string | "from-internal" |
|
» description |
string | "John Smith 1001" |
|
» device_state_busy_at |
string | "0" |
|
» devicetype |
string | "fixed" |
|
» dial |
string | "PJSIP/1001" |
|
» disable_star_voicemail |
string | "no" |
|
» disallow |
string | ||
» dtmfmode |
string | "rfc4733" |
|
» emergency_cid |
string | ||
» extension |
integer | 1001 |
|
» findmefollow_annmsg_id |
string | "0" |
|
» findmefollow_calendar_id |
string | ||
» findmefollow_calendar_match |
string | "yes" |
|
» findmefollow_changecid |
string | "default" |
|
» findmefollow_dring |
|||
» findmefollow_enabled |
string | ||
» findmefollow_fixedcid |
string | ||
» findmefollow_grplist |
string | "1001" |
|
» findmefollow_grppre |
|||
» findmefollow_grptime |
integer | 30 |
|
» findmefollow_needsconf |
False |
||
» findmefollow_postdest |
string | "ext-local,vmu1001,1" |
|
» findmefollow_pre_ring |
integer | 20 |
|
» findmefollow_remotealert_id |
string | "0" |
|
» findmefollow_ringing |
|||
» findmefollow_strategy |
string | "ringallv2" |
|
» findmefollow_toolate_id |
string | "0" |
|
» findmefollow_voicemail |
string | "default" |
|
» force_rport |
string | "yes" |
|
» icesupport |
string | "no" |
|
» intercom |
string | "enabled" |
|
» mailbox |
string | "1001@device" |
|
» max_contacts |
string | "30" |
|
» maximum_expiration |
string | "7200" |
|
» media_encryption |
string | "no" |
|
» media_encryption_optimistic |
string | "no" |
|
» media_use_received_transport |
string | "no" |
|
» mohclass |
string | "default" |
|
» mwi_subscription |
string | "auto" |
|
» name |
string | "John Smith" |
|
» namedcallgroup |
string | ||
» namedpickupgroup |
string | ||
» noanswer |
string | ||
» noanswer_cid |
string | ||
» noanswer_dest |
string | ||
» outboundcid |
string | "\\"MyCorp J. Smith\\" <9513331234>" |
|
» password |
string | ||
» qualifyfreq |
string | "60" |
|
» recording |
string | ||
» recording_in_external |
string | "dontcare" |
|
» recording_in_internal |
string | "dontcare" |
|
» recording_ondemand |
string | "disabled" |
|
» recording_out_external |
string | "dontcare" |
|
» recording_out_internal |
string | "dontcare" |
|
» recording_priority |
integer | 10 |
|
» rewrite_contact |
string | "yes" |
|
» ringtimer |
string | "0" |
|
» rtcp_mux |
string | "no" |
|
» rtp_symmetric |
string | "yes" |
|
» secret |
string | ||
» sendrpid |
string | "pai" |
|
» sipdriver |
string | "chan_pjsip" |
|
» sipname |
string | ||
» tech |
string | "pjsip" |
|
» timers |
string | "yes" |
|
» transport |
string | ||
» trustrpid |
string | "yes" |
|
» user |
string | "1001" |
|
» vmx_busy_enabled |
string | "blocked" |
|
» vmx_option_0_number |
string | ||
» vmx_option_1_number |
string | ||
» vmx_option_2_number |
string | ||
» vmx_play_instructions |
boolean | False |
|
» vmx_temp_enabled |
string | "blocked" |
|
» vmx_unavail_enabled |
string | "blocked" |
|
» voicemail |
string | "default" |
|
» voicemail_email |
string | "jsmith@example.com" |
|
» voicemail_enable |
string | "yes" |
|
» voicemail_options |
string | `"attach=yes\ | |
» voicemail_pager |
string | ||
» voicemail_same_exten |
string | "no" |
|
» voicemail_vmpwd |
string | "1001" |
|
location_id |
location id string |
"61254e7ecbe793d0e26c7996" |
|
outbound_callerid |
object | - | |
» name |
string | "MyCorp J. Smith" |
|
» number |
string | "9513360234" |
|
» value |
string | "\"MyCorp J. Smith\" <9513360234>" |
|
pbx |
instance uuid string |
"279951a6-4f51-5019-a897-0e7624828abf" |
|
phone |
[object] | - | |
» _id |
id string | "61254e804b8fa062670a3df9" |
|
» company |
string | "611ced1255c44a89f8df7cc0" |
|
» data |
object | - | |
» » reg |
[object] | - | |
» » » displayname |
string | "John Smith" |
|
» » » label |
string | "1001" |
|
» » » password |
string | ||
» » » server |
[object] | - | |
» » » » address |
string | "foobar.ringplan.com" |
|
» » » userid |
id integer | 1001 |
|
» extensions |
[extension object] |
see Extension | |
purpose |
string | "ip-phone" |
|
reserved |
object | - | |
» config_id |
id string | "61254e804b8fa062670a3df9" |
|
» to |
string | "polycom" |
|
subscriber |
object | - | |
» call_status |
string | "on_hold" |
|
» extension_id |
extension id string |
"61254e7f884ca03e99ba0dfe" |
|
» state |
string | "UNAUTHENTICATED" |
|
user |
contact object |
see Contact |
Fax Message
A fax message is a message sent through destinations.
Field | Type | Description | Example |
---|---|---|---|
id |
fax message id string |
Internal ID | "a8f3260b07657b92121973fc"" |
company |
company id string |
company ID |
"7081e68fcebe251d6b612fb2"" |
created_at |
date string | Date of transmission | "2019-06-13T14:46:24.834000Z"" |
file |
object | Fax contents | - |
» id |
id string | Internal ID | "30b19a2ff4cb9e50ac109eae" |
» internal_id |
id integer | Internal ID | 42 |
from |
string | Source fax number | "2052726012" |
from_name |
string | Sender name | "Bob" |
is_read |
boolean | Whether the message was read | true |
pages |
integer | Length of message in pages | 2 |
subject |
string | Title of the message | "Test FAX message" |
to |
string | Destination fax number | "8584375000" |
to_name |
string | Recipient name | "Alice" |
File
Files are uploaded files used in attachments to messages.
Field | Type | Description | Example |
---|---|---|---|
id |
file id string |
Internal ID | "f4f2fdda269d44bc403de84a" |
company_id |
company id string |
company ID |
"5cd2d3384368b16e31c454ff" |
description |
string | Textual description | "A cat on table" |
mimetype |
string | MIME type | "image/jpeg" |
name |
string | Name given | "My Cat" |
preview |
object | Preview | - |
» base64 |
string | Entire preview file in base64 | "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASA...BDAAK3ALon//Z" |
» filename |
string | Preview filename | "cat_picture_preview.jpg" |
» mimetype |
string | MIME type of preview | "image/jpeg" |
size |
integer | Size in bytes | 284821 |
uploaded_at |
date string | Date of upload | "2018-12-29T11:24:22.943306Z" |
uploaded_name |
string | Filename | "cat_picture.jpg" |
user_id |
texting contact id |
Uploading texting contact |
"5cd2d338436ff8b16e31c454" |
Instance
Instance refers to a dedicated PBX instance belonging to a company. The PBX UUID rather than the internal ID is used when referring to instances.
Field | Type | Description | Example |
---|---|---|---|
_id |
instance id string |
Internal ID | "61254e7c4b8fa062670a3d9b" |
uuid |
instance uuid string |
PBX UUID | "279951a6-4f51-5019-a897-0e7624828abf" |
accountcode |
string | Internal PBX code for CDR | "SB-A00001234" |
channel_driver |
string | SIP driver | "chan_pjsip" |
company_id |
company id string |
ID of the company |
"611ced1255c44a89f8df7cc0" |
company_name |
string | Name of the company |
"My Company Inc" |
external_domain |
string | Main domain name | "testing.example.com" |
fqdn |
string | Domain name to access the instance |
"foobar.testing.example.com" |
hostname |
string | Internal hostname | "foobar" |
internal_domain |
string | Internal domain | "foobar.local" |
ip |
string | IP address of the host | "198.51.100.1" |
proxy_ip |
string | SIP proxy IP address | "203.0.113.1" |
Location
Location refers to a specific physical location with its own PBX instance. Every company has at least one location.
Field | Type | Description | Example |
---|---|---|---|
id |
location id string |
Internal ID | "61254e7ecbe793d0e26c7996" |
address2 |
string | Second line of address | |
building |
object | Building details | - |
» type |
string | Building type | "Apartment" |
» value |
string | Building number | "42" |
callerid |
string | Caller ID service number | "9513360234" |
city |
string | City of location |
"Chula Vista" |
company_id |
company id string |
ID of the company residing |
"611ced1255c44a89f8df7cc0" |
country |
string | Country of location |
"United States" |
e911_provisioned |
boolean | Registered to E911 services? | false |
email |
string | Email address representing the location |
"cv@example.com" |
fax |
string | Fax number | "15554443333" |
latitude |
float | Geographic coordinates | 33.3877219 |
longitude |
float | Geographic coordinates | -116.7919419 |
name |
string | Human readable name of the location |
"Main location" |
pbx_id |
instance uuid string |
UUID of the PBX instance |
"279951a6-4f51-5019-a897-0e7624828abf" |
phone |
string | Main phone number | "15553334444" |
state |
string | First-level administrative division | "CA" |
street |
object | Street details | - |
» name |
string | Street name | "Foo Lane" |
» number |
integer | Street number | 23 |
» type |
string | Street type | "Avenue" |
zip |
string | ZIP code or postal code | "91901" |
Message
A message refers to each text message sent in a conversation.
Field | Type | Description | Example |
---|---|---|---|
id |
message id string |
Internal ID | "615717dfaea77fef6ace1bbf" |
campaign_info |
object | Campaign group conversation information | - |
» name |
string | Campaign group conversation event | "NewCampaignCreate" |
conversation_id |
conversation id string |
ID of the conversation this message belongs to |
"615717df4b8fa06267cd2f73" |
conversation_type |
string | Type of conversation |
"direct" |
created_at |
date string | Creation date | "2021-10-01T17:14:55.613000+0300" |
direction |
string | Whether the message was sent or received |
"inbound" |
files |
[file object] |
Array of file s attached to the message |
[] |
frm |
string | Originating phone number | "+17604509400" |
is_read |
boolean | Is the message marked as seen? |
false |
is_visible |
boolean | Is the message currently visible? |
true |
source_conversation_type |
string | Campaign or direct conversation message | "campaign" |
stamp_id |
UUID string | "b44c10de-1d7b-4914-ac68-6af475bc3236" |
|
success |
boolean | Was the message successfully sent? |
true |
text |
string | Content of the message |
"Hello" |
timezone |
string | Timezone of the sender | "Europe/Kiev" |
to |
string | Receiving phone number | "+19513360234" |
Texting Contact
A texting contact is the source or destination of text messages and participates in conversations.
Field | Type | Description | Example |
---|---|---|---|
id |
texting contact id string |
Internal ID | "61254ea64b8fa062670a3fc8" |
company_id |
company id string |
ID of the company |
"611ced1255c44a89f8df7cc0" |
first_name |
string | First name of texting contact |
"John" |
last_name |
string | Last name of texting contact |
"Smith" |
number |
string | Phone number | "+15555551234" |
Texting Number
A texting number is a dedicated phone number for sending and receiving text messages. It is associated with a single company and can be owned by multiple email addresses.
Field | Type | Description | Example |
---|---|---|---|
id |
texting number id string |
Internal ID | "61254e814b8fa062670a3e14" |
company_id |
company id string |
company ID |
"611ced1255c44a89f8df7cc0" |
number |
string | Phone number itself | "9513301234" |
ownership |
[string] | Email addresses that own this texting number |
["janedoe@example.com"] |
Voicemail
A voicemail is a message routed by an instance, containing an audio file that conveys the message.
Field | Type | Description | Example |
---|---|---|---|
_id |
voicemail id string |
Internal ID | "61015919b3c46160a6de8ea2" |
company_id |
company id string |
ID of the company |
"6101511f25781882dec1e427" |
extension_destination |
integer | extension number receiving the voicemail |
1001 |
extension_destination_id |
extension id string |
ID of the receiving extension |
"6101522c4c901ad517cb44a7" |
extension_source |
integer | extension number sending the voicemail |
1002 |
pbx |
instance uuid string |
UUID of the PBX instance |
"c62afa64-728a-575e-80bb-d5acb29a85a4" |
source_representation_name |
string | Representative name assigned | "John Doe" |
time_received |
date string | Date of receiving | "2021-07-28T16:18:17.404000Z" |
voicemail_email |
string | Email address | "johndoe@example.com" |
voicemail_file |
object | Audio file containing the voicemail |
- |
» id |
id string | Internal ID for the file | "6101591822c291ae68f260a9" |
» duration |
float | Length of audio | 0.2 |
» link |
string | URL leading to the file | "https://filehost.example.net/msg0000.wav" |
» name |
string | File name | "msg0000.wav" |
» size |
integer | Size of file in bytes | 3244 |
Webhook URL
Webhook URL holds the URL endpoint for any webhook.
Field | Type | Description | Example |
---|---|---|---|
id |
webhook url id string |
Internal ID | "6165720df936448755a444a8" |
company_id |
company id string |
ID of the company |
"611ced1255c44a89f8df7cc0" |
url |
string | Webhook URL | "webhook.example.com" |
Webhook Event
Webhook event holds a webhook callback that can be subscribed to.
The event type is one of
dial.action.started
dial.action.completed
call.action.hangup
texting.message.inbound
Field | Type | Description | Example |
---|---|---|---|
id |
webhook url id string |
Internal ID | "6165732029a740a320e8031f" |
company_id |
company id string |
ID of the company |
"611ced1255c44a89f8df7cc0" |
type |
string | Event | "texting.message.inbound" |