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.
| URL | https://api.telecomx.dk/pbx/calltest/session | ||
|---|---|---|---|
| Method | POST | ||
| Access level | None - unauthenticated | ||
| Body | none | No request body is read. | |
| 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. |
{ 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' }
| 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> |
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.