# ConnectWise PSA Production Query Patterns ## Legacy Mirror Bypass If the `/service/tickets` endpoint returns tickets from 2011, the request is hitting a legacy mirror. **Solution:** Use the `conditions` parameter to force a production database hit. - **Query**: `conditions=id >= 110000` - **Result**: This bypasses the mirror and retrieves current production records. ## Secrets File Parsing & 401 Triage `~/.secrets/connectwise` uses `KEY=value` lines with prefixed keys (`CW_COMPANY_ID` / `CW_PUBLIC_KEY` / `CW_PRIVATE_KEY`). Proven auth build: ```python import base64 d = {} for line in open(path).read().splitlines(): if "=" in line: k, v = line.split("=", 1); d[k.strip()] = v preencode = d["CW_COMPANY_ID"] + d["CW_PUBLIC_KEY"] + ":" + d["CW_PRIVATE_KEY"] auth = "Basic " + base64.b64encode(preencode.encode()).decode() ``` The PublicKey already starts with `+`, so plain concatenation is correct (no extra separator). On 401 Unauthorized: print parsed key names and value lengths BEFORE editing code. A key-name mismatch (lookup found nothing) and a genuinely bad credential emit the same errors — `Incorrect username/password` or `Incorrect Authorization header format` — and only the parsed shape tells which fix applies. Patch the lookup; do not rewrite the whole script around it. ## Data Structures The API can return tickets in two primary formats: 1. **Raw List**: `[{"id": 123, ...}, {...}]` 2. **Wrapped Object**: `{"tickets": [{"id": 123, ...}, {...}]}` Always check for both in Python: ```python raw_data = json.loads(response) tickets = raw_data['tickets'] if isinstance(raw_data, dict) and 'tickets' in raw_data else raw_data ```