NinjaOne Device Glance

An optional, strictly read-only integration with NinjaOne RMM: when a
client starts a chat, AVA tries to identify their machine and shows the
engineer a "device at a glance" card right in the chat's context panel — no
tab-switching to the RMM console mid-conversation.

Off by default. With the NinjaOne variables unset, the feature is
completely dormant: no Device section renders anywhere, and no NinjaOne
network calls are ever made. Engineer and client behavior is byte-identical to
a build without the feature.


What the engineer sees

A read-only card in the client-context panel of an active chat:

  • Identity header — device name, make/model, organization
  • Stat tiles — online/offline status, last boot, disk free, pending/failed
    OS patches, antivirus state, public/private IPs, OS/system info, last
    logged-on user
  • Alerts strip — recent NinjaOne alerts for the device
  • Confidence chip — how sure the match is (a device is only shown when the
    resolution pipeline has real evidence; it never guesses)
  • "Open in NinjaOne" — a deep link to the device's page in your NinjaOne
    console

Telemetry values (disk, patches, AV, alerts) reflect NinjaOne's own
last-check-in data for the device — not a live poll triggered by the chat.


The read-only guarantee

This integration is designed so that it cannot modify anything in your RMM,
as a matter of credential scope rather than convention:

  • The NinjaOne API client you create is scoped to Monitoring only — the
    credential itself is incapable of running scripts, rebooting devices, or
    triggering any action, regardless of what any application bug did.
  • AVA's NinjaOne client exposes GET requests exclusively — there is no
    code path that issues a write to NinjaOne. (The one POST under the hood is
    the OAuth2 token exchange itself, which is a POST by spec.)
  • No remote-session launch, no device actions — the "Open in NinjaOne" link is
    a console URL and requires the engineer to already be signed in to NinjaOne
    in their browser.

The only write the feature can perform anywhere is the optional
AutoTask ticket enrichment (to your own AT ticket, never to NinjaOne), and
that is gated behind its own default-off switch — see below.


How device resolution works (two independent layers)

Layer 1 — AutoTask-only baseline (no NinjaOne credentials needed). If your
AutoTask instance already syncs NinjaOne data onto Configuration Items (the
NinjaRMM-RemoteUrl / -BackgroundUrl / -Antivirus / -PrivateIpAddress /
-DeviceUID UDFs, as the standard NinjaOne↔AutoTask sync populates), AVA
matches the chat's AutoTask company + reported hostname to a Configuration
Item and shows those UDF facts plus a deep link parsed from the remote-URL UDF
— even with all NINJAONE_* variables unset.

Layer 2 — live NinjaOne API (optional). With the three credentials set,
AVA additionally queries the NinjaOne API for live device telemetry, and can
fall back to a hostname/user search when no Configuration Item matched.

Matching is identity-gated and never-guess: hints have to line up with the
chat's company before a device is shown.


Step 1 — Create the API client (NinjaOne admin)

  1. In NinjaOne: Administration → Apps → API → Client App IDs → Add.
  2. Platform: API Services (machine-to-machine).
  3. Scope: Monitoring only — do not grant management or any write
    scope. This is the least-privilege line the whole feature is built on.
  4. Grant type: Client Credentials. No redirect URI (server-to-server, not
    interactive OAuth).
  5. Copy the generated Client ID and Client Secret.

Step 2 — Set the enable variables

The feature is all-or-nothing: all three must be set together.

VariableRequired to enableEffect
NINJAONE_BASE_URLYesYour region's API base URL (table below). Trailing slash optional.
NINJAONE_CLIENT_IDYesThe Client App ID from Step 1
NINJAONE_CLIENT_SECRETYesThe Client App secret. Quote it in the env file — it is read via the same raw-file mechanism as the AutoTask secret, so $ and other special characters are safe.
NINJAONE_TIMEOUT_MSOptional (default 15000)Per-request timeout for NinjaOne API calls

Region base URLs

Use the same data-center region your NinjaOne console login URL shows:

RegionNINJAONE_BASE_URL
Americas (default/US)https://app.ninjarmm.com
Americas 2https://us2.ninjarmm.com
Canadahttps://ca.ninjarmm.com
Europehttps://eu.ninjarmm.com
Oceaniahttps://oc.ninjarmm.com

