Skip to main content

Debt Collection System Integration

This guide describes how an external debt collection system can integrate with ITX to support outbound calling campaigns, case popup for inbound and outbound calls, call status and AI summary syncing, and a self-service Interactive voice response (IVR) and SMS flow for debtors.

Before using the integration, a few things need to be set up in ITX — see Prerequisites. The integration itself consists of four building blocks:

  1. Calltasks — importing and ending call tasks
  2. Popup in debt collection system — showing the debtor's case when a call is placed or received
  3. Call status and AI summary sync — keeping call outcomes and AI-generated summaries in sync with your case
  4. Self service — letting debtors call in, identify themselves, and receive an automated status update on their debt collection case. They can settle the outstanding claim without speaking to an agent—either by receiving an SMS with a payment link, KID number, bank account number and amount, or by paying directly with Vipps. If further assistance is needed, smart routing automatically connects the caller to the right team based on the case information.

Prerequisites

A few things need to be set up in ITX before call tasks can be imported.

External systems

One or several external systems need to be set up in ITX via Call Lists > External systems. For example, you can set up one system for private debtors and another for company debtors. This is also where the popup URL for opening a case in your system is configured.

External system setup in ITX, showing system code and popup URL fields

Campaigns

One or several campaigns need to be set up in ITX via the API or in the GUI via Sales > Campaigns:

Campaign setup in ITX, showing call code and call attempt settings

API endpoint to create campaigns:

POST /dialer/callcode

API endpoint to retrieve campaigns:

GET /dialer/callcode

Calltasks

Calltasks drive the outbound dialing campaigns run by ITX on behalf of the debt collection system.

Importing calltasks

Calltasks are imported using:

POST /itxdialer/calltaskimport

A few things to keep in mind for a debt collection setup:

  • systemCode differentiates between debtor types, and must match the system code of one of the external systems set up in ITX. ITX can have one system configured for private debtors and a separate system configured for company debtors.
  • callCode identifies the campaign the call tasks should be added to. Different campaigns are configured in ITX, and this parameter routes imported call tasks to the correct one.
  • Each call task object in callTasks[*] needs to include systemLookupCode, which is the debtor's case number, and extCustId, a unique ID for the debtor in the debt collection system, in addition to the debtor's name and phone number.

Full documentation for this endpoint, including the request/response schema and error codes, is available in the Calltasks guide.

Ending calltasks

Call tasks are ended using:

PUT /v1/calltasks/{itcaId}/end

Who ends a calltask, and when:

ScenarioEnded by
Debtor has paid and the call task in ITX is still activeDebt collection system (explicit call to end the calltask)
Debtor has answered the callITX (automatically)
maxCallAttempts has been reachedITX (automatically)

In other words, the debt collection system only needs to actively end a calltask when it detects that the debt has been paid and the calltask in ITX is still active — ITX handles the other end conditions automatically.

Retrieving the itcaId

To end a calltask, you first need its itcaId. Retrieve the calltask object using:

POST /dialer/calltaskget

Search by the case number that was originally imported into ITX (the systemLookupCode) for active (unfinished) call tasks:

{
"systemLookupCodes": ["{case number imported to ITX}"],
"finishedList": [false]
}

The response contains the itcaId, which is then used in the PUT /v1/calltasks/{itcaId}/end call.

info

The response is a list, so a search on systemLookupCode can match more than one call task — for example if the same case has been imported into more than one campaign. If that happens, add another filter field (such as callCodes) to narrow the result down to a single call task if needed. See the POST /dialer/calltaskget reference at the end of this guide for the full set of available filter fields.


To show a debtor's case automatically when a related call happens, the debt collection system needs an endpoint that can handle a popup URL containing the case number, for example:

https://mysystem.com/popup?caseNumber={$CODE}

{$CODE} is replaced by ITX with the relevant case number / systemLookupCode. This URL is set on the external system configured in ITX.

info

It's also possible to have the caller's phone number as an argument. This might be handy if the caller enters the wrong case number and you want to display a popup with all the cases for that phone number.

This popup URL is triggered by ITX in the following situations:

  • An agent calls out on a calltask that was imported for this system.
  • A debtor calls in and the incoming call is matched to a calltask by phone number.
  • A debtor calls in without any calltask match, and manually enters their systemLookupCode (case number) using the keypad. (Configured in the ITX switchboard.)

Call status and AI summary sync

To keep call status and AI-generated call summaries in sync with a case in the debt collection system, do the following:

1. Subscribe to webhooks

Subscribe to the following webhook events:

  • phone-call.ended
  • phone-call-summary.creation
  • phone-call-summary.update

See the Webhooks guide for details on setting up and consuming ITX webhooks.

2. Look up the call

Use the phoneCallId from the webhook event as the value of the eactIds property when calling:

POST /itxems/calls/search

JSON payload:

{
"eactIds": ["{phoneCallId}"]
}
info

The phone-call.ended webhook fires for every call handled by ITX, not just calls related to debt collection, so check that the returned call actually belongs to your integration before processing it further. Do this by comparing externalSystem.itsyId in the response against the itsyId of one of the external systems set up for the debt collection integration — if it doesn't match, ignore the call. The case number (systemLookupCode) — whether taken from the matched call task or entered by the caller on the keypad — is also available directly on the response, in the systemLookupCode property.

