TimeZest PSA Integration
TimeZest exists to couple customer scheduling to the MSP's PSA. The
booking page is incidental — the value is that a confirmed slot lands
on the ConnectWise / Autotask / Halo ticket, on the technician's PSA
calendar, and in the billing record. Two parts of the scheduling
request payload carry that coupling: associatedEntities and
triggerMode.
Anti-triggers
This skill shapes the TimeZest side of the link. It has no PSA
credentials and cannot read or write a ticket:
- Reading, updating, or closing the ticket — status, notes, time
entries, assignment; use
connectwise, halopsa, or the autotask
plugin.
- Finding the ticket to book against — ticket search and triage
happen in the PSA; arrive here with the ID already resolved.
- Configuring the PSA-side integration — the
pod workflow, its
notification templates, and the TimeZest app install are configured
in the PSA and in the TimeZest web UI, not through these tools.
- A booking that never sent, as opposed to one that never synced —
a request stuck before delivery is a scheduling-request state
question; use
timezest-scheduling.
associatedEntities — the PSA link
Every timezest_scheduling_create_request call should carry an
associatedEntities array. Each entry links the booking to one PSA
record:
{
"associatedEntities": [
{
"type": "connectwise",
"id": "88421",
"number": "88421"
}
]
}
| Field |
Required |
Meaning |
type |
Yes |
PSA system — one of connectwise, autotask, halo |
id |
Yes |
The PSA entity ID |
number |
No |
Human-readable ticket reference |
A scheduling request created with no associatedEntities is an
orphan — nobody can find the booking from the PSA side later. Always
attach the association.
triggerMode — pod vs generate_url
| Mode |
What it does |
Use when |
pod |
Fires the configured PSA workflow on booking — updates the ticket, logs activity, delivers the link via the PSA's notification path |
Normal ticket-driven bookings |
generate_url |
Returns a bookingUrl for the dispatcher to paste manually; no PSA workflow fires |
Ad-hoc links, custom emails, testing |
pod is the right default for any booking tied to a ticket.
generate_url against a ticket is usually a mistake worth confirming.
Common Workflows
Build a PSA-linked booking
- Identify the PSA system the ticket lives in (
connectwise,
autotask, or halo) — critical when the MSP runs more than one
PSA in parallel.
- Build the
associatedEntities entry with type, id, and
number when known.
- Set
triggerMode: "pod" unless the dispatcher specifically wants a
manual link.
- Pass both into
timezest_scheduling_create_request.
Audit requests for PSA association
- Call
timezest_scheduling_list.
- Inspect each request's
associatedEntities and bucket:
- clean — one association, plausible type, has a
number
- orphan — no association at all
- suspect — association present but the
type looks wrong for
the MSP's PSA mix
- Pull
timezest_scheduling_get for any orphan or suspect request.
Diagnose a booking that did not sync
timezest_scheduling_get the request — confirm it is booked.
- Check
triggerMode: a generate_url request never fires the PSA
workflow, so the ticket was never meant to update automatically.
- Check
associatedEntities: a missing or wrong-type association
means the workflow had nothing to update.
- Remediation: re-create with a corrected payload, or add a manual
PSA note so the booking is not lost.
Edge Cases
- Multiple PSAs — One MSP may run ConnectWise and Autotask side by
side. The
type enum must match the ticket's actual system.
- Cross-system ID mismatch — A ConnectWise ticket ID linked as
autotask resolves to nothing. Verify the pairing.
- generate_url on a ticket — Produces a working link but no PSA
update. Flag and confirm intent.
Best Practices
- Never create a scheduling request without a PSA
associatedEntities
entry.
- Default
triggerMode to pod for ticket-driven bookings.
- Always include
number when known — it makes the request findable
by humans.
- Treat the scheduling request as the source of truth until the
pod
workflow confirms the PSA was updated.
Related Skills
1---2name: timezest-psa-integration3description: Wiring a TimeZest scheduling request into a PSA: the associatedEntities payload shapes for ConnectWise, Autotask, and Halo tickets, the difference between the pod and generate_url trigger modes, and the causes of bookings that complete but never update the PSA ticket.4---56# TimeZest PSA Integration78TimeZest exists to couple customer scheduling to the MSP's PSA. The9booking page is incidental — the value is that a confirmed slot lands10on the ConnectWise / Autotask / Halo ticket, on the technician's PSA11calendar, and in the billing record. Two parts of the scheduling12request payload carry that coupling: `associatedEntities` and13`triggerMode`.1415## Anti-triggers1617This skill shapes the TimeZest side of the link. It has no PSA18credentials and cannot read or write a ticket:1920- **Reading, updating, or closing the ticket** — status, notes, time21 entries, assignment; use `connectwise`, `halopsa`, or the `autotask`22 plugin.23- **Finding the ticket to book against** — ticket search and triage24 happen in the PSA; arrive here with the ID already resolved.25- **Configuring the PSA-side integration** — the `pod` workflow, its26 notification templates, and the TimeZest app install are configured27 in the PSA and in the TimeZest web UI, not through these tools.28- **A booking that never sent, as opposed to one that never synced** —29 a request stuck before delivery is a scheduling-request state30 question; use `timezest-scheduling`.3132## `associatedEntities` — the PSA link3334Every `timezest_scheduling_create_request` call should carry an35`associatedEntities` array. Each entry links the booking to one PSA36record:3738```json39{40 "associatedEntities": [41 {42 "type": "connectwise",43 "id": "88421",44 "number": "88421"45 }46 ]47}48```4950| Field | Required | Meaning |51|-------|----------|---------|52| `type` | Yes | PSA system — one of `connectwise`, `autotask`, `halo` |53| `id` | Yes | The PSA entity ID |54| `number` | No | Human-readable ticket reference |5556A scheduling request created with **no** `associatedEntities` is an57orphan — nobody can find the booking from the PSA side later. Always58attach the association.5960## `triggerMode` — pod vs generate_url6162| Mode | What it does | Use when |63|------|--------------|----------|64| `pod` | Fires the configured PSA workflow on booking — updates the ticket, logs activity, delivers the link via the PSA's notification path | Normal ticket-driven bookings |65| `generate_url` | Returns a `bookingUrl` for the dispatcher to paste manually; no PSA workflow fires | Ad-hoc links, custom emails, testing |6667`pod` is the right default for any booking tied to a ticket.68`generate_url` against a ticket is usually a mistake worth confirming.6970## Common Workflows7172### Build a PSA-linked booking73741. Identify the PSA system the ticket lives in (`connectwise`,75 `autotask`, or `halo`) — critical when the MSP runs more than one76 PSA in parallel.772. Build the `associatedEntities` entry with `type`, `id`, and78 `number` when known.793. Set `triggerMode: "pod"` unless the dispatcher specifically wants a80 manual link.814. Pass both into `timezest_scheduling_create_request`.8283### Audit requests for PSA association84851. Call `timezest_scheduling_list`.862. Inspect each request's `associatedEntities` and bucket:87 - **clean** — one association, plausible type, has a `number`88 - **orphan** — no association at all89 - **suspect** — association present but the `type` looks wrong for90 the MSP's PSA mix913. Pull `timezest_scheduling_get` for any orphan or suspect request.9293### Diagnose a booking that did not sync94951. `timezest_scheduling_get` the request — confirm it is `booked`.962. Check `triggerMode`: a `generate_url` request never fires the PSA97 workflow, so the ticket was never meant to update automatically.983. Check `associatedEntities`: a missing or wrong-`type` association99 means the workflow had nothing to update.1004. Remediation: re-create with a corrected payload, or add a manual101 PSA note so the booking is not lost.102103## Edge Cases104105- **Multiple PSAs** — One MSP may run ConnectWise and Autotask side by106 side. The `type` enum must match the ticket's actual system.107- **Cross-system ID mismatch** — A ConnectWise ticket ID linked as108 `autotask` resolves to nothing. Verify the pairing.109- **generate_url on a ticket** — Produces a working link but no PSA110 update. Flag and confirm intent.111112## Best Practices113114- Never create a scheduling request without a PSA `associatedEntities`115 entry.116- Default `triggerMode` to `pod` for ticket-driven bookings.117- Always include `number` when known — it makes the request findable118 by humans.119- Treat the scheduling request as the source of truth until the `pod`120 workflow confirms the PSA was updated.121122## Related Skills123124- [scheduling](../scheduling/SKILL.md) — Booking technicians against PSA tickets125- [api-patterns](../api-patterns/SKILL.md) — Auth, navigation, polling cadence