# ScreenConnect (ConnectWise Control) API Reference - ACG instance

Live-verified spec for the ACG ScreenConnect cloud instance via the RESTful API
Manager extension. Source: ConnectWise ScreenConnect docs
(https://docs.connectwise.com/ScreenConnect_Documentation/Developers) + live
probing 2026-06-22.

## Connection & auth

- **Instance:** `https://computerguru.screenconnect.com`
- **Extension GUID:** `2d558935-686a-4bd0-9991-07539f5fe749` (RESTful API Manager)
- **Endpoint:** `POST <instance>/App_Extensions/<guid>/Service.ashx/<Method>`
- **Auth headers (VERIFIED):**
  - `CTRLAuthHeader: <raw api_secret>`  (NO "Basic" prefix - Basic auth 401s)
  - `Origin: https://computerguru.screenconnect.com`
  - `Content-Type: application/json`
- **Secret:** SOPS vault `msp-tools/screenconnect.sops.yaml` field `credentials.api_secret`.
- **Param convention:** reads take a JSON object; write methods take a POSITIONAL ARRAY.
- **Custom properties (this instance):** CP1=Company, CP2=Site, CP3=Tag (up to CP8).

## Methods (probed live 2026-06-22)

| Method | Params | Status | Notes |
|---|---|---|---|
| `GetSessionsByFilter` | `{"sessionFilter":"<expr>"}` | VERIFIED | **Full-fleet listing.** Session-filter expression. `SessionType = 'Access'` -> 958 agents; `SessionType = 'Support'` -> 24. CLI `sessions`. See filter syntax below. |
| `GetSessionsByName` | `{"sessionName":"<name>"}` | VERIFIED | EXACT Name match. "" returns only blank-Name sessions (NOT the fleet). CLI `sessions --name`. |
| `GetSessionDetailsBySessionID` | `{"sessionID":"<id>"}` | VERIFIED | Full session object (CustomPropertyValues, ActiveConnections, ...). CLI `session`. |
| `GetSessionBySessionID` | `{"sessionID":"<id>"}` | VERIFIED | Returns the session (or [] if none). |
| `SendCommandToSession` | `["<sessionID>","<command>"]` | VERIFIED (gated) | Runs a backstage command on the guest. CLI `send-command`. STATE-CHANGING. |
| `SendMessageToSession` | `["<sessionID>","<message>"]` | wired (array) | Chat message to the guest. CLI `send-message`. STATE-CHANGING. |
| `UpdateSessionCustomProperties` | `["<sessionID>",["cp1","cp2","cp3",...]]` | VERIFIED (gated) | Set CP1=Company/CP2=Site/CP3=Tag. CLI `set-properties`. STATE-CHANGING. |
| `CreateSession` | array (signature TBD) | EXISTS | Not the primary path - the installer creates access sessions. `raw` only. |
| `GetSessions` / `GetAllSessions` / `GetSessionGroups` | - | ABSENT | "web method does not exist" - but not needed; `GetSessionsByFilter` covers inventory. |

## Session-filter language (GetSessionsByFilter, probed live 2026-07-06)

Param name is `sessionFilter` (not `filter`). Empty/null -> "Session filter cannot be
null". String literals are single-quoted (double-quotes also work but need JSON
escaping). Verified operators/forms:

- `SessionType = 'Access'` (=2, the unattended agent fleet) | `'Support'` (=0) | `'Meeting'` (none here).
- `CustomProperty1 = 'Safesite'` -> per-client (CP1=Company, CP2=Site, CP3=Tag; up to CP8).
- `Name = '0124-DELL3540'` (exact) | `Name LIKE '*DELL*'` (partial, `*` wildcard, case-insensitive).
- Compound: `CustomProperty1 = 'Safesite' AND SessionType = 'Access'`; `AND`/`OR` supported.
- A bare token (`"DELL"`) or `"*"` matches nothing - always name a field.

## Parameterized access installer (the deploy capability)

The cloud serves a pre-keyed installer (no thumbprint param needed - the relay is
the instance subdomain). Build URL:

```
<instance>/Bin/ScreenConnect.ClientSetup.<ext>?e=Access&y=Guest&t=<name>&c=<CP1>&c=<CP2>&c=<CP3>&c=&c=&c=&c=&c=
```

- `<ext>`: msi | exe (Windows), pkg (macOS), deb | rpm | sh (Linux). VERIFIED: the
  `.msi` returns HTTP 200 / application/x-msi (~16 MB).
- `e=Access` (unattended access agent), `y=Guest` (the guest/installed role).
- `t=<name>`: the session Name (set it = machine name so by-name lookup works).
- repeated `c=`: custom properties in order (CP1=Company, CP2=Site, CP3=Tag, ... 8 slots).
- Windows silent install: `msiexec /i <file> /qn /norestart`.

CLI `build-installer --platform msi --name HOST --company X --site Y --tag Z`.

VERIFIED end-to-end 2026-06-22: RMM-pushed parameterized .msi -> session
`RMM-TEST-MACHINE` appeared with CustomPropertyValues `["AZ Computer Guru","Howard-VM","SC-TEST",...]`;
`send-command` created a marker file on the guest; `set-properties` re-tagged CP3.

## Error handling

- Missing method -> HTTP 500 body `"Web method does not exist"` (treated as expected,
  not a skill failure - not logged).
- Bad params on a real method -> HTTP 500 `"session manager fault"` /
  NullReferenceException (a bogus sessionID faults the same as a bad shape, so the
  generic fault does NOT distinguish - verify writes against a known test session).
- A bare `{}` to a write method faults: writes need the positional array.
