ConnectWise API + AI: What You Can Actually Automate in 2026
9 min read
The ConnectWise API is one of the most capable PSA APIs in the MSP ecosystem — and one of the most underused. Most MSPs interact with ConnectWise exclusively through the UI, clicking through tickets, updating statuses, and logging time by hand. But underneath that UI sits a full REST API that lets you read, create, update, and delete nearly every object in your PSA. When you pair that API with AI, the automation possibilities go from “save a few clicks” to “eliminate entire workflow categories.”
This post is a practical guide to the ConnectWise Manage REST API: what endpoints matter for MSP automation, how authentication works, what the rate limits look like, and — most importantly — what you can actually build when AI sits on top of the API. If you’ve read our ConnectWise PSA + AI guide or the no-migration upgrade post, this goes deeper into the technical layer that makes all of it work.
ConnectWise API basics: authentication and structure
The ConnectWise Manage API is a standard REST API that uses JSON payloads. Every request requires three things:
- A client ID — registered through the ConnectWise Developer Portal. This identifies your integration.
- API keys — a public/private key pair tied to a CW member account. The member’s security role determines what the API can access.
- Base URL — typically
https://api-na.myconnectwise.net/{codebase}/apis/3.0/for North American cloud instances. The codebase is version-specific (e.g.,v2025_1) — fetch yours fromhttps://api-na.myconnectwise.net/login/companyinfo/{yourcompany}.
Authentication goes in the Authorization header as a Basic auth string, constructed from {companyId}+{publicKey}:{privateKey}, base64-encoded. The clientId header is sent separately.
Authorization: Basic {base64(companyId+publicKey:privateKey)}
clientId: your-client-id-uuid
A quick test to confirm your credentials work:
curl -s \
-H "Authorization: Basic $(echo -n 'yourcompany+publickey:privatekey' | base64)" \
-H "clientId: your-client-id" \
"https://api-na.myconnectwise.net/v2025_1/apis/3.0/system/info" | python3 -m json.tool
If you get a JSON response with version info, you’re connected.
Rate limits
ConnectWise enforces rate limits per client ID, though the exact thresholds are not publicly documented and vary by hosting tier. In practice, most integrations hit limits around 1,000 requests per minute for cloud-hosted instances. The API returns 429 Too Many Requests when you exceed the limit, with a Retry-After header.
For AI-driven automation, this means you need to be thoughtful about batching. Polling every ticket every 30 seconds across a large board will burn through your limit fast. Webhook-driven architectures — where ConnectWise pushes events to your system — scale much better.
Pagination
All list endpoints support page and pageSize parameters (max 1,000 per page) and return a Link header with pagination URLs. For large datasets like ticket history or time entries, always paginate — don’t try to pull everything in a single request.
The endpoints that matter for MSP automation
The ConnectWise API covers hundreds of endpoints across service, project, sales, procurement, finance, and system modules. For AI-powered service desk automation, these are the ones that matter:
Service tickets — /service/tickets
This is the core endpoint. You can create tickets, update any field (status, priority, type, subtype, board, assigned resource), add internal and external notes via /service/tickets/{id}/notes, and query tickets with CW’s condition syntax.
GET /service/tickets?conditions=board/name="Service Desk" AND status/name!="Closed"&orderBy=dateEntered desc&pageSize=50
The conditions parameter supports =, !=, >, <, contains, like, and logical operators. It’s powerful but has quirks — string values need double quotes inside the query parameter, and nested object fields use slash notation.
Contacts — /company/contacts
Every ticket references a contact. The contact endpoint lets you look up users, get their company association, pull communication items (email, phone), and check custom fields. For AI triage, this is how you identify who submitted the ticket and pull their context.
Companies — /company/companies
Company data includes contract information, territory, SLA settings, and custom fields. When AI triages a ticket, knowing the company’s service tier changes the priority calculation.
Configurations — /company/configurations
Configurations are ConnectWise’s asset/device records. They map to workstations, servers, network devices, and software. You can create, update, and query configurations — useful for syncing device data from your RMM or flagging devices related to a ticket.
GET /company/configurations?conditions=company/id=250 AND type/name="Workstation"
Time entries — /time/entries
Time tracking is where most MSPs lose money. The API lets you create time entries programmatically — specifying the ticket, member, hours, work type, and billable status. For automated workflows, this means logging time the moment a runbook completes, not after a tech remembers to do it.
{
"chargeToId": 12345,
"chargeToType": "ServiceTicket",
"member": { "identifier": "rwatne" },
"timeStart": "2026-05-14T09:00:00Z",
"timeEnd": "2026-05-14T09:05:00Z",
"workType": { "id": 1 },
"billableOption": "Billable"
}
Callbacks (webhooks) — /system/callbacks
Instead of polling for changes, register callbacks that fire on specific events. You can listen for ticket creation, ticket updates, contact changes, and more. The callback sends a POST to your URL with the object ID and action — you then fetch the full object with a follow-up API call.
{
"url": "https://your-endpoint.com/cw-webhook",
"objectId": 1,
"type": "ticket",
"level": "owner",
"description": "New ticket notifications"
}
This is how production-grade ConnectWise integrations work. Poll for the initial sync, then switch to webhook-driven processing for real-time response.
Practical automation examples
Knowing the endpoints is table stakes. Here’s what you build with them.
Auto-triage with AI-generated internal notes
When a new ticket arrives (via webhook), the AI reads the ticket subject and initial description via the API, classifies the intent, queries connected tools (RMM, documentation, M365) for relevant context, and posts an internal note back to the ticket:
POST /service/tickets/{id}/notes
{
"text": "## AI Triage Summary\n**Classification:** Password Reset\n**Priority:** Medium\n**User:** Sarah Johnson (sjohnson@acmecorp.com)\n**Device:** ACME-WS-042 — Online, 12 days uptime\n**M365:** Account active, MFA enabled, no recent sign-in failures\n**ITGlue SOP:** Password Reset — Standard (link)\n**Recommendation:** Run password reset runbook",
"internalAnalysisFlag": true,
"detailDescriptionFlag": false
}
The tech opens the ticket and the research is already done. That’s 10 minutes of context-gathering eliminated per ticket. (This is exactly what Junto’s triage pipeline does on every incoming ticket — but using the ConnectWise API alongside NinjaOne, ITGlue, M365, and Sophos simultaneously.)
Auto-update status and priority
AI doesn’t just read tickets — it writes back. After classification, the AI can update the ticket’s type, subtype, priority, and board assignment via a PATCH:
PATCH /service/tickets/{id}
[
{ "op": "replace", "path": "priority", "value": { "id": 8 } },
{ "op": "replace", "path": "type", "value": { "id": 250 } },
{ "op": "replace", "path": "board", "value": { "id": 30 } }
]
ConnectWise uses JSON Patch format for updates. Each operation specifies the field and the new value. This is cleaner than sending the entire ticket object back and avoids accidental overwrites.
Auto-log time entries after runbook execution
When an automated runbook resolves a ticket — say, a password reset that took the AI 45 seconds — the system creates a time entry and closes the ticket:
POST /time/entries
{
"chargeToId": 12345,
"chargeToType": "ServiceTicket",
"member": { "identifier": "junto-automation" },
"timeStart": "2026-05-14T14:30:00Z",
"timeEnd": "2026-05-14T14:31:00Z",
"workType": { "id": 1 },
"notes": "Automated password reset via runbook. User confirmed access.",
"billableOption": "Billable"
}
No tech forgot to log time. No disputed invoices. The time entry is accurate because it was logged by the system that did the work.
Create configurations from RMM data
When a new device appears in your RMM (NinjaOne, Datto, etc.) but doesn’t exist in ConnectWise, the AI can create the configuration automatically:
POST /company/configurations
{
"name": "ACME-WS-057",
"type": { "id": 5 },
"company": { "id": 250 },
"contact": { "id": 1042 },
"serialNumber": "PF2KR3N1",
"installedBy": { "identifier": "junto-automation" },
"vendorNotes": "Auto-created from NinjaOne device sync"
}
This keeps your PSA asset records in sync with your RMM without anyone manually creating configurations.
ConnectWise native AI vs. what you can build on the API
ConnectWise has invested in AI through Sidekick (their AI assistant across PSA, Automate, RMM, and Security products) and their recent acquisition of zofiQ for agentic AI capabilities. Here’s how the native options stack up against what you can build on the API:
| Capability | ConnectWise Sidekick + zofiQ | API + external AI |
|---|---|---|
| Ticket summarization | Yes (native) | Yes — and with context from non-CW tools |
| Auto triage / classification | Yes (Sidekick for PSA) | Full intent-based classification with custom training |
| Cross-tool context | CW ecosystem (PSA, Automate, RMM, ScreenConnect) | Any tool with an API — NinjaOne, ITGlue, Hudu, M365, Sophos, SentinelOne |
| Automated resolution | zofiQ (emerging) | Runbooks with approval workflows and execution |
| Time entry automation | No | Full API support for creating and updating time entries |
| Custom workflows | CW Flow (limited) | Unlimited — you control the logic |
The native AI is strongest within the ConnectWise ecosystem. If your stack is 100% ConnectWise — Automate, ScreenConnect, RMM — Sidekick covers the basics and zofiQ is adding agentic capabilities. But most MSPs run a mixed stack. NinjaOne or Datto for RMM. ITGlue or Hudu for documentation. SentinelOne or Sophos for security. The ConnectWise API is the bridge that lets external AI work with your PSA data alongside everything else.
The MCP approach: wrapping the ConnectWise API for AI
Raw API calls work, but they’re brittle. Every endpoint has its own quirks — conditions syntax, pagination, nested object references, patch format. When you’re building AI that interacts with the ConnectWise API, you don’t want the AI crafting raw HTTP requests. You want it working through a structured interface.
That’s where MCP (Model Context Protocol) comes in. We wrote a full guide to Claude MCP servers for MSPs covering setup, config, and build-vs-buy. An MCP server wraps the ConnectWise API into a set of tools that an AI model can invoke naturally. Instead of the AI needing to know that ticket notes require POST /service/tickets/{id}/notes with internalAnalysisFlag: true, it calls a tool like add_internal_note(ticket_id, text).
We covered MCP in depth in our MCP for MSPs post. The short version: MCP standardizes how AI connects to external tools. A ConnectWise MCP server exposes tools like:
search_tickets(conditions, limit)— query tickets with natural language translated to CW conditionsget_ticket_details(ticket_id)— full ticket with contact, company, and configuration dataadd_ticket_note(ticket_id, text, internal)— post notes without worrying about the note flag schemaupdate_ticket(ticket_id, fields)— update status, priority, type, board with validationcreate_time_entry(ticket_id, member, duration, notes)— log time with proper work type mapping
The AI works through these tools instead of raw HTTP. It asks “find open tickets on the Service Desk board assigned to nobody” instead of constructing a conditions query string. The MCP server handles the translation, authentication, pagination, and error handling.
For MSPs building their own ConnectWise MCP server, the core challenge is multi-tenancy. Every API call needs to use the right credentials for the right client instance. Credential management, tenant isolation, and audit logging all need to be handled at the server level — not by the AI model.
What Junto does with the ConnectWise API
Junto connects to ConnectWise PSA via the same API endpoints described in this post. Here’s what happens on a real ticket:
A user at Acme Corp emails “Outlook keeps crashing.” The ticket lands in ConnectWise. Within 30 seconds, Junto’s AI:
- Reads the ticket via
GET /service/tickets/{id} - Identifies the user and pulls their device from NinjaOne — finds 3 pending Outlook updates and a 22-day uptime
- Searches ITGlue for Acme Corp’s Outlook configuration docs — finds they’re on Microsoft 365 E3 with a specific Outlook profile policy
- Checks recent tickets via
GET /service/tickets?conditions=contact/id=1042 and summary contains "Outlook"— finds two similar tickets last month, both resolved with an Outlook profile repair - Posts an internal note via
POST /service/tickets/{id}/noteswith all of this context and a suggested resolution - Updates the ticket type, priority, and board via
PATCH /service/tickets/{id}
The tech opens the ticket and sees: device context, documentation, history, and a suggested fix. No tab switching. No 10-minute research phase. Every API call above is one you could build yourself — Junto just chains them together across your entire stack, for every ticket, automatically.
See the full list of supported tools at juntoai.com/integrations.
Getting started
If you want to explore the ConnectWise API directly, start here:
- Register a client ID at the ConnectWise Developer Portal
- Create an API member in your CW instance with a scoped security role — don’t use an admin account
- Generate API keys for that member
- Start with read-only calls —
GET /service/tickets,GET /company/contacts,GET /system/info - Add webhook callbacks for real-time ticket processing
- Scope write access carefully — use CW’s security roles to limit what the API member can modify
If you’d rather see AI working on your ConnectWise tickets in an hour instead of building it over a month, book a 15-minute demo. We’ll connect to your PSA, pull a few real tickets, and show you what automated triage looks like using the same API calls described above — across ConnectWise, NinjaOne, ITGlue, and the rest of your stack.