/close-ticket
Close a ConnectWise PSA ticket with resolution notes
$ npx -y skills add wyre-technology/msp-claude-plugins --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/close-ticket
Context preview
What this command does when you run it.
Close a ConnectWise PSA ticket with resolution notes
Command definition
close-ticket.mddescription: Close a ConnectWise PSA ticket with resolution notes
argument-hint: "<ticket_id> <resolution> [status] [time_minutes] [time_notes] [billable]"
arguments: [ticket_id, resolution, status, time_minutes, time_notes, billable]
Close ConnectWise PSA Ticket
Close a ConnectWise ticket with resolution notes and optional time entry.
Prerequisites
- Valid ConnectWise PSA API credentials configured
- User must have ticket update permissions
- Ticket must exist and be accessible
- A valid closed status must exist on the ticket's board
Steps
1. **Validate ticket exists and get current state**
GET /service/tickets/{id}- Confirm ticket is accessible
- Get current board ID for status lookup
- Check if ticket is already closed
2. **Resolve closed status**
GET /service/boards/{boardId}/statuses?conditions=closedStatus=true- If status parameter provided, validate it's a closed status
- Otherwise, use board's default closed status
3. **Add resolution note**
POST /service/tickets/{id}/notes
Content-Type: application/json
{
"text": "<resolution>",
"resolutionFlag": true,
"internalAnalysisFlag": false,
"customerUpdatedFlag": true,
"processNotifications": true
}4. **Log time entry (if time_minutes provided)**
POST /time/entries
Content-Type: application/json
{
"chargeToId": <ticket_id>,
"chargeToType": "ServiceTicket",
"timeStart": "<current_datetime>",
"timeEnd": "<current_datetime + time_minutes>",
"actualHours": <time_minutes / 60>,
"notes": "<time_notes or resolution>",
"billableOption": "<Billable or DoNotBill>"
}5. **Update ticket status to closed**
PATCH /service/tickets/{id}
Content-Type: application/json
[
{"op": "replace", "path": "/status/id", "value": <closed_status_id>},
{"op": "replace", "path": "/resolution", "value": "<resolution>"}
]6. **Return closure confirmation**
Parameters
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | ticket_id | integer | Yes | - | ConnectWise ticket ID to close | | resolution | string | Yes | - | Resolution notes | | status | string | No | Board default | Closed status name | | time_minutes | integer | No | - | Final time entry in minutes | | time_notes | string | No | - | Notes for time entry | | billable | boolean | No | true | Mark time as billable |
Examples
Basic Closure
/close-ticket 12345 "Password reset completed and verified with user"
With Time Entry
/close-ticket 12345 "Server patched and rebooted successfully" --time_minutes 30 --time_notes "Applied security patches"
Non-Billable Time
/close-ticket 12345 "Hardware replaced under warranty" --time_minutes 60 --billable false
Specific Closed Status
/close-ticket 12345 "Issue resolved" --status "Completed"
Full Closure with All Options
/close-ticket 12345 "Configured new email account and tested send/receive functionality" --status "Completed" --time_minutes 45 --time_notes "Email configuration and testing" --billable true
Output
Basic Closure
Ticket #12345 Closed Successfully
Resolution:
"Password reset completed and verified with user"
Final State:
Company: Acme Corporation
Summary: Password reset request
Board: Service Desk
Status: Closed
Priority: Medium (3)
Closed By: Jane Technician
Closed At: 2026-02-04 15:30:00
Total Time: 1.5 hours
URL: https://na.myconnectwise.net/v4_6_release/services/system_io/Service/fv_sr100_request.rails?service_recid=12345
With Time Entry
Ticket #12345 Closed Successfully
Resolution:
"Server patched and rebooted successfully"
Time Entry Added:
Duration: 30 minutes (0.5 hours)
Notes: Applied security patches
Billable: Yes
Work Type: Remote Support
Final State:
Company: Acme Corporation
Summary: Server maintenance required
Board: Managed Services
Status: Completed
Priority: Medium (3)
Closed By: Jane Technician
Closed At: 2026-02-04 16:00:00
Time Summary:
Previous: 2.0 hours
This Entry: 0.5 hours
Total: 2.5 hours (all billable)
URL: https://na.myconnectwise.net/v4_6_release/services/system_io/Service/fv_sr100_request.rails?service_recid=12345
API Authentication
# Base64 encode credentials: company+publicKey:privateKey
AUTH=$(echo -n "${CW_COMPANY}+${CW_PUBLIC_KEY}:${CW_PRIVATE_KEY}" | base64)
# Add resolution note
curl -s -X POST \
"https://${CW_HOST}/v4_6_release/apis/3.0/service/tickets/${TICKET_ID}/notes" \
-H "Authorization: Basic ${AUTH}" \
-H "clientId: ${CW_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '{
"text": "Resolution notes here",
"resolutionFlag": true,
"customerUpdatedFlag": true,
"processNotifications": true
}'
# Log time entry
curl -s -X POST \
"https://${CW_HOST}/v4_6_release/apis/3.0/time/entries" \
-H "Authorization: Basic ${AUTH}" \
-H "clientId: ${CW_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '{
"chargeToId": '"${TICKET_ID}"',
"chargeToType": "ServiceTicket",
"timeStart": "2026-02-04T15:00:00Z",
"timeEnd": "2026-02-04T15:30:00Z",
"actualHours": 0.5,
"notes": "Final work notes",
"billableOption": "Billable"
}'
# Update status to closed
curl -s -X PATCH \
"https://${CW_HOST}/v4_6_release/apis/3.0/service/tickets/${TICKET_ID}" \
-H "Authorization: Basic ${AUTH}" \
-H "clientId: ${CW_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '[
{"op": "replace", "path": "/status/id", "value": 5},
{"op": "replace", "path": "/resolution", "value": "Resolution notes here"}
]'Error Handling
Ticket Not Found
Error: Ticket #99999 not found
The ticket may have been deleted or you may not have pe
Read more
description: Close a ConnectWise PSA ticket with resolution notes argument-hint: "<ticket_id> <resolution> [status] [time_minutes] [time_notes] [billable]" arguments: [ticket_id, resolution, status, time_minutes, time_notes, billable]
Close ConnectWise PSA Ticket
Close a ConnectWise ticket with resolution notes and optional time entry.
Prerequisites
- Valid ConnectWise PSA API credentials configured
- User must have ticket update permissions
- Ticket must exist and be accessible
- A valid closed status must exist on the ticket's board
Steps
1. **Validate ticket exists and get current state**
GET /service/tickets/{id}- Confirm ticket is accessible
- Get current board ID for status lookup
- Check if ticket is already closed
2. **Resolve closed status**
GET /service/boards/{boardId}/statuses?conditions=closedStatus=true- If status parameter provided, validate it's a closed status
- Otherwise, use board's default closed status
3. **Add resolution note**
POST /service/tickets/{id}/notes
Content-Type: application/json
{
"text": "<resolution>",
"resolutionFlag": true,
"internalAnalysisFlag": false,
"customerUpdatedFlag": true,
"processNotifications": true
}4. **Log time entry (if time_minutes provided)**
POST /time/entries
Content-Type: application/json
{
"chargeToId": <ticket_id>,
"chargeToType": "ServiceTicket",
"timeStart": "<current_datetime>",
"timeEnd": "<current_datetime + time_minutes>",
"actualHours": <time_minutes / 60>,
"notes": "<time_notes or resolution>",
"billableOption": "<Billable or DoNotBill>"
}5. **Update ticket status to closed**
PATCH /service/tickets/{id}
Content-Type: application/json
[
{"op": "replace", "path": "/status/id", "value": <closed_status_id>},
{"op": "replace", "path": "/resolution", "value": "<resolution>"}
]6. **Return closure confirmation**
Parameters
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | ticket_id | integer | Yes | - | ConnectWise ticket ID to close | | resolution | string | Yes | - | Resolution notes | | status | string | No | Board default | Closed status name | | time_minutes | integer | No | - | Final time entry in minutes | | time_notes | string | No | - | Notes for time entry | | billable | boolean | No | true | Mark time as billable |
Examples
Basic Closure
/close-ticket 12345 "Password reset completed and verified with user"
With Time Entry
/close-ticket 12345 "Server patched and rebooted successfully" --time_minutes 30 --time_notes "Applied security patches"
Non-Billable Time
/close-ticket 12345 "Hardware replaced under warranty" --time_minutes 60 --billable false
Specific Closed Status
/close-ticket 12345 "Issue resolved" --status "Completed"
Full Closure with All Options
/close-ticket 12345 "Configured new email account and tested send/receive functionality" --status "Completed" --time_minutes 45 --time_notes "Email configuration and testing" --billable true
Output
Basic Closure
Ticket #12345 Closed Successfully Resolution: "Password reset completed and verified with user" Final State: Company: Acme Corporation Summary: Password reset request Board: Service Desk Status: Closed Priority: Medium (3) Closed By: Jane Technician Closed At: 2026-02-04 15:30:00 Total Time: 1.5 hours URL: https://na.myconnectwise.net/v4_6_release/services/system_io/Service/fv_sr100_request.rails?service_recid=12345
With Time Entry
Ticket #12345 Closed Successfully Resolution: "Server patched and rebooted successfully" Time Entry Added: Duration: 30 minutes (0.5 hours) Notes: Applied security patches Billable: Yes Work Type: Remote Support Final State: Company: Acme Corporation Summary: Server maintenance required Board: Managed Services Status: Completed Priority: Medium (3) Closed By: Jane Technician Closed At: 2026-02-04 16:00:00 Time Summary: Previous: 2.0 hours This Entry: 0.5 hours Total: 2.5 hours (all billable) URL: https://na.myconnectwise.net/v4_6_release/services/system_io/Service/fv_sr100_request.rails?service_recid=12345
API Authentication
# Base64 encode credentials: company+publicKey:privateKey
AUTH=$(echo -n "${CW_COMPANY}+${CW_PUBLIC_KEY}:${CW_PRIVATE_KEY}" | base64)
# Add resolution note
curl -s -X POST \
"https://${CW_HOST}/v4_6_release/apis/3.0/service/tickets/${TICKET_ID}/notes" \
-H "Authorization: Basic ${AUTH}" \
-H "clientId: ${CW_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '{
"text": "Resolution notes here",
"resolutionFlag": true,
"customerUpdatedFlag": true,
"processNotifications": true
}'
# Log time entry
curl -s -X POST \
"https://${CW_HOST}/v4_6_release/apis/3.0/time/entries" \
-H "Authorization: Basic ${AUTH}" \
-H "clientId: ${CW_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '{
"chargeToId": '"${TICKET_ID}"',
"chargeToType": "ServiceTicket",
"timeStart": "2026-02-04T15:00:00Z",
"timeEnd": "2026-02-04T15:30:00Z",
"actualHours": 0.5,
"notes": "Final work notes",
"billableOption": "Billable"
}'
# Update status to closed
curl -s -X PATCH \
"https://${CW_HOST}/v4_6_release/apis/3.0/service/tickets/${TICKET_ID}" \
-H "Authorization: Basic ${AUTH}" \
-H "clientId: ${CW_CLIENT_ID}" \
-H "Content-Type: application/json" \
-d '[
{"op": "replace", "path": "/status/id", "value": 5},
{"op": "replace", "path": "/resolution", "value": "Resolution notes here"}
]'Error Handling
Ticket Not Found
Error: Ticket #99999 not found The ticket may have been deleted or you may not have pe
One command to supercharge Claude Code for MSP workflows. Then restart Claude Code. That's it. Documentation: mcp.wyre.ai
Repo: wyre-technology/msp-claude-plugins
Other commands on msp-claude-plugins.
- /case-review
Review and triage abuse mailbox cases in Abnormal Security
Open command - /search-threats
Search for specific threat patterns in Abnormal Security by sender, recipient, attack type, or keywords
Open command - /threat-triage
Triage recent email threats detected by Abnormal Security by severity and attack type
Open command - /list-overdue-invoices
List open and overdue Alternative Payments invoices and optionally generate hosted payment links for them
Open command - /reconcile-payout
Reconcile an Alternative Payments payout by listing its transactions and matching them against invoices and customers
Open command - /eol-report
EOL/EOS risk report — devices, OS versions, and firmware approaching or past end-of-life/end-of-support, prioritized by criticality
Open command