Step 3 — Systray URL hints (recommended)

AVA resolves "which machine is this?" most reliably when the client reaches
the chat page via a link carrying systray-substituted hints. NinjaOne systray
custom URL items support ${HOSTNAME} / $USERNAME / ${DOMAIN}
placeholders, substituted at click time. In your NinjaOne branding/systray
policy, point the chat link at:

https://chat.example.com/?host=${HOSTNAME}&user=$USERNAME&domain=${DOMAIN}

AVA captures these once on page load, forwards them with the chat-start
request, and stores them on the session as display and lookup hints only —
never an authorization signal
(they are client-reported, exactly like a
browser user agent). The hints are also stripped from the visible URL after
capture.

Omitting the query string entirely still works: the resolution pipeline falls
back to a user/email-based search (when the API layer is enabled) or shows a
"no managed device matched" empty state.


Step 4 — Validate

npx tsx scripts/test-ninjaone.ts [hostname]

Confirms configuration presence, exercises the real OAuth2 client-credentials
token exchange, lists organizations and a few devices, and — with a hostname
argument — runs the same hostname search the device-resolution pipeline uses.


Optional: AutoTask ticket enrichment (NINJAONE_ENRICH_TICKETS)

Independently of the device card, AVA can write the resolved device onto the
chat's AutoTask ticket: attaching the matched Configuration Item
(configurationItemID) and, when available, the NinjaRMM-DeviceUID ticket
UDF. This is best-effort, only fires on high-confidence matches, and never
overwrites a pre-existing CI or UDF value already on the ticket.

VariableDefaultEffect
NINJAONE_ENRICH_TICKETSfalse (off)Sole enable switch for AT ticket writes. Anything other than the exact string true means disabled — no AT enrichment calls at all. The read-only device card is unaffected either way.

⚠️ Do not enable this until you have run the UDF merge pre-flight against
your own AutoTask instance.
The enrichment PATCHes the ticket's
userDefinedFields array, and correctness depends on your AutoTask instance
merging that array (updating the named UDF, leaving others untouched)
rather than replacing it wholesale. This behavior should be verified per
instance, on a throwaway ticket, before any production ticket is touched.

UDF merge pre-flight (one-time, ~10 minutes)

  1. Create a scrap ticket in your AutoTask instance — any test company, any
    title clearly marked as a test. You'll delete it afterwards.

  2. Seed two different UDFs on that ticket with recognizable values (via the
    AutoTask UI or API) — for example a text UDF set to KEEP-ME and a second
    UDF set to WILL-PATCH.

  3. PATCH exactly one of them via the REST API, sending a
    userDefinedFields array that contains only the one UDF you're changing:

    curl -X PATCH "$AUTOTASK_API_ZONE_URL/Tickets" \
      -H "Content-Type: application/json" \
      -H "UserName: $AUTOTASK_API_USER" \
      -H "Secret: $AUTOTASK_API_SECRET" \
      -H "ApiIntegrationcode: $AUTOTASK_API_INTEGRATION_CODE" \
      -d '{"id": <scrap-ticket-id>, "userDefinedFields": [{"name": "<patched-udf-name>", "value": "PATCHED"}]}'
  4. Re-read the ticket and verify both outcomes: the patched UDF now says
    PATCHED, and the other UDF still says KEEP-ME. A plain filter query
    returns UDFs by default — do not add an IncludeFields key (some instances
    reject it).

  5. Both survived? Your instance merges. Delete the scrap ticket and set
    NINJAONE_ENRICH_TICKETS=true.
    The seeded UDF was blanked? Your instance replaces the array — leave
    enrichment off (the device card still works fully without it).


Honest limitations

  • The "Open in NinjaOne" deep link requires an existing NinjaOne console
    session
    in the engineer's browser — it is not a standalone remote-session
    launcher.
  • No device actions of any kind — no remote session, no reboot, no
    scripts. This is a read-only glance by design.
  • Systray hints are client-reported — useful for lookup, never trusted for
    identity or authorization.
  • Telemetry reflects NinjaOne's last check-in, not a chat-triggered
    real-time poll.

Next steps


Did this page help you?