Table of Contents

API : PBX : Call test session

Introduction

Provisions a throwaway WebRTC SIP phone and returns credentials the browser can register with immediately. The phone is created through the ordinary SIP phone factory, so validation, Redis provisioning and the change log all happen exactly as they do for a real phone. It carries no product and is never invoiced.

This endpoint is unauthenticated and takes no request body. That is deliberate: with no input there is nothing to point at another customer. Adding a body field to this endpoint would remove the property that makes it safe to expose.

The phone is deleted by Finish, or by Reap once it is older than 5 minutes.

Request

URL https://api.telecomx.dk/pbx/calltest/session
Method POST
Access level None - unauthenticated
Body none No request body is read.

Response

Json object
sessionId String Random 32 hex character token naming this session on every later request. Not the phone's id.
server String WebRTC signalling server for the cluster the phone was created on, e.g. wss://wssip.telecomx.dk.
username String SIP username, auto-generated 32-char string, never reused.
password String SIP password, auto-generated 32-char string, never reused.
realm String SIP realm to authenticate against.
testNumber String The number to dial. Informational - the extension's GOTO decides where the call actually goes.
displayName String Caller name the softphone should register with.
iceServers Array STUN servers, in the shape RTCPeerConnection expects.
expiresAt String ISO timestamp after which the reaper may delete the phone, whether or not the browser is done.

Example

{
  sessionId: '4f9c1e7b2a6d40188c3e5b9a7d21f0ac',
  server: 'wss://wssip.telecomx.dk',
  username: '48gjh4ufghfhu3hufbfjksfhjkecv',
  password: 'fuhiehi0jejicdoj2i0jchiwnpdcc',
  realm: 'telecomx.dk',
  testNumber: '8999',
  displayName: 'Call test',
  iceServers: [ { urls: [ 'stun:mgw1.telecomx.dk:3478', 'stun:mgw2.telecomx.dk:3478' ] } ],
  expiresAt: '2026-09-02T10:05:00.000Z'
}

Errors

Error code Message Description
409 conflict The platform is already running the most concurrent tests it allows (50). The client should tell the visitor the test line is busy and offer a retry - not retry in a loop.
500 call_test_disabled The configured test extension is no longer restricted to its dialplan item, so no credentials will be issued. See below.
500 internal_error <Unspecified>

call_test_disabled

Creating a phone is refused unless the configured test extension still has outbound.destinations = GOTO and an outbound.goto item. That check exists because the management UI's outbound tab does not offer GOTO among its values, so opening that extension and saving it - or including it in a bulk update - silently converts it to LOCAL and removes the only thing confining the credentials.

The refusal is logged to syslog at most once every five minutes and is deliberately excluded from the error mail, because the endpoint is unauthenticated and a single crawler would otherwise turn one misconfiguration into a mail flood. If the call test stops working, grep syslog for call_test_disabled before anything else.