---
updatedAt: 2026-08-21T11:43:51.000Z
agentTools:
  projectIndex: https://docs.nextpertise.nl/llms.txt
---

# Running a diagnostic action on a connection

```shell Shell
import time

import requests

# Configure the Nextpertise API
NEXTPERTISE_API = "https://api.nextpertise.nl"
NEXTPERTISE_TOKEN = "xxx"

# Pick the connection you want to diagnose. Any connection UUID will do;
# here we simply take the first connection of the organization.
response = requests.get(
    f"{NEXTPERTISE_API}/mixed-broadband/connections/",
    headers={"Authorization": f"Bearer {NEXTPERTISE_TOKEN}"},
    params={"page_size": 10, "page": 1},
)
response.raise_for_status()
connection_list = response.json()["results"]
if not connection_list:
    print("There are no connections to diagnose!")
    exit(0)
connection_uuid = connection_list[0]["uuid"]

# Ask the API which diagnostic actions are available for this connection
response = requests.get(
    f"{NEXTPERTISE_API}/mixed-broadband/connections/{connection_uuid}/diagnose/actions/",
    headers={"Authorization": f"Bearer {NEXTPERTISE_TOKEN}"},
)
response.raise_for_status()
actions = response.json()["actions"]

# Analyses only inspect the connection, while actions execute something. List both
# groups separately, but keep a single numbering so the user makes one choice.
analyses = [action for action in actions if action["type"] == "analysis"]
operations = [item for item in actions if item["type"] == "action"]

menu = []
for group_title, group in (
    ("Analyses (only inspect the connection)", analyses),
    ("Actions (change the connection)", operations),
):
    if not group:
        continue
    print(group_title)
    for item in group:
        recommended = " (recommended)" if item["recommended"] else ""
        print(f"  {len(menu)}. {item['i18n_name']}{recommended}")
        print(f"     {item['i18n_description']}")
        menu.append(item)
selected_action = menu[int(input("Which number would you like to execute? "))]
    
# Queue the selected action. Some actions, such as ppp_disconnect, carry parameters
# that tell the API which circuit (EVC) to act on. Those parameters are returned with
# the action itself, so hand them back unchanged.
response = requests.post(
    f"{NEXTPERTISE_API}/mixed-broadband/connections/{connection_uuid}/diagnose/run-actions/",
    headers={"Authorization": f"Bearer {NEXTPERTISE_TOKEN}"},
    json={
        "actions": [
            {
                "action": selected_action["technical_name"],
                "params": selected_action["params"] or {},
            }
        ]
    },
)
response.raise_for_status()
runs = response.json()["runs"]
run_uuid = runs[0]["uuid"]
print(f"Queued diagnostic run {run_uuid}.")

# Poll the run once per second until it is no longer new or pending
for _ in range(120):
    response = requests.get(
        f"{NEXTPERTISE_API}/mixed-broadband/connections/{connection_uuid}/diagnose/runs/{run_uuid}/",
        headers={"Authorization": f"Bearer {NEXTPERTISE_TOKEN}"},
    )
    response.raise_for_status()
    run = response.json()
    if run["status"] in ("complete", "error"):
        break
    time.sleep(1)
else:
    raise TimeoutError(f"Diagnostic run {run_uuid} did not finish in time.")

if run["status"] == "error":
    print("The diagnostic could not be executed.")
    exit(1)

# Render the result of the completed run
results = run["results"]
print(f"{run['type']}: {results['status']} - {results['i18n_description']}")

# ont_check: success - De ONT is bereikbaar.
for section in results["summary"]:
    if section["i18n_subtitle"]:
        print(section["i18n_subtitle"])
    for item in section["items"]:
        if item["type"] == "diagnostic_plain_text":
            print(f"  {item['i18n_name']}: {item['plain_text']}")
        elif item["type"] == "diagnostic_up_and_down":
            print(f"  {item['i18n_name']}: up {item['i18n_up']}, down {item['i18n_down']}")
        elif item["type"] == "diagnostic_utc_time":
            print(f"  {item['i18n_name']}: {item['utc_datetime']}")
        elif item["type"] == "diagnostic_map_location":
            print(f"  {item['i18n_name']}: {item['latitude']}, {item['longitude']}")

```

