Recordings and DTMF

Install DotSIP, open the web admin, connect real SIP, and decide each call from your own HTTP API.

A call does not need an agent. Your route can answer, play a WAV recording, collect keypad digits, call your own webhook, transfer to an extension, or hang up. The same route can still hand the call to an agent later in the list.

One action still works. answer, transfer, and hangup are described on Routes. A list of commands is the form you use when the caller should hear a recording or press a key.

Where the recording goes

Copy a file into data/media next to the program. On Windows that is data\media\welcome.wav beside ai-vratnik.exe. The name in the plan is only the file name, welcome.wav. There is no upload button in the admin. The file is read when the call reaches the play step, so you do not restart DotSIP after you replace it.

The file has to be a WAV: one channel, 16-bit PCM, at 8000, 16000, or 24000 Hz, and at most 8 MB. MP3 is not played. A name with a folder, a backslash, or .. is refused. A file that cannot be played is skipped and the next command still runs.

You can also point url at an HTTP or HTTPS address that returns that same WAV. The download limit is the same 8 MB. Use one of media or url, not a path on the caller’s phone.

Command list

Reply with HTTP 200 and JSON. Up to 32 commands. Each step uses do.

{
  "format": "dotsip.route-result",
  "format_version": 2,
  "commands": [
    { "do": "answer" },
    { "do": "play", "media": "welcome.wav" },
    { "do": "gather", "max_digits": 1, "timeout_ms": 15000, "digits": {
      "1": [ { "do": "transfer", "phone": "200" } ],
      "timeout": [ { "do": "hangup" } ]
    }}
  ]
}
doWhat you setWhat the caller gets
answerThe call is picked up.
playmedia or url. barge_in false is the default.The WAV plays to the end, then the next command starts. barge_in true, or collect true, takes DTMF during playback and stops the recording.
waitms, from 1 to 60000DotSIP pauses before the next command. Use this when the caller should hear the whole recording before the next step.
gatherdigits and/or callback_urlKeypad digits are collected.
hookurl, optional event, optional waitDotSIP POSTs to your server.
transferphoneThe extension created under SIP phones.
hangupAn answered call is hung up.
rejectoptional reasonA call that is still ringing is refused.
agentagent, optional rights, user, promptThe live voice agent takes the call. The agent must already exist.

With barge_in left false, the caller hears the whole recording before the next command. Set barge_in to true, or collect to true, when a key pressed during the recording should stop it and be collected. The file is mono 16-bit PCM WAV at 8000, 16000, or 24000 Hz. MP3 is not played.

gather uses max_digits from 1 to 16, default 1, and timeout_ms from 200 to 60000, default 8000. finish_on is one key, default #.

A digit that is not in the map, and a timeout with no timeout entry and no callback, leaves the call up. Put a timeout list if the call should end.

Digits without a webhook

This is the synchronous menu. The plan already says what each key does. DotSIP does not call you again.

{
  "do": "gather",
  "max_digits": 1,
  "timeout_ms": 15000,
  "digits": {
    "1": [ { "do": "transfer", "phone": "200" } ],
    "2": [ { "do": "play", "media": "hours.wav" }, { "do": "hangup" } ],
    "timeout": [ { "do": "hangup" } ]
  }
}

Keys are 0–9, *, and #, or the word timeout. The value is a list of commands. A full switchboard is in Example: switchboard.

Digits with a webhook that waits

Leave the digit out of the map and set callback_url. wait defaults to true. DotSIP POSTs, waits up to 5 seconds, and runs the JSON you return as the next plan. Your reply can be a command list or a single action. HTTP 400 or higher is a failed call to you, and that reply is not run.

{
  "format": "dotsip.dtmf",
  "format_version": 1,
  "call_id": "call-id-from-dotsip",
  "digits": "1",
  "timeout": false,
  "caller": { "number": "+421900000000" }
}

timeout is true when the gather timer won and digits is whatever was pressed before that, often an empty string. A matching entry in digits wins over the callback: that key is not posted.

{
  "commands": [
    { "do": "transfer", "phone": "200" }
  ]
}

Digits with a webhook that does not wait

Set wait to false when you only want a notification. DotSIP still POSTs dotsip.dtmf. It does not read your reply and it does not transfer or hang up because of that reply. The call continues with nothing else unless you already queued another command. Use the digit map when the key must change the call. Use wait: false when your server should store the key while a local digit map, or a later command, handles the phone.

{
  "do": "gather",
  "max_digits": 4,
  "finish_on": "#",
  "timeout_ms": 20000,
  "callback_url": "https://pbx.example/dtmf-log",
  "wait": false,
  "digits": {
    "timeout": [ { "do": "hangup" } ]
  }
}

Four digits, or #, end the gather. The POST goes out and the call is not steered by the HTTP body.

Webhooks that are not digits

hook POSTs when the command is reached, for example when the call is answered or before a transfer. wait defaults to true: DotSIP waits and runs your reply. wait: false notifies and continues with the next command in the list you already sent. The event name is the event field, or hook when you omit it.

{
  "format": "dotsip.hook",
  "format_version": 1,
  "call_id": "call-id-from-dotsip",
  "event": "answered",
  "caller": { "number": "+421900000000" }
}
{
  "commands": [
    { "do": "answer" },
    { "do": "hook", "url": "https://pbx.example/call-opened", "event": "answered", "wait": false },
    { "do": "play", "media": "welcome.wav" }
  ]
}

Both posts use JSON. There is no API key on the route request. HTTPS checks the certificate. A waited HTTP 200 that is a plan is executed. Anything else is ignored and the batch continues.

On transfer, wait false still posts dotsip.line and does not run a returned plan, and the refer still proceeds. wait true runs a returned plan and does not send the refer. timeout_ms defaults to 20000 and may be 200 to 120000. After a failed refer, status is no_answer or failed, DotSIP posts dotsip.transfer-result, then runs on_fail unless that callback returned a plan.

dial needs phones, group, phone, or number. At most 8 extensions. number is an outside number and, when set, the other targets are not used. mode sequence is the default. parallel rings together and keeps the first answer. After a connected internal dial, callback_url receives dotsip.dial with the same shape as dotsip.line and status answered.

queue needs group, phones, or phone. timeout_ms defaults to 120000 and may be 1000 to 300000. A WAV in media or url loops while it waits. The first idle extension is transferred. On timeout, on_fail runs.

The command record captures one slice of caller audio into data/recordings/<call_id>.wav and can post dotsip.recording. That is not the whole-call recording. Whole-call recording is Call recording under Settings, and an optional recording object on the route response. See Calls, debug, access.