3. Determine whether the call was answered

  • If startTs exists in the payload and has a timestamp value, i.e. is not null, the call was answered.

4. Determine detailed call status

How you determine the more detailed call status depends on whether the call is linked to a calltask:

  • Call is linked to a calltask (the response from POST /itxems/calls/search includes callAttempt.iccaId): Use the iccaId to search:

    POST /itxdialer/calltaskcallattempts/search

    This lets you determine whether the call went to voicemail, was dropped, or was lost.

  • Call is not linked to a calltask (i.e. the debtor is not known in ITX): Simply use whether startTs exists and has a timestamp value to determine call status.

5. Retrieve the AI summary

A phone-call-summary.creation event is sent out once the AI summary is ready, usually shortly after the call ends — but this can take longer, or fail. A phone-call-summary.update event is sent out each time the summary is updated (might be manually changed by an agent). Repeat the step 2 lookup using the phoneCallId from the event, and apply the same check described there, before processing the summary.

For details on retrieving the AI summary, see the Phone calls guide.

The phoneCallSummaryId sent in the phone call summary webhook events corresponds with the call activity's eactId.


Self service

Letting debtors call in, identify themselves, and receive an automated status update on their debt collection case. They can settle the outstanding claim without speaking to an agent—either by receiving an SMS with a payment link, KID number, bank account number and amount, or by paying directly with Vipps. If further assistance is needed, smart routing automatically connects the caller to the right team based on the case information.

1. Expose a case/payment lookup endpoint

Provide an endpoint that returns case and payment information for a given debtor case, for example:

GET https://mysystem.com/CaseInfo/{caseNumber}
info

It's also possible to have the caller's phone number as an argument as well if needed, but it's expected that the case number (systemLookupCode in ITX) is enough.

This is then configured in the ITX Switchboard, where different outcomes can be set up using JSONPath and conditional logic. Property names and values in the response are flexible and can be tailored to your system.

Example response:

{
"paymentAccount": "24800000001",
"paymentReference": "5900000000123596",
"paymentUrl": "https://paymentprovider/123",
"remainingAmount": 29370.52,
"closedDate": null,
"caseNumber": 123,
"caseCategory": "Standard",
"caseHandlerName": "John Doe"
}

2. Configure JSONPath conditions in the Switchboard

Use JSONPath expressions against the response above to branch the self-service flow:

ConditionMeaningAction
$[?(@.closedDate == null)]Case is openSend an SMS with payment information (payment URL, amount, reference, etc. can be dynamically inserted using JSONPath)
$[?(@.closedDate != null)]Case is closedPlay a voice recording informing the caller that the case is closed

Any field from the response can be referenced via JSONPath to personalize the SMS content or voice prompt.

Example switchboard configuration

Reference number (case number) entered via keypad connected to the external system:

Reference number (case number)

Advanced dynamic routing based on the case number:

 Advanced dynamic routing based on the case number

Open case options:

 Open case options

SMS with values from the case info response:

 SMS with values from the case info response


Appendix: POST /dialer/calltaskget reference

This endpoint predates the OpenAPI/Swagger documentation and isn't listed there, so it's documented here for reference.

Request

POST /dialer/calltaskget

The request body is a single JSON object combining search filter fields with pagination and sorting options. All fields are optional — combine whichever ones you need to narrow the search.

Filter fields (most relevant for an external integration):

FieldTypeDescription
systemLookupCodesstring[]Case numbers imported into ITX. Used to look up the call task(s) for a specific case.
extCustIdsstring[]Debtor IDs from the debt collection system.
itcaIdsnumber[]ITX call task IDs, if already known.
callCodesobject[]Filter by one or more campaigns (call codes).
statusListnumber[]Filter by internal call task status code(s).
answeredListboolean[]Filter by whether the call task has been answered.
finishedListboolean[]Filter by whether the call task is finished.
callNumbersstring[]Filter by the phone number(s) dialed.
hasCallBackDatebooleanFilter by whether a callback date is set on the call task.

The full filter object supports additional ITX-internal fields (corporation, assigned user, date ranges, activity feedback types, and so on), but these require internal ITX identifiers and aren't typically relevant for an external debt collection system.

Pagination and sorting fields:

FieldTypeDefaultDescription
limitnumber50Maximum rows to return per page. Values ≤ 0 are treated as 1000; values above 50000 are capped at 50000.
pageNumbernumber1Page of results to return.
sortstringColumn to sort the results by.
detailbooleanfalseReturn full call task details rather than a summary.

Response

{
"callTasks": [ /* array of call task objects, including itcaId */ ],
"foundRows": 1,
"firstRow": 1,
"lastRow": 1,
"pageCount": 1
}
  • callTasks — the matching call task objects for the current page. Each includes the itcaId needed to end a calltask.
  • foundRows — total number of matching call tasks across all pages.
  • firstRow / lastRow — the row range returned on this page.
  • pageCount — total number of pages available at the given limit.