```json Response Example
{"success":true}
```

# Configure the API

<!-- shell@5-7 -->

Set the Nextpertise API location and your API token. More information about obtaining a new API token can be found on the [Authentication](https://docs.nextpertise.nl/reference/authentication) page.

# Select the connection to diagnose

<!-- shell@9-21 -->

Diagnostics always run against a single connection, so we first need a connection UUID. In this example we take the first connection returned by the [Get Connections](https://docs.nextpertise.nl/reference/get-connections) endpoint; in practice this is the connection your user selected.

# Get the available diagnostic actions

<!-- shell@23-29 -->

Which diagnostics are available depends on the network and the state of the connection, so never hard-code them. The [Get Connection Diagnose Actions (BETA)](https://docs.nextpertise.nl/reference/get_connection_diagnose_actions) endpoint returns the actions you may run right now. Each action has a `type` (`analysis` only inspects the connection, `action` executes something), a `technical_name` to submit later on, an `i18n_name` and `i18n_description` you can show to your user, a `recommended` flag, and an optional `params` object.

The `i18n_description` is written for your user and may describe the exact target of the action, for example the EVC that a `ppp_disconnect` applies to. A connection with several EVCs therefore returns a `ppp_disconnect` entry per EVC, each with its own `params`.

# Show the actions in a menu

<!-- shell@31-49 -->

Render the returned actions as a menu using `i18n_name` and `i18n_description`, and highlight the ones marked `recommended`. Because you display exactly what the API returned, new diagnostics automatically appear in your interface.

Split the menu by `type`. An `analysis` only reads the current state of the connection and is safe to run at any time, while an `action` executes something on the connection and can be disruptive, so your user should pick it deliberately. Listing the two groups separately makes that difference obvious, while a single numbering over both groups keeps it to one choice.

# Execute the selected action

<!-- shell@51-69 -->

When the user hits execute, submit the action to the [Run Connection Diagnose Actions (BETA)](https://docs.nextpertise.nl/reference/run_connection_diagnose_actions) endpoint. Submit the `technical_name` as `action`, together with the `params` object you received for that action in the previous step. Some actions need those parameters to know what to act on: `ppp_disconnect` (kicking an EVC) carries a `circuit_uuid` that identifies the EVC. Never build that object yourself, just pass back what you received. Actions without parameters simply take an empty object.

You may submit several actions in one call. They are queued in submission order and executed sequentially, and the returned run UUIDs come back in that same order. If one of the submitted actions is invalid, the entire request is rejected and nothing is queued.

# Poll the run until it is finished

<!-- shell@71-87 -->

Diagnostics run asynchronously, so the run starts with status `new` and moves to `pending` once it is picked up. Poll the [Get Connection Diagnose Run (BETA)](https://docs.nextpertise.nl/reference/get_connection_diagnose_run) endpoint about once per second until the status is `complete` or `error`. Always bound the loop: most diagnostics finish within seconds, but a device that does not respond should not keep your application waiting forever.

# Show the result

<!-- shell@89-105 -->

A completed run contains a `results` object with its own `status` (`success`, `error` or `inconclusive`), an `i18n_description`, and a `summary` you can render directly. The summary is a list of sections, each with an optional `i18n_subtitle` and a list of items. Every item carries a `type` that tells you how to display it: `diagnostic_plain_text`, `diagnostic_up_and_down` (for example line speeds), `diagnostic_utc_time` and `diagnostic_map_location`. Use `i18n_name` as the label. If you need the unformatted device output, it is available in `results['raw']`.

Use [List Connection Diagnose Runs (BETA)](https://docs.nextpertise.nl/reference/list_connection_diagnose_runs) to show the diagnostic history of a connection.