How can we help? 👋

Mitel - MiCC-E: Interaction Parking Workflow Setup

ℹ️

This guide covers the shared MiCC-E infrastructure required by both the Interaction Parking for Voice AI Handoff and Interaction Parking for Voice Assist guides. Complete this guide before proceeding to either of those.

⚠️

This guide assumes you are confident working in the Open Access Server (OAS), the MX-ONE number plan, and Mitel Configuration Manager. Treat the steps as guidance and adapt them to your own environment. Talkative provides limited support for MiCC-E configuration — as the Mitel platform experts, partners are expected to lead this work.

ℹ️

Early version. This is an early release of the MiCC-E interaction parking guide and may be subject to revision as the integration matures.

Introduction

Interaction Parking is Talkative's preferred method for passing metadata — interaction context, console URLs, destination routing — when handing a call from the Voice AI system to MiCC-E. It replaces the older Mitel Transfer Tool approach.

Parking spaces are allocated and managed within Talkative. When a call is transferred, a free slot is claimed, interaction metadata is stored against it, and the slot identifier is used to retrieve that data and route the call correctly.

On MiCC-E the handoff is built entirely from standard platform components — a directory-number series, an OAS Basic Virtual Device (BVD), and a MiCC-E Service Group for routing to the agent. There is no separate Talkative API package for Mitel Professional Services to install. When the bot transfers a call it SIP Refers to one of the BVD's directory numbers; the OAS CTI Server sees the call, MiCC-E retrieves the stored interaction data from Talkative, and the call is delivered to an agent with the interaction context surfaced on screen.

Setup overview:

  1. Identify (or create) the number series for your parking-slot numbers
  1. Create a Basic Virtual Device (BVD) in the OAS for your parking range
  1. Create a Parking Lot in Talkative
  1. Generate an API key in Talkative
  1. Build the parking script
  1. Create the Service Access that runs the script
  1. Route parked calls to an agent via a MiCC-E Service Group

1. Identify a number series for your parking slots

Every parking space is a CTI group, and a CTI group number must be a free directory number that sits inside a defined number series. So the first step is to decide which numbers your parking slots will use, and make sure they fall inside a Directory numbers series.

You have two options:

  • Use an existing series — if you already have a Directory numbers series with free numbers (for example a 50000-50099 range), simply use a free block within it. No new series is required.
  • Create a dedicated series — if you would prefer a dedicated block, add a new number series for it.

This guide uses a dedicated block of 50400-50409 (ten parking spaces) as the worked example.

Size the range for your expected concurrency — you need one parking space for every handoff in progress at the same time. Slots free almost immediately (each is held only for the couple of seconds it takes to retrieve the metadata), so the number required is usually small, but leave some headroom. The series can be expanded later if you find you need more spaces.

To view or create a number series, in Service Node Manager go to Number Analysis → Number Plan → Number Series. The list shows each series and its Number Type (for example Directory numbers or External destination). To add one, click Add, set Number Series Type = Directory numbers, and enter your range (e.g. 50400-50409).

💡

Keep your parking-slot numbers the same digit length as your existing directory numbers to avoid number-analysis conflicts, and choose a contiguous block — it maps cleanly onto the Talkative parking lot slots later.

Adding a new number series for our parking slot range
Adding a new number series for our parking slot range

2. Create a Basic Virtual Device (BVD) for your parking spaces

Your parking spaces are defined as a Basic Virtual Device (BVD) in the Open Access Server. A BVD maps a range of directory numbers that the OAS CTI Server monitors on behalf of MiCC-E; when the Talkative bot SIP Refers a call to one of those numbers, OAS/MiCC-E sees it and handles the routing.

Because a BVD spans a Begin–End range, a single BVD covers your whole pool of parking slots — you do not create one device per number.

In the OAS Maintenance Tool, go to Configuration → Virtual Devices → Basic Virtual Devices and add a new device:

