PSA abstraction layer with provider pattern, ConnectWise integration (connection management, ticket linking, note posting, status updates, member mapping), Integrations page UI, Fernet credential encryption, in-memory TTL cache, 6 DB migrations, ConnectWise API reference docs.
268 lines
12 KiB
Markdown
268 lines
12 KiB
Markdown
# ConnectWise PSA API — Integration Quick Reference
|
|
## For ResolutionFlow Development (Claude Code)
|
|
|
|
> **Source:** ConnectWise PSA OpenAPI Spec v2025.16
|
|
> **Full extracted spec:** `docs/connectwise/connectwise-psa-resolutionflow-reference.json`
|
|
> **Full original spec:** `docs/connectwise/All.json` (7.6MB, 1838 endpoints, 842 schemas)
|
|
|
|
---
|
|
|
|
## Authentication
|
|
|
|
- **Method:** API Key (Public/Private key pair per API Member)
|
|
- **Headers required on every request:**
|
|
- `Authorization: Basic {base64(companyId+publicKey:privateKey)}`
|
|
- `clientId: {your_connectwise_client_id}` (assigned via developer program)
|
|
- **Accept header:** `application/vnd.connectwise.com+json; version=2025.16`
|
|
- **Base URL pattern:** `https://{site}/v4_6_release/apis/3.0`
|
|
- **Date format:** ISO 8601 `yyyy-MM-ddTHH:mm:ssZ`
|
|
- **SSL required** on production servers
|
|
|
|
## Pagination & Query
|
|
|
|
- Default page size: 25, max: 1000
|
|
- Query params: `conditions`, `orderBy`, `fields`, `page`, `pageSize`, `childConditions`, `customFieldConditions`
|
|
- Condition syntax: `fieldName="value"`, supports `AND`, `OR`, `like`, `contains`, `>`, `<`, `!=`
|
|
- No documented hard rate limits (design respectfully)
|
|
|
|
---
|
|
|
|
## TIER 1 — Core Integration
|
|
|
|
### Service Tickets (`/service/tickets`)
|
|
**The central entity. 120 fields. 33 endpoints.**
|
|
|
|
Key endpoints:
|
|
| Method | Path | Purpose |
|
|
|--------|------|---------|
|
|
| GET | `/service/tickets` | List tickets (with conditions filter) |
|
|
| POST | `/service/tickets` | Create a ticket |
|
|
| GET | `/service/tickets/{id}` | Get single ticket |
|
|
| PATCH | `/service/tickets/{id}` | Update ticket fields |
|
|
| GET | `/service/tickets/{parentId}/notes` | List ticket notes |
|
|
| POST | `/service/tickets/{parentId}/notes` | **Add note to ticket** ⭐ |
|
|
| GET | `/service/tickets/{parentId}/configurations` | Get attached devices |
|
|
| POST | `/service/tickets/{parentId}/configurations` | Attach a device |
|
|
| GET | `/service/tickets/{parentId}/tasks` | Get ticket tasks |
|
|
| POST | `/service/tickets/{parentId}/tasks` | Add task to ticket |
|
|
| GET | `/service/tickets/{parentId}/allNotes` | Get ALL note types |
|
|
| POST | `/service/tickets/search` | Advanced search |
|
|
| GET | `/service/tickets/calculateSla` | Get SLA times |
|
|
| POST | `/service/tickets/{parentId}/merge` | Merge tickets |
|
|
| POST | `/service/tickets/{id}/copy` | Copy a ticket |
|
|
| POST | `/service/tickets/{parentId}/convert` | Convert to project |
|
|
|
|
Key Ticket fields for ResolutionFlow:
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| `id` | integer | |
|
|
| `summary` | string | Max length: 100; |
|
|
| `board` | BoardReference | |
|
|
| `status` | ServiceStatusReference | |
|
|
| `company` | CompanyReference | |
|
|
| `contact` | ContactReference | |
|
|
| `contactName` | string | Max length: 62; |
|
|
| `contactEmailAddress` | string | Max length: 250; |
|
|
| `site` | SiteReference | |
|
|
| `type` | ServiceTypeReference | |
|
|
| `subType` | ServiceSubTypeReference | |
|
|
| `item` | ServiceItemReference | |
|
|
| `team` | ServiceTeamReference | |
|
|
| `owner` | MemberReference | |
|
|
| `priority` | PriorityReference | |
|
|
| `severity` | string | Required On Updates; |
|
|
| `impact` | string | Required On Updates; |
|
|
| `source` | ServiceSourceReference | |
|
|
| `sla` | SLAReference | |
|
|
| `slaStatus` | string | |
|
|
| `isInSla` | boolean | |
|
|
| `agreement` | AgreementReference | |
|
|
| `initialDescription` | string | Only available for POST, will not be returned in the response. |
|
|
| `initialInternalAnalysis` | string | Only available for POST, will not be returned in the response. |
|
|
| `initialResolution` | string | Only available for POST, will not be returned in the response. |
|
|
| `closedFlag` | boolean | |
|
|
| `closedDate` | string | |
|
|
| `closedBy` | string | |
|
|
| `dateResolved` | string | |
|
|
| `dateResponded` | string | |
|
|
| `actualHours` | number | |
|
|
| `budgetHours` | number | |
|
|
| `resources` | string | |
|
|
| `parentTicketId` | integer | |
|
|
| `externalXRef` | string | Max length: 100; |
|
|
| `knowledgeBaseLinkId` | integer | |
|
|
| `customFields` | array | |
|
|
| `processNotifications` | boolean | Can be set to false to skip notification processing when adding or updating a... |
|
|
| `skipCallback` | boolean | |
|
|
| `recordType` | string | |
|
|
| `respondMinutes` | integer | To obtain the current SLA times for an active ticket, please use the /service... |
|
|
| `resPlanMinutes` | integer | To obtain the current SLA times for an active ticket, please use the /service... |
|
|
| `resolveMinutes` | integer | To obtain the current SLA times for an active ticket, please use the /service... |
|
|
|
|
### ServiceNote / TicketNote Schema
|
|
**The schema for notes added to tickets. This is where session documentation lands.**
|
|
|
|
| Field | Type | Purpose |
|
|
|-------|------|---------|
|
|
| `id` | integer | Note ID |
|
|
| `ticketId` | integer | Parent ticket |
|
|
| `text` | string | **Note content — session documentation goes here** |
|
|
| `detailDescriptionFlag` | boolean | Mark as "Description" note |
|
|
| `internalAnalysisFlag` | boolean | Mark as "Internal Analysis" note ⭐ |
|
|
| `resolutionFlag` | boolean | Mark as "Resolution" note ⭐ |
|
|
| `issueFlag` | boolean | Mark as issue note |
|
|
| `internalFlag` | boolean | Internal-only (not visible to customer) |
|
|
| `externalFlag` | boolean | Visible to customer |
|
|
| `member` | MemberReference | Who wrote the note |
|
|
| `contact` | ContactReference | Contact associated |
|
|
| `processNotifications` | boolean | Trigger notification workflows |
|
|
| `dateCreated` | string | When created |
|
|
| `createdBy` | string | Creator |
|
|
| `sentimentScore` | number | AI sentiment (ServiceNote only) |
|
|
|
|
**ResolutionFlow mapping:** Post session documentation as an **internal analysis note** (`internalAnalysisFlag: true, internalFlag: true`), and optionally post a resolution summary (`resolutionFlag: true`) when the session resolves the issue.
|
|
|
|
### Companies (`/company/companies`)
|
|
**72 fields. Client/customer context for sessions.**
|
|
|
|
Key fields: `id`, `identifier`, `name`, `status`, `addressLine1`, `city`, `state`, `zip`, `phoneNumber`, `website`, `territory`, `market`, `defaultContact`, `parentCompany`, `customFields`
|
|
|
|
Key endpoints:
|
|
- `GET /company/companies` — List/search companies
|
|
- `GET /company/companies/{id}` — Get company detail
|
|
- `GET /company/companies/{parentId}/sites` — Get company sites
|
|
- `GET /company/companies/{parentId}/notes` — Get company notes
|
|
- `GET /company/companies/{parentId}/groups` — Get company groups
|
|
- `GET /company/companies/{parentId}/teams` — Get company teams
|
|
|
|
### Contacts (`/company/contacts`)
|
|
**62 fields. The person reporting the issue.**
|
|
|
|
Key fields: `id`, `firstName`, `lastName`, `company`, `site`, `title`, `department`, `inactiveFlag`, `defaultPhoneType`, `defaultBillingFlag`, `communicationItems`
|
|
|
|
### Configurations / Assets (`/company/configurations`)
|
|
**58 fields. Devices and assets — critical MSP context.**
|
|
|
|
Key fields: `id`, `name`, `type`, `status`, `company`, `contact`, `site`, `deviceIdentifier`, `serialNumber`, `modelNumber`, `tagNumber`, `purchaseDate`, `installationDate`, `warrantyExpirationDate`, `vendorNotes`, `osType`, `osInfo`, `cpuSpeed`, `ram`, `lastBackupDate`, `ipAddress`, `macAddress`, `lastLoginName`, `customFields`
|
|
|
|
### Boards & Statuses (`/service/boards`)
|
|
**65-field Board model. 23-field BoardStatus model. 63 endpoints.**
|
|
|
|
Boards define service desk structure. Each board has statuses, types, subtypes, items, teams, notifications.
|
|
|
|
Key endpoints:
|
|
- `GET /service/boards` — List all boards
|
|
- `GET /service/boards/{id}` — Get board detail
|
|
- `GET /service/boards/{parentId}/statuses` — Get board statuses
|
|
- `GET /service/boards/{parentId}/types` — Get ticket types for board
|
|
- `GET /service/boards/{parentId}/subtypes` — Get subtypes
|
|
- `GET /service/boards/{parentId}/items` — Get items
|
|
- `GET /service/boards/{parentId}/teams` — Get board teams
|
|
|
|
### Callbacks / Webhooks (`/system/callbacks`)
|
|
**Real-time event notifications.**
|
|
|
|
| Method | Path | Purpose |
|
|
|--------|------|---------|
|
|
| GET | `/system/callbacks` | List registered callbacks |
|
|
| POST | `/system/callbacks` | **Register a new callback** |
|
|
| GET | `/system/callbacks/{id}` | Get callback detail |
|
|
| PATCH | `/system/callbacks/{id}` | Update callback |
|
|
| DELETE | `/system/callbacks/{id}` | Remove callback |
|
|
|
|
CallbackEntry fields: `id`, `description`, `url`, `objectId`, `type`, `level`, `memberId`, `payloadVersion`, `inactiveFlag`
|
|
|
|
**ResolutionFlow usage:** Register callbacks for ticket creation/update events to suggest relevant Flows in real-time.
|
|
|
|
---
|
|
|
|
## TIER 2 — High Value Add-ons
|
|
|
|
### Knowledge Base (`/service/knowledgeBaseArticles`)
|
|
**12 fields. Maps directly to Flows.**
|
|
|
|
| Field | Type | Purpose |
|
|
|-------|------|---------|
|
|
| `id` | integer | Article ID |
|
|
| `title` | string | Article title |
|
|
| `issue` | string | **Problem description** |
|
|
| `resolution` | string | **Solution** |
|
|
| `board` | BoardReference | Associated board |
|
|
| `categoryId` | integer | KB category |
|
|
| `subCategoryId` | integer | KB subcategory |
|
|
|
|
**ResolutionFlow mapping:** Completed sessions → auto-generate KB articles. Existing KB articles → inform FlowPilot AI suggestions.
|
|
|
|
### Time Entries (`/time/entries`)
|
|
**62 fields. Auto-log time from session duration.**
|
|
|
|
Key fields: `id`, `company`, `chargeToId`, `chargeToType`, `member`, `workType`, `workRole`, `timeStart`, `timeEnd`, `actualHours`, `notes`, `internalNotes`
|
|
|
|
### Documents (`/system/documents`)
|
|
**Attach session exports to tickets.**
|
|
|
|
- `POST /system/documents` — Upload document (multipart form data with `recordType=Ticket&recordId={id}`)
|
|
- `GET /system/documents/{id}/download` — Download document
|
|
|
|
### Members (`/system/members`)
|
|
**126 fields. Map CW members to ResolutionFlow users.**
|
|
|
|
Key fields: `id`, `identifier`, `firstName`, `lastName`, `emailAddress`, `photo`, `title`, `securityRole`, `defaultLocation`, `defaultDepartment`
|
|
|
|
### SLAs (`/service/SLAs`)
|
|
**23 fields. Pull SLA context into sessions.**
|
|
|
|
Fields include response/resolution hours and percentages by impact/urgency matrix.
|
|
|
|
### Priorities (`/service/priorities`)
|
|
Fields: `id`, `name`, `color`, `sortOrder`, `defaultFlag`, `level`
|
|
|
|
---
|
|
|
|
## TIER 3 — Future Expansion
|
|
|
|
### Projects (`/project/projects`)
|
|
**For larger MSP engagements. 11 endpoints.**
|
|
|
|
Key endpoints: CRUD on projects, plus `/project/projects/{parentId}/contacts`, `/project/projects/{parentId}/notes`, `/project/projects/{parentId}/teamMembers`
|
|
|
|
### Project Tickets (`/project/tickets`)
|
|
**80 fields. 24 endpoints. Separate from service tickets but similar structure.**
|
|
|
|
Includes own notes system at `/project/ticketNote`
|
|
|
|
### Workflows (`/system/workflows`)
|
|
**46 endpoints. ConnectWise's internal automation engine.**
|
|
|
|
Could trigger ResolutionFlow sessions automatically based on ticket events.
|
|
|
|
### Activities (`/sales/activities`)
|
|
**Track follow-ups post-session.**
|
|
|
|
### Agreements (`/finance/agreements`)
|
|
**44 endpoints. Billing/SLA context per client.**
|
|
|
|
---
|
|
|
|
## Integration Architecture Notes
|
|
|
|
### Session → Ticket Note (Primary Flow)
|
|
1. Engineer opens session, optionally links to CW ticket ID
|
|
2. Session documentation auto-generates during troubleshooting
|
|
3. On session complete: POST to `/service/tickets/{ticketId}/notes` with `internalAnalysisFlag: true`
|
|
4. Optionally POST resolution note with `resolutionFlag: true`
|
|
5. Optionally update ticket status via PATCH `/service/tickets/{id}`
|
|
|
|
### Ticket Context → Session (Reverse Flow)
|
|
1. Engineer enters CW ticket ID or session is launched from CW callback
|
|
2. GET `/service/tickets/{id}` for ticket details
|
|
3. GET `/service/tickets/{id}/configurations` for attached devices
|
|
4. GET `/company/companies/{companyId}` for client context
|
|
5. Feed all context to FlowPilot AI for informed troubleshooting
|
|
|
|
### Callback-Driven Flow Suggestions
|
|
1. Register callback via POST `/system/callbacks`
|
|
2. Receive ticket creation events at ResolutionFlow webhook endpoint
|
|
3. Analyze ticket summary/type/board
|
|
4. Suggest relevant Flows to the assigned engineer
|