NUACOM API

Numbers & call routing

IVR

An IVR (auto-attendant) menu plays a greeting and routes the caller by the key they press, with separate behaviour for open hours, closed hours and the case where no key is pressed. In V2 this group is a single operation, PUT /v2/ivr/{id}/menu, which replaces the whole configuration of IVR {id}. Listing, creating and deleting IVRs is still done through V1 (GET /v1/ivr_menu, POST /v1/ivr_menu_new, DELETE /v1/ivr_menu/{id}), and an IVR is attached to a number in the portal under Numbers & Inbound Call Routing.

Workflow (what the portal does)

  1. GET /v1/ivr_menu returns every IVR with its name and a data object in exactly the shape the PUT expects. Edit that object rather than building one from scratch.
  2. Collect the identifiers your actions will point at:
  3. Build data:
    • options_msg_enabled: whether digits 0–9 are offered at all.
    • initial.ring_duration (0–30 seconds) and initial.message (an announcement slot): what happens before the menu.
    • open.message, open.pause (seconds to wait for a key: 0.1, 0.5, 1…20, 25 or 30), open.actions (exactly ten entries, digits 0–9) and open.fall_through (no key pressed).
    • close.actions for out-of-hours calls and, when its first action is "play message" (1), close.on_event_actions for a key pressed during that message.
    • Every action is {"action_1": {"id", "value"}, "action_2": {"id", "value"}}. value is always a string of at most 50 characters: an extension number, a queue number, an announcement slot, an IVR id, a phone number, comma-separated tag ids or a template id.
  4. PUT /v2/ivr/{id}/menu with name and data. 204 means saved, and the change is live for the next call: there is no provisioning step.
  5. Opening hours and holidays live outside this group and take menu_id = the IVR id: opening hours through V1 (PATCH /v1/opening_hours), public holidays with PATCH /v2/ivr/public_holiday_settings and custom holidays with PATCH /v2/ivr/custom_holiday_settings.

Actions

  • First action (action_1.id): 0 hang up, 1 play message, 2 dial extension, 3 join queue, 4 play prompt then dial the entered number, 6 voicemail, 7 repeat the options, 8 forward to a number, 9 go to another IVR, 13 add a call tag, 14 send a message.
  • Second action (action_2.id): 0 none, 1 dial extension, 2 join queue, 4 dial the entered number, 5 fall through, 6 voicemail, 8 forward, 9 go to another IVR, 14 send a message.
  • Chaining: after 1, 3 or 13 any second action is allowed; after 4 only 4 or 14; after everything else action_2.id must be 0. The fall-through slot has no second action 5; the closed slot has no first action 7.

Call routing

flowchart TD
    call["Incoming call"] --> initial["initial.ring_duration + initial.message"]
    initial --> hours{"Open hours?"}
    hours -- "open" --> menu["open.message, open.pause"]
    menu -- "digit 0-9 pressed" --> actions["open.actions[digit]: action_1 (+ chained action_2)"]
    menu -- "no key pressed" --> fall["open.fall_through"]
    hours -- "closed or holiday" --> close["close.actions"]
    close -- "action_1.id 1 (play message)" --> event["close.on_event_actions on keypress"]
    actions --> terminal["Terminal action: hang up, dial extension/queue, voicemail, forward, another IVR, add tag, send message"]
    fall --> terminal
    close --> terminal
    event --> terminal

Roles and access

  • Account admin only (403 otherwise).

Pitfalls

  • Full replacement: leave out name and the IVR is renamed to an empty string; a digit whose two actions are both 0 is removed; with options_msg_enabled: false the digits 0–9 are left as they were.
  • Validation checks every id against the allowed list but not the chaining rules: an unchainable pair such as 4 followed by 0 fails with 500, not 422.
  • References are not checked to exist. A wrong slot, extension, queue number or template id only shows up when a caller reaches it.
  • open.actions must be a list of exactly ten entries for digits 0–9. An object keyed 1–10 passes the size check and then fails.
  • {id} accepts 1–127 and creates the configuration row when it is missing, but IVRs themselves are only created through V1 (ids 1–31). Use ids you got from the list.
  • initial.message and open.message are integers 10–99; an empty string is treated as "no message".