Field
Value (example)
Notes
Name
VaiParking
A label for the device
Domain
MXONE1
Your MX-ONE / CTI domain
CTI Server
MXONE1CCS
The CTI Server that monitors the device
Begin
50400
First parking-slot number
End
50409
Last parking-slot number — the Begin→End span is your parking capacity
💡

The Begin–End range is where you size parking capacity — one number per concurrent handoff. To add more spaces later, simply widen the End (as long as the numbers are free within your Directory numbers series from Step 1).

Notion image

3. Create a Parking Lot in Talkative

Navigate to Settings → Parking Lots

Notion image

Click Create Parking Lot.

Field
Description
Label
Internal identifier for this parking lot
Prefix (optional)
Prepended to each slot number to form the full number dialled. Leave blank unless your dial plan needs a full E.164 number.
Starting Key
The key the parking attendant iterates from when allocating slots
Number of Slots
Number of parking spaces — should match the size of your BVD range from Step 2. A slot is only occupied for a couple of seconds (just long enough for the Refer to fire and the interaction data to be retrieved), so you need fewer than you might expect.
Timeout (minutes)
Auto-vacates a slot after this time — handles calls abandoned before the transfer or retrieval fires. 5 minutes is the default; 1 minute is often optimal, and can be tuned if a high abandonment rate is leaving slots stuck.
💡

Parking spaces do not need to be per-queue — the destination is passed as metadata and resolved dynamically, so a single pool of parking spaces can serve multiple queues.

Notion image
📝

The Execute Workflow Setup section on this page (shown above) gives you the exact API URLs the script needs — a sample-data example URL and the live {dnis} URL — with your region and parking-lot ID already filled in. Copy these for Step 5; you no longer need to read the lot ID from the page URL.

4. Generate an API Key in Talkative

Navigate to Settings → API Tokens and create a new token. This key is used by the parking script (Step 5) to retrieve the interaction metadata from Talkative.

Notion image
⚠️

Tokens are tied to the user that creates them and are long-lived (10 years). Create the token under a shared group account rather than an individual user account — deleting the user also deletes the token, which will break the integration. The creating user must have account holder permissions.

5. Build the parking script

The parking script is a Script Manager script (built in Script Designer) whose VBScriptExecute block calls the Talkative parking-lot API, reads the response, and assigns each field to an IVR Data variable (destination, console URL, history URL). Those IVR Data fields are what surface to the agent. The script reads the arriving DNIS dynamically, so one script covers the whole BVD range.

Script variables

The script reads and writes a set of Script variables — created on the Script Variables tab, all of type String. Create these before adding the VB Script node:

Variable
Purpose
DNIS
The parked slot number the call arrived on — populated by the Assign node (@DNIS = @@MediaLib.DNIS) and read by the script
TransferDest
The transfer destination returned by the API (destination field)
ConsoleUrl
The live console URL returned by the API (url field)
HistoryUrl
The interaction-log URL returned by the API (historyUrl field)

The script references each as @<name> (for example @DNIS, @TransferDest) via FlowContext.GetVariable / FlowContext.SetVariable.

Notion image

The Script Designer flow

Build the script in Script Designer. First, change the Section dropdown from Startup to Event-Driven — the script must run on a call event, not at system startup.

Then add the following nodes in sequence:

  • Call Delivered (OnCallDelivered) — the entry event; fires when a call is delivered to the parking BVD.
  • Assign — captures the arriving DNIS into a script variable. On the node's Settings tab, set Variable Name @DNIS = Value or Expression Assigned @@MediaLib.DNIS (the DNIS the call was delivered on). The VB Script reads this variable.
Notion image
  • VB Script — labelled Parking Lot Lookup. The VBScriptExecute block that takes the DNIS, makes the Talkative parking-lot API request (below), reads the JSON response, and assigns each field to an IVR Data variable (destination, console URL, history URL).
  • Service Group — routes the call into a MiCC-E Service Group that delivers it to an agent, passing the interaction context along as Agent Data. On the node's Settings tab, choose your Service Group (e.g. "Default Users") and set the Agent Data fields so the agent receives the URLs — Data Description 1 "Console URL" = @ConsoleUrl, and Data Description 2 "History URL" = @HistoryUrl. (See Step 7 for the Service Group itself.)
Notion image
  • Clear Call (ClearCall) — clears the parking-side call leg once the call has been routed.
  • End — ends the script.
Notion image

The API request the script makes

You do not need to construct the URL by hand — the parking lot's Execute Workflow Setup section (on the Edit Parking Lot page) shows the exact URLs to use, with your region and parking-lot ID already filled in:

URL
Use
Example slot URL
Ends in /parking-lot-slot/example and always returns sample data — use it to build and test your script without needing a live parked call.
Live slot URL
Ends in /parking-lot-slot/{dnis} — the real request. Your script replaces {dnis} with the parked slot key (the BVD number the call arrived on).

Example (a lot with ID 39 in the eu region):

Testing: https://eu.engage.app/api/core/v1/parking-lots/39/parking-lot-slot/example
Live:    https://eu.engage.app/api/core/v1/parking-lots/39/parking-lot-slot/{dnis}

All URLs require your Core API token sent as an Authorization: Bearer <token> header (the token from Step 4). Retrieving a live slot also clears it.

Customise the script for your environment: paste the Live slot URL from your own parking lot (region and lot ID are already baked in), have the script substitute the arriving DNIS, and set your API token in the Bearer header. Then confirm the response-field → IVR Data variable mapping matches your Service Group / screen-pop setup.

💡

Build and test the script against the example slot URL first (it always returns sample data), then switch to the live {dnis} URL once the parsing and IVR Data mapping work.

The VB Script code (Parking Lot Lookup)

This is the VBScriptExecute block used in the VB Script node. It reads @DNIS, calls the parking-lot API, parses the JSON response, and writes @TransferDest, @ConsoleUrl and @HistoryUrl. Before compiling, edit two things for your environment: the API URL (region + parking-lot ID — use the live URL from Step 3) and the Authorization: Bearer token (replace <YOUR_CORE_API_TOKEN> with the token from Step 4).

Imports System
Imports System.Net
Imports System.IO
Imports SMScriptBox

<Serializable()> Public Class Script
    Sub New()
    End Sub

    Shared Function ExtractJsonValue(json As String, key As String) As String
        Dim searchKey As String = """" & key & """:"
        Dim startIndex As Integer = json.IndexOf(searchKey)
        If startIndex = -1 Then
            Return ""
        End If
        startIndex += searchKey.Length

        ' Skip whitespace
        While startIndex < json.Length AndAlso json(startIndex) = " "c
            startIndex += 1
        End While

        If startIndex >= json.Length Then
            Return ""
        End If

        If json(startIndex) = """"c Then
            ' String value
            Dim valueStart As Integer = startIndex + 1
            Dim valueEnd As Integer = json.IndexOf(""""c, valueStart)
            While valueEnd > 0 AndAlso json(valueEnd - 1) = "\"c
                valueEnd = json.IndexOf(""""c, valueEnd + 1)
            End While
            If valueEnd = -1 Then
                Return ""
            End If
            Return json.Substring(valueStart, valueEnd - valueStart).Replace("\/", "/")
        Else
            ' Numeric / bare value
            Dim valueEnd As Integer = startIndex
            While valueEnd < json.Length AndAlso json(valueEnd) <> ","c AndAlso json(valueEnd) <> "}"c
                valueEnd += 1
            End While
            Return json.Substring(startIndex, valueEnd - startIndex).Trim()
        End If
    End Function

    Shared Sub Main()
        Try
            Dim dnis As String = FlowContext.GetVariable("@DNIS")
            Dim url As String = "https://eu.engage.app/api/core/v1/parking-lots/39/parking-lot-slot/" & dnis

            ServicePointManager.SecurityProtocol = CType(3072, SecurityProtocolType)

            Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
            request.Method = "GET"
            request.Headers.Add("Authorization", "Bearer <YOUR_CORE_API_TOKEN>")

            Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
            Dim reader As New StreamReader(response.GetResponseStream())
            Dim responseText As String = reader.ReadToEnd()
            reader.Close()

            FlowContext.Print("Response=" & responseText)

            ' Extract fields from the JSON response
            Dim destination As String = ExtractJsonValue(responseText, "destination")
            Dim consoleUrl As String = ExtractJsonValue(responseText, "url")
            Dim historyUrl As String = ExtractJsonValue(responseText, "historyUrl")

            FlowContext.SetVariable("@TransferDest", destination)
            FlowContext.SetVariable("@ConsoleUrl", consoleUrl)
            FlowContext.SetVariable("@HistoryUrl", historyUrl)

        Catch ex As Exception
            FlowContext.Print("VB Script error: " & ex.Message)
        End Try
    End Sub
End Class

Once built, compile the script so it can be selected on a Service Access (Step 6). An editable copy of this script is also provided as a downloadable file.

💡

Whilst this script will satisfy the requirements - you may build your own script or adjust this to suit your needs it’s not an imperative to utilise this exact script.

6. Create the Service Access that runs the script

The Service Access binds your BVD to the compiled script and monitors the parked call — when a call reaches a BVD number, the Service Access fires the script. Create a Service Access with the following (matching the working reference):

Field
Value (example)
Notes
Name
Park 50400
A label for the Service Access
Device name
your parking BVD
The BVD created in Step 2 (e.g. the VaiParking / 50400–50409 device)
Script Manager
Yes
Enables the script
Script Name
your compiled script (e.g. InteractionParkingScript)
The parking script built in Step 5
Priority
99
As per the working reference
Auto Start
Enabled
Starts the Service Access with the system

To create the Service Access, open Configuration Manager and go to the Service Accesses section. Right-click it and choose New, then click Next — you will see a dialog asking you to choose your script (select the script you compiled in Step 5):

Notion image

Click Next, then Finish. When prompted to review the properties, select Yes and enter the values from the table above (Device name = your BVD, Script Manager = Yes, plus Priority and Auto Start):

Notion image

Finally, activate the Service Access: right-click it and choose Activate.

Notion image
⚠️

If you make any changes to your script, you should click “reactivate” to ensure the changes are loaded correctly.

7. Route parked calls to an agent (MiCC-E Service Group)

The Service Group is the MiCC-E group that receives the parked call from the script's Service Group node (Step 5) and delivers it to an agent. Use a suitable existing Service Group if you have one, or create a new one in Configuration Manager.

Routing to agents (skills)

This Service Group routes on skills, not directly-assigned agents. On the Service Group's Skills tab, assign the skill your agents hold — in the reference lab this is a Voice skill (VoiceSkill, First Choice, Level 1). Any agent with that skill will receive calls from the group.

Notion image

Surfacing the interaction to the agent (screen pop)

The screen pop is configured on the Service Group's Agent Action tab. Recall that the Service Group node (Step 5) passed the URLs as IVR Data — field 1 = Console URL, field 2 = History URL. On the Agent Action tab:

  • Set Application to %I1% — the IVR Data field 1, i.e. the Console URL. (IVR Data fields are referenced as %IX%, where X is the field index 1–10.)
  • Tick Launch URL in Agent Tab — this opens the Console URL as a tab inside the agent's console when the session is presented, giving them the live interaction in context.
Notion image
⚠️

Routing behaviour & limitations: As built, every parked call is delivered to a single fixed Service Group ("Default Users" here), so the destination Talkative returns (captured as @TransferDest) isn't used for routing. If you need different destinations to reach different Service Groups, you can add conditional logic to the script that branches on @TransferDest (e.g. 1001 → Service Group 1, 1002 → Service Group 2). Note this is Service-Group-level routing only: unlike MCX — where the API's destination extension is dialled directly — MiCC-E routes through a Service Group (so the interaction URL can be attached), and transferring to an arbitrary returned extension is not currently confirmed possible.

Did this answer your question?
😞
😐
🤩