From 046175af3ab533a3dd1e86dc2be4fd4c6fabc704 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Fri, 17 Apr 2026 10:53:34 -0700 Subject: [PATCH] =?UTF-8?q?Add=20/syncro=20command=20=E2=80=94=20Syncro=20?= =?UTF-8?q?PSA=20ticket=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create, update, close, comment on, search, and bill tickets via Syncro REST API. Includes customer search, invoice creation, line items, and ticket timer management. API key from SOPS vault. Verified: pulls real ticket data from computerguru.syncromsp.com. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/syncro.md | 145 +++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 .claude/commands/syncro.md diff --git a/.claude/commands/syncro.md b/.claude/commands/syncro.md new file mode 100644 index 0000000..08b6838 --- /dev/null +++ b/.claude/commands/syncro.md @@ -0,0 +1,145 @@ +# /syncro — Syncro PSA ticket management + +Create, update, close, comment on, and bill tickets in Syncro PSA. + +## Usage + +``` +/syncro Show open tickets summary +/syncro ticket View ticket details + comments +/syncro create Create new ticket +/syncro update Update ticket status +/syncro close Close/resolve a ticket +/syncro comment Add a comment to a ticket +/syncro bill Create invoice from ticket time entries +/syncro search Search tickets by subject/customer +/syncro customers Search customers +``` + +## API Configuration + +**Base URL:** `https://computerguru.syncromsp.com/api/v1` +**API Key:** SOPS vault `msp-tools/syncro.sops.yaml` → `credentials.credential` +**Rate limit:** 180 requests/minute per IP +**Docs:** https://api-docs.syncromsp.com/ + +## Implementation + +When invoked, use the Syncro REST API via `curl`. All requests include `?api_key=` as query parameter (NOT in header — Syncro uses query param auth). + +### Get API key + +```bash +API_KEY=$(bash D:/vault/scripts/vault.sh get-field msp-tools/syncro.sops.yaml credentials.credential) +BASE="https://computerguru.syncromsp.com/api/v1" +``` + +If `vault.sh get-field` fails (yq not installed), fall back to: +```bash +API_KEY=$(sops -d D:/vault/msp-tools/syncro.sops.yaml | python -c "import sys,yaml; print(yaml.safe_load(sys.stdin)['credentials']['credential'])") +``` + +### Endpoints reference + +#### Tickets + +| Operation | Method | Endpoint | Body | +|---|---|---|---| +| List tickets | GET | `/tickets?status=&per_page=25` | — | +| Get ticket | GET | `/tickets/` | — | +| Create ticket | POST | `/tickets` | `{"customer_id": N, "subject": "...", "problem_type": "...", "status": "New"}` | +| Update ticket | PUT | `/tickets/` | `{"status": "In Progress", "priority": "..."}` | +| Delete ticket | DELETE | `/tickets/` | — | + +**Ticket statuses:** `New`, `In Progress`, `Waiting on Customer`, `Waiting on Vendor`, `Scheduled`, `Resolved`, `Invoiced`, `Closed` + +**Ticket fields (create/update):** +- `customer_id` (required for create) +- `subject` (required for create) +- `problem_type` (string, free-form) +- `status` (string, one of the statuses above) +- `priority` (string) +- `due_date` (ISO date) +- `user_id` (assign to tech) +- `contact_id` (customer contact) +- `ticket_type_id` (ticket category) + +#### Comments + +| Operation | Method | Endpoint | Body | +|---|---|---|---| +| Add comment | POST | `/tickets//comment` | `{"subject": "Update", "body": "...", "hidden": false, "do_not_email": false}` | + +**Comment fields:** +- `subject` — comment header (e.g., "Update", "Resolution", "Internal Note") +- `body` — comment text (HTML supported) +- `hidden` — if true, internal-only (customer can't see) +- `do_not_email` — if true, don't email customer about this comment + +#### Customers + +| Operation | Method | Endpoint | +|---|---|---| +| List/search | GET | `/customers?query=&per_page=25` | +| Get customer | GET | `/customers/` | +| Create customer | POST | `/customers` | + +#### Invoices + +| Operation | Method | Endpoint | Body | +|---|---|---|---| +| List invoices | GET | `/invoices?per_page=25` | +| Get invoice | GET | `/invoices/` | +| Create from ticket | POST | `/invoices` | `{"ticket_id": N, "customer_id": N}` | + +#### Line Items + +| Operation | Method | Endpoint | Body | +|---|---|---|---| +| Add line item | POST | `/line_items` | `{"invoice_id": N, "item": "...", "quantity": 1, "price": 125.00}` | + +#### Ticket Timers + +| Operation | Method | Endpoint | +|---|---|---| +| List | GET | `/ticket_timers?ticket_id=` | +| Create | POST | `/ticket_timers` | + +### Display formatting + +When showing ticket lists, format as: + +``` +#32164 New Jerry Burger Own cloud thing again +#32163 New LeeAnn Parkinson Remote - Jim cant access his email +#32162 Invoiced Len's Auto Brokerage Server upgrade +``` + +When showing ticket detail, include: +- Ticket number, subject, status, priority +- Customer name + contact +- Created date, due date, last updated +- Assigned tech +- Comments (most recent first, truncated to last 5) +- Time entries if any +- Billing status + +### Billing workflow + +When `/syncro bill ` is called: +1. Get ticket details + time entries +2. Show summary: total billable time, line items that would be created +3. Ask for confirmation: "Create invoice for $X? [yes/no]" +4. On yes: POST `/invoices` with ticket_id, then add line items +5. Update ticket status to "Invoiced" + +### Error handling + +- 401: API key invalid or expired +- 404: ticket/customer/invoice not found +- 422: validation error (show the error message from response body) +- 429: rate limited (wait 60s and retry) + +### Integration with session logs + +When closing a ticket (`/syncro close`), offer to create a session log entry in `clients//session-logs/` documenting what was resolved. Pull the ticket subject, comments, and resolution into a structured log.