Click2Call TCP API¶
The TCP transport addresses a module method by command name. It is the entry point for server-to-server integrations: CRM backends, dialer bots, reporting jobs, and anything that already holds a persistent platform connection.
The same methods are available over HTTP — see REST API. The command name and the HTTP path are two addresses of one method, with identical fields and results.
Request envelope¶
{
"command": "Click2CallStartCall",
"extID": "8f2a1c",
"data": {
"callToParentType": "CUSTOMER",
"callToParentId": 140,
"phone": "+380671234567"
}
}
| Field | Type | Description |
|---|---|---|
command |
string | Method name, exactly as published by the module |
extID |
string | Caller-generated correlation id; the response carries it back |
data |
object | Method parameters |
extID is what makes the connection full-duplex: responses and streamed events share one
socket, so a reply is matched to its request by extID rather than by arrival order.
Response¶
{
"extID": "8f2a1c",
"status": 200,
"data": {
"callId": 501,
"externalId": "prov-77213",
"status": "INITIATED"
}
}
An error keeps the same envelope: the outcome is in status, and data carries the
message.
{
"extID": "8f2a1c",
"status": 409,
"data": "Phone 380950000000 is blacklisted: customer request"
}
Status codes are the same as in REST. 502 means the module itself
is not on the bus — the platform answers instead of hanging the request. A malformed
request never reaches the module and comes back as 400 with
{"error": "NO_COMMAND_OR_EXT_ID"} or {"error": "INVALID_JSON_OBJECT"}.
Node.js SDK¶
scaletrade-server-api exposes any
published command as a method, so no client update is needed when a module adds methods:
const STPlatform = require('scaletrade-server-api');
const platform = new STPlatform(
'broker.scaletrade.com:8080',
'crm-backend',
{},
null, null,
'your-jwt-auth-token'
);
const call = await platform.Click2CallStartCall({
callToParentType: 'CUSTOMER',
callToParentId: 140,
phone: '+380671234567'
});
if (call.status === 200) {
console.log('call id', call.data.callId);
} else {
// On failure `data` is the message text, not an object.
console.error(call.status, call.data);
}
Long-running work is not awaited on the socket: Click2CallStartCall returns as soon as
the provider accepts the request. The outcome of the conversation arrives later as an
event.
Commands¶
Calls¶
| Command | Description |
|---|---|
| Click2CallStartCall | Start an outbound call |
| Click2CallEndCall | Hang up an active call |
| Click2CallGetCalls | Call history with filters and aggregates |
| Click2CallGetCallRecording | Recording link |
| Click2CallGetLastCallsByParents | Last call time for a batch of customers or leads |
Providers and profiles¶
| Command | Description |
|---|---|
| Click2CallGetProviderAdapters | Implemented adapters and their capabilities |
| Click2CallAddProvider | Register a provider |
| Click2CallUpdateProvider | Update a provider |
| Click2CallDeleteProvider | Soft-delete a provider |
| Click2CallGetProviders | Provider catalogue |
| Click2CallAddProfile | Create a provider profile |
| Click2CallUpdateProfile | Update a provider profile |
| Click2CallDeleteProfile | Soft-delete a provider profile |
| Click2CallGetProfiles | Provider profiles of the brand |
| Click2CallGetMyProfiles | Profiles available to the current manager |
Agents and dial rules¶
| Command | Description |
|---|---|
| Click2CallAddAgent | Link a manager to a provider line |
| Click2CallUpdateAgent | Update the link |
| Click2CallDeleteAgent | Remove the link |
| Click2CallGetAgents | Links of the brand |
| Click2CallAddDialRule | Add a dial rule |
| Click2CallUpdateDialRule | Update a dial rule |
| Click2CallDeleteDialRule | Delete a dial rule |
| Click2CallGetDialRules | Dial rules |
Blacklist and calling windows¶
| Command | Description |
|---|---|
| Click2CallAddBlacklistPhone | Blacklist a number |
| Click2CallImportBlacklistPhones | Bulk import numbers |
| Click2CallDeleteBlacklistPhone | Remove a number |
| Click2CallCheckBlacklistPhone | Check one number |
| Click2CallGetBlacklist | Blacklist entries |
| Click2CallAddCallWindow | Add a calling window |
| Click2CallUpdateCallWindow | Update a calling window |
| Click2CallDeleteCallWindow | Delete a calling window |
| Click2CallCheckCallWindow | Whether a number can be called now |
| Click2CallGetCallWindows | Calling windows |
Webhooks and service¶
| Command | Description |
|---|---|
| Click2CallAddWebhook | Create a provider callback URL |
| Click2CallUpdateWebhook | Update a webhook |
| Click2CallDeleteWebhook | Delete a webhook |
| Click2CallGetWebhooks | Webhooks of the brand |
| Click2CallGetWebhookEvents | Raw provider events |
| Click2CallHandleWebhook | Public provider endpoint (HTTP only in practice) |
| Click2CallPing | Liveness probe with a problem list |
| Click2CallHealth | Full module state |
Events¶
Call progress is delivered as events on the same connection, so a dialer does not have to
poll Click2CallGetCalls:
| Event | When |
|---|---|
click2call.call.initiated |
Call record created |
click2call.call.started |
Status became ANSWERED |
click2call.call.ended |
Call reached a final status |
platform.emitter.on('click2call.call.ended', e => {
console.log(e.data.callId, e.data.status, e.data.closedBy);
});
A call that never gets a final status from the provider is closed by the module as
UNRESOLVED with closedBy: "TIMEOUT" — the event always arrives, so a waiting
integration cannot hang forever.
Monitoring the module¶
Click2CallPing is the probe to call from a monitor: it answers ok plus a problems
list and costs one SELECT 1. A process that answers on the bus can still have lost its
database or its status-polling cron, and in that state calls would silently stay in
INITIATED — an empty problems list is what actually means healthy.