# 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
