> For the complete documentation index, see [llms.txt](https://docs.shortcutco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shortcutco.com/developers/mcp/tools.md).

# MCP tools

Every tool the Shortcut MCP server offers, with the scopes each needs, what it changes, and its arguments.

After this page you will know every tool the Shortcut MCP server offers (73 in all), which scopes each one needs, what it changes, and the arguments it takes. An agent sees only the tools its token's scopes allow; `explain_scopes` lists the rest and the scopes that would add them.

Every resource tool runs the same operation as its REST endpoint and returns the same JSON; workflow tools have no REST endpoint and are built from the same reads. Lists return at most 50 items and a `nextCursor`; pass it back as `cursor` for the next page. Writes take a `requestKey`: retrying with the same one returns the first result instead of acting twice.

## Workflow tools

Hand-written for agents: each answers a common question in one call. When the token lacks the scope for part of an answer, that part is left out and `meta.omitted` names it with the scope that would add it.

### `explain_scopes`

Explain what this connection can and cannot do: the scopes its token holds, which tools are available, which tools or parts of answers need a scope it lacks, and how a company admin grants more. Call it before telling the user something is impossible.

|        |           |
| ------ | --------- |
| Needs  | No scope  |
| Effect | Read-only |

No arguments.

### `find_customer`

Find customers by any mix of name, company, email, phone, or street address. Every word must match. Returns up to 10 matches with their ids, contact details, and addresses; pass an id to get\_customer for the full record. Start here when the user names a customer.

|        |                  |
| ------ | ---------------- |
| Needs  | `customers:read` |
| Effect | Read-only        |

| Argument | Type   | Required | Description                                                                                                                    |
| -------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `query`  | string | yes      | Words to match against the customer's name, company, email, phone, or a property address, such as `Jane Elm St` or `555-0142`. |

### `get_customer_overview`

Everything about one customer in one call: contact details and properties, active jobs, the next scheduled and last completed visit, the open balance (owed and past due, matching get\_open\_invoices), and open estimates. Parts the token cannot read are left out and named in meta.omitted with the scope that adds them; tell the user which scope to ask for. Get the id from find\_customer.

|                  |                                                                                                                                                                               |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Needs            | `customers:read`                                                                                                                                                              |
| Left out without | `activeJobs` needs `jobs:read`; `nextVisit` needs `visits:read`; `lastVisit` needs `visits:read`; `openBalance` needs `invoices:read`; `openEstimates` needs `estimates:read` |
| Effect           | Read-only                                                                                                                                                                     |

| Argument     | Type | Required | Description                                                |
| ------------ | ---- | -------- | ---------------------------------------------------------- |
| `customerId` | id   | yes      | The customer's id, from find\_customer or list\_customers. |

### `get_open_invoices`

List invoices still waiting for payment: unpaid (sent, not yet due) and overdue, newest first, optionally for one customer (customerId) or one status. Each has its number, amounts in US dollars, amountDue after payments, due date, ageDays since it was sent, and daysOverdue. Unsent drafts are not included. Returns at most 50 invoices and a nextCursor for the next page.

|        |                 |
| ------ | --------------- |
| Needs  | `invoices:read` |
| Effect | Read-only       |

| Argument     | Type                       | Required | Description                                                                                     |
| ------------ | -------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
| `limit`      | integer 1-50               | no       | How many items to return, 1-50. Defaults to 50.                                                 |
| `cursor`     | string                     | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                       |
| `status`     | one of `unpaid`, `overdue` | no       | Only `unpaid` or only `overdue` invoices. Defaults to both.                                     |
| `customerId` | id                         | no       | Only this customer's invoices. An id that is not one of the workspace's customers is not found. |

### `get_schedule`

Get the schedule for a date or range (YYYY-MM-DD in the workspace's timezone; defaults to today, and the answer says what today is). Visits come in schedule order: by date, then crew (unassigned last), then route position, with addresses and statuses. A page holds at most 50 visits; totalVisits per date and per crew says when a crew continues on the next page (pass nextCursor). Crew names need teams:read and customer names need customers:read; without them ids are shown.

|                  |                                                                        |
| ---------------- | ---------------------------------------------------------------------- |
| Needs            | `visits:read`                                                          |
| Left out without | `teamNames` needs `teams:read`; `customerNames` needs `customers:read` |
| Effect           | Read-only                                                              |

| Argument | Type   | Required | Description                                                                                            |
| -------- | ------ | -------- | ------------------------------------------------------------------------------------------------------ |
| `from`   | string | no       | First date. Defaults to today, `YYYY-MM-DD` in the workspace's timezone.                               |
| `to`     | string | no       | Last date, at most 31 days after `from`. Defaults to `from`, `YYYY-MM-DD` in the workspace's timezone. |
| `teamId` | id     | no       | Only this crew's visits.                                                                               |
| `cursor` | string | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                              |

## Resource tools

One tool per API operation, grouped by what they read or change.

### Crews

#### `get_team`

Get one team (crew) by id, with its active members in crew order, whether it is the default crew, and archivedAt if archived.

|        |              |
| ------ | ------------ |
| Needs  | `teams:read` |
| Effect | Read-only    |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_teams`

List the workspace's teams (crews) with their active members, which crew is the default, and archived crews with archivedAt. Pass archived: false for current crews only. Returns at most 50 teams and a nextCursor for the next page.

|        |              |
| ------ | ------------ |
| Needs  | `teams:read` |
| Effect | Read-only    |

| Argument       | Type         | Required | Description                                                                                                                                                                                            |
| -------------- | ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50 | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string       | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `archived`     | boolean      | no       | True for archived crews only, false for current crews only; omit for both.                                                                                                                             |
| `updatedSince` | timestamp    | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

### Custom fields

#### `list_custom_fields`

List the workspace's custom customer fields with their ids, names, types (text, select, date, number, boolean), and select options.

|        |                      |
| ------ | -------------------- |
| Needs  | `custom_fields:read` |
| Effect | Read-only            |

No arguments.

### Customers

#### `add_property`

Add a property (service address) to the customer whose id you pass as id, with an optional label such as Home, coordinates, and lawn square footage. Workspace automations that start when a lead record is created may run if the token has automations:trigger. Pass the same requestKey when retrying so a retry never adds the property twice.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `customers:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument            | Type               | Required | Description                                                                                                                                                              |
| ------------------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                | id                 | yes      | The object's id.                                                                                                                                                         |
| `address`           | string             | yes      | The service address on one line, such as `412 Elm St, Bozeman, MT 59715`.                                                                                                |
| `label`             | string             | no       | A short name for the property, such as `Home`.                                                                                                                           |
| `latitude`          | number -90-90      | no       | Latitude of the address. Send with `longitude`.                                                                                                                          |
| `longitude`         | number -180-180    | no       | Longitude of the address. Send with `latitude`.                                                                                                                          |
| `squareFeet`        | number 0-100000000 | no       | Lawn area in square feet.                                                                                                                                                |
| `externalReference` | object             | no       | Your id for this object. It is saved with the object in the same request; if another object already has it, nothing is created and the response is 409 `already_exists`. |
| `requestKey`        | string             | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                   |

#### `create_customer`

Create a customer with a name, their first service address, and optionally email, phone, and company. Email must not belong to another customer. The customer is queued for QuickBooks sync when QuickBooks is connected. If the token has automations:trigger, workspace automations that start for new customers may email or text them. Pass the same requestKey when retrying so a retry never creates a second customer.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `customers:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument            | Type           | Required | Description                                                                                                                                                              |
| ------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `firstName`         | string         | yes      | First name.                                                                                                                                                              |
| `lastName`          | string         | yes      | Last name.                                                                                                                                                               |
| `companyName`       | string or null | no       | Company name, when the customer is a business. Null or empty clears it.                                                                                                  |
| `email`             | string         | no       | Email address. Optional: without one the customer gets no email from the app. It must not belong to another customer or a team member.                                   |
| `phone`             | string         | no       | Phone number, such as `(406) 555-0142`. US numbers may omit the country code.                                                                                            |
| `property`          | object         | yes      | The customer's first property (service address). Add more with `POST /v1/customers/{id}/properties`.                                                                     |
| `externalReference` | object         | no       | Your id for this object. It is saved with the object in the same request; if another object already has it, nothing is created and the response is 409 `already_exists`. |
| `requestKey`        | string         | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                   |

#### `deactivate_customer`

Deactivate (archive) the customer whose id you pass as id: they become inactive and every one of their pending or scheduled jobs is paused, so no further visits are scheduled. Optionally give a reason and a churn reason (moved\_away, price, service\_issues, unknown). Workspace automations that start on a status change may run if the token has automations:trigger. Reversible with reactivate\_customer, but resuming the jobs is a separate choice there.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `customers:write`                                                                                           |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument      | Type                                                      | Required | Description                                                                                                                            |
| ------------- | --------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`          | id                                                        | yes      | The object's id.                                                                                                                       |
| `reason`      | string                                                    | no       | Why, saved on the customer's note in the app.                                                                                          |
| `churnReason` | one of `moved_away`, `price`, `service_issues`, `unknown` | no       | The churn reason for retention reports. Defaults to `unknown`.                                                                         |
| `requestKey`  | string                                                    | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `get_customer`

Get one customer by id, with their contact details, tags, and properties (service addresses).

|        |                  |
| ------ | ---------------- |
| Needs  | `customers:read` |
| Effect | Read-only        |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `get_customer_custom_fields`

Get the custom-field values of the customer whose id you pass as id. For select fields the value is an option id; list\_custom\_fields has the field names and option labels.

|        |                  |
| ------ | ---------------- |
| Needs  | `customers:read` |
| Effect | Read-only        |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `reactivate_customer`

Reactivate the inactive customer whose id you pass as id. Their paused jobs stay paused unless resumeJobs is now (resume from today) or date (resume from resumeDate, YYYY-MM-DD in the workspace's timezone); resuming needs jobs:write and schedules visits again. Workspace automations that start on a status change may run if the token has automations:trigger.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `customers:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type                                | Required | Description                                                                                                                                                                                 |
| ------------ | ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id                                  | yes      | The object's id.                                                                                                                                                                            |
| `resumeJobs` | one of `keep_paused`, `now`, `date` | no       | What happens to the customer's paused jobs: `keep_paused` (the default) leaves them paused, `now` resumes them from today, `date` from `resumeDate`. Resuming needs the `jobs:write` scope. |
| `resumeDate` | string                              | no       | With `resumeJobs: date`, the workspace-local date (YYYY-MM-DD, today or later) jobs resume from.                                                                                            |
| `reason`     | string                              | no       | Why, saved on the customer's note in the app.                                                                                                                                               |
| `requestKey` | string                              | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                                      |

#### `set_customer_custom_fields`

Set custom-field values on the customer whose id you pass as id, by field id (from list\_custom\_fields). Text up to 200 characters, select an option id, date YYYY-MM-DD, number a decimal, boolean true or false; null clears. Fields you leave out are unchanged. Workspace automations that start on a field change may run if the token has automations:trigger.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `customers:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type           | Required | Description                                                                                                                            |
| ------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id             | yes      | The object's id.                                                                                                                       |
| `values`     | list of object | yes      | The values to set. Fields you leave out are unchanged.                                                                                 |
| `requestKey` | string         | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `set_customer_tags`

Replace the whole tag list of the customer whose id you pass as id with the tag ids you pass (from list\_tags). Every tag you leave out is removed and an empty list removes all; to add one tag, pass the current tags plus the new one. Workspace automations that start when a tag is added or removed may run if the token has automations:trigger.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `customers:write`                                                                                           |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type       | Required | Description                                                                                                                            |
| ------------ | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id         | yes      | The object's id.                                                                                                                       |
| `tagIds`     | list of id | yes      | Every tag the customer should have, by id. Tags not listed are removed; an empty list removes all.                                     |
| `requestKey` | string     | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `update_customer`

Change the first or last name, company name, email, or phone of the customer whose id you pass as id. Only the fields you pass change. A new email must not belong to another customer. The change is queued for QuickBooks sync when QuickBooks is connected.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `customers:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument      | Type           | Required | Description                                                                              |
| ------------- | -------------- | -------- | ---------------------------------------------------------------------------------------- |
| `id`          | id             | yes      | The object's id.                                                                         |
| `firstName`   | string         | no       | First name.                                                                              |
| `lastName`    | string         | no       | Last name.                                                                               |
| `companyName` | string or null | no       | Company name, when the customer is a business. Null or empty clears it.                  |
| `email`       | string         | no       | Email address. It must not belong to another customer or a team member in the workspace. |
| `phone`       | string or null | no       | Phone number. Null or empty clears it.                                                   |

#### `update_property`

Change a property's address (with latitude and longitude), label, or lawn square footage. Pass the property's id and only the fields to change. Moving the address to another spot deletes the property's map and measurements, so it is refused unless confirmClearPropertyMap is true. Ask the user before confirming.

|        |                                                          |
| ------ | -------------------------------------------------------- |
| Needs  | `customers:write`                                        |
| Effect | Changes data; destructive (the app would ask to confirm) |

| Argument                  | Type                       | Required | Description                                                                                                                                                                                              |
| ------------------------- | -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | id                         | yes      | The object's id.                                                                                                                                                                                         |
| `address`                 | string                     | no       | A new address. Send `latitude` and `longitude` with it so the map and routes stay right. Moving it to another spot clears the property's map; see `confirmClearPropertyMap`.                             |
| `label`                   | string or null             | no       | A short name for the property. Null or empty clears it.                                                                                                                                                  |
| `latitude`                | number -90-90              | no       | Latitude of the address. Send with `longitude`.                                                                                                                                                          |
| `longitude`               | number -180-180            | no       | Longitude of the address. Send with `latitude`.                                                                                                                                                          |
| `squareFeet`              | number 0-100000000 or null | no       | Lawn area in square feet. Null clears it.                                                                                                                                                                |
| `confirmClearPropertyMap` | boolean                    | no       | Set `true` to allow an address change that clears the property's map, measurements, or measured square footage. Without it such a change is refused with `property_map_would_clear` and nothing changes. |

### Estimates

#### `approve_estimate`

Approve an estimate by id on the customer's behalf. This creates the estimate's jobs (pending, ready to schedule) exactly as approving in the app does, emails the workspace's admins, and, if the token has automations:trigger, workspace automations may message the customer. Pass the customer's choices of options or optional lines in selections. Approving twice creates nothing more.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `estimates:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type           | Required | Description                                                                                                                            |
| ------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id             | yes      | The object's id.                                                                                                                       |
| `selections` | list of object | no       | The customer's choices, as they would make them on the estimate page.                                                                  |
| `requestKey` | string         | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `create_estimate`

Create a draft estimate (a price offer) for a lead: pass leadId and lines, each with a catalog serviceId, cadence (recurring or one\_off), and optionally rate, quantity, options, and products. Totals are computed by the app. The estimate itself is not sent (use send\_estimate); workspace automations on new estimates may react if the token has automations:trigger. Pass a requestKey when retrying.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `estimates:write`                                               |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type           | Required | Description                                                                                                                                                                         |
| ------------ | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `leadId`     | id             | yes      | The lead the estimate answers. Its customer account and property are used; if the lead's email belongs to an existing customer it is linked to them, which needs `customers:write`. |
| `propertyId` | id             | no       | One of the customer's properties. Defaults to the lead's property.                                                                                                                  |
| `message`    | string         | no       | A message to the customer, sent with the estimate.                                                                                                                                  |
| `lines`      | list of object | no       | The estimate's lines, in order.                                                                                                                                                     |
| `requestKey` | string         | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                              |

#### `get_estimate`

Get one estimate by id with its status, total, and lines: each line's service, price, cadence, options, and products, and whether the customer chose or left it out.

|        |                  |
| ------ | ---------------- |
| Needs  | `estimates:read` |
| Effect | Read-only        |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_estimates`

List estimates (prices offered to leads and customers) newest first, with optional filters: status (draft, pending, approved, declined, voided, expired), customerId, or leadId. Returns totals, not lines; use get\_estimate for an estimate's lines. Returns at most 50 estimates and a nextCursor for the next page.

|        |                  |
| ------ | ---------------- |
| Needs  | `estimates:read` |
| Effect | Read-only        |

| Argument       | Type                                                                   | Required | Description                                                                                                                                                                                            |
| -------------- | ---------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50                                                           | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string                                                                 | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `status`       | one of `draft`, `pending`, `approved`, `declined`, `voided`, `expired` | no       | Only estimates with this status.                                                                                                                                                                       |
| `customerId`   | id                                                                     | no       | Only this customer's estimates.                                                                                                                                                                        |
| `leadId`       | id                                                                     | no       | Only estimates for this lead.                                                                                                                                                                          |
| `updatedSince` | timestamp                                                              | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `remind_estimate`

Remind the customer about a pending estimate by id, by email and/or text (defaults to how it was last sent). This messages the customer. At most one reminder per estimate every ten minutes; repeating with the same requestKey never sends again.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `estimates:send`, `estimates:read`                              |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type    | Required | Description                                                                                                                            |
| ------------ | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id      | yes      | The object's id.                                                                                                                       |
| `sendEmail`  | boolean | no       | Email a reminder. Defaults to the channels of the latest send.                                                                         |
| `sendSms`    | boolean | no       | Text a reminder. Defaults to the channels of the latest send.                                                                          |
| `requestKey` | string  | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `send_estimate`

Send an estimate by id to the customer by email (default) and optionally text, as sending in the app does. This messages the customer. A draft becomes pending; sending again does not send a second message. Customers who opted out of texts are skipped.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `estimates:send`, `estimates:read`                              |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type    | Required | Description                                                                                                                            |
| ------------ | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id      | yes      | The object's id.                                                                                                                       |
| `sendEmail`  | boolean | no       | Email the estimate link. Defaults to true.                                                                                             |
| `sendSms`    | boolean | no       | Text the estimate link. Customers who opted out of texts are skipped. Defaults to false.                                               |
| `message`    | string  | no       | Replaces the message to the customer.                                                                                                  |
| `requestKey` | string  | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `update_estimate`

Change a draft estimate by id: its message, property, or lines (lines replaces all of them; each needs a catalog serviceId and cadence). Only drafts can change. Totals are computed by the app.

|        |                   |
| ------ | ----------------- |
| Needs  | `estimates:write` |
| Effect | Changes data      |

| Argument     | Type           | Required | Description                                              |
| ------------ | -------------- | -------- | -------------------------------------------------------- |
| `id`         | id             | yes      | The object's id.                                         |
| `propertyId` | id             | no       | Another of the customer's properties.                    |
| `message`    | string or null | no       | The message to the customer; `null` clears it.           |
| `lines`      | list of object | no       | Replaces every line. Omit to keep the lines as they are. |

#### `void_estimate`

Void an estimate by id so the customer can no longer approve it. This cannot be undone; a voided, declined, or expired estimate cannot be voided again. Jobs it already created stay as they are. Workspace automations on voided estimates may react if the token has automations:trigger.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `estimates:write`                                                                                           |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

### Invoices

#### `get_invoice`

Get one invoice by id: its number, kind, status, amounts in US dollars (subtotal, sales tax, processing fee, late fees, total), due date (YYYY-MM-DD, as printed on the invoice), and its lines as the customer sees them, each with the visit it bills.

|        |                 |
| ------ | --------------- |
| Needs  | `invoices:read` |
| Effect | Read-only       |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_invoices`

List invoices with filters: status (draft, unpaid, overdue, paid, void), customerId, or dueBefore (YYYY-MM-DD; invoices whose dueDate is earlier). Each invoice has its number, kind, amounts in US dollars, due date, and customer id; use get\_invoice for its lines. Returns at most 50 invoices and a nextCursor for the next page.

|        |                 |
| ------ | --------------- |
| Needs  | `invoices:read` |
| Effect | Read-only       |

| Argument       | Type                                                | Required | Description                                                                                                                                                                                            |
| -------------- | --------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50                                        | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string                                              | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `status`       | one of `draft`, `unpaid`, `overdue`, `paid`, `void` | no       | Only invoices with this status, as the invoice's `status` field reports it.                                                                                                                            |
| `customerId`   | id                                                  | no       | Only this customer's invoices.                                                                                                                                                                         |
| `dueBefore`    | string                                              | no       | `YYYY-MM-DD`. Only invoices whose `dueDate` is before this date (not on it).                                                                                                                           |
| `updatedSince` | timestamp                                           | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `remind_invoice`

Send the customer a payment reminder for an unpaid or overdue invoice by email and text (sendEmail, sendSms; both default to true), as Remind does in the app. The customer receives it; their email preferences and SMS opt-out apply. Drafts, paid, and void invoices are refused, and an invoice can be reminded at most once in ten minutes. Pass a requestKey so a retry never sends a second reminder.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `invoices:send`, `invoices:read`                                |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type    | Required | Description                                                                                                                            |
| ------------ | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id      | yes      | The object's id.                                                                                                                       |
| `sendEmail`  | boolean | no       | Email the reminder. Defaults to true.                                                                                                  |
| `sendSms`    | boolean | no       | Text the reminder. Defaults to true; the customer's SMS opt-out still applies.                                                         |
| `requestKey` | string  | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `send_invoice`

Send a draft invoice to its customer by email, as Send does in the app. The customer receives it. Workspace automations for new invoices run only if the token has automations:trigger. A draft for an autopay customer is refused because sending would charge their card; those are sent from the app. Only drafts can be sent; use remind\_invoice for a sent invoice. Pass a requestKey when retrying.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `invoices:send`, `invoices:read`                                |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `void_invoice`

Void an unpaid or overdue invoice, with a reason that is recorded on the customer's notes. The customer can no longer pay it; a linked QuickBooks invoice is updated, and workspace automations that start on an invoice change may run if the token has automations:trigger. Drafts, paid invoices, prepay invoices, invoices with payments, refunds, or credits, and invoices with an online payment in progress are refused with the reason. This cannot be undone, so confirm with the user first. Pass a requestKey when retrying.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `invoices:write`                                                                                            |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `reason`     | string | yes      | Why the invoice is being voided. It is recorded on the customer's notes, as in the app.                                                |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

### Jobs

#### `cancel_job`

Cancel a job and all of its open visits. Completed visits keep their history; canceling an already canceled job changes nothing, and completed jobs cannot be canceled. This cannot be undone, so confirm with the user first. Pass the same requestKey when retrying.

|        |                                                          |
| ------ | -------------------------------------------------------- |
| Needs  | `jobs:write`                                             |
| Effect | Changes data; destructive (the app would ask to confirm) |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `create_jobs`

Create jobs for a customer from catalog services: one job per service, each one\_off or recurring (with cadenceFrequency and cadencePeriod), priced by rate and quantity. Pass propertyId when the customer has more than one property. Jobs start pending with no visits; call schedule\_job to put them on the schedule. Pass the same requestKey when retrying so a retry never creates duplicates.

|        |              |
| ------ | ------------ |
| Needs  | `jobs:write` |
| Effect | Changes data |

| Argument     | Type           | Required | Description                                                                                                                            |
| ------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `customerId` | id             | yes      | The customer the jobs are for.                                                                                                         |
| `propertyId` | id             | no       | The customer's property to service. Required when the customer has more than one active property.                                      |
| `services`   | list of object | yes      | One job is created per service. Jobs created together are grouped, so their visits share a stop.                                       |
| `requestKey` | string         | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `get_job`

Get one job by id: its name, customer, property and address, status, cadence, price (rate, quantity, subtotal), crew (teamId, and effectiveTeamId for the crew doing the next visit), next visit date, and pause details.

|        |             |
| ------ | ----------- |
| Needs  | `jobs:read` |
| Effect | Read-only   |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_job_visits`

List one job's visits (its scheduled services), optionally filtered by status, with each visit's date, status, crew, and times. Returns at most 50 visits and a nextCursor for the next page.

|        |                            |
| ------ | -------------------------- |
| Needs  | `jobs:read`, `visits:read` |
| Effect | Read-only                  |

| Argument       | Type                                                                                                 | Required | Description                                                                                                                                                                                            |
| -------------- | ---------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`           | id                                                                                                   | yes      | The job's id.                                                                                                                                                                                          |
| `limit`        | integer 1-50                                                                                         | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string                                                                                               | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `status`       | one of `pending`, `scheduled`, `completed`, `canceled`, `rescheduled`, `needs_reschedule`, `skipped` | no       | Only visits with this status.                                                                                                                                                                          |
| `updatedSince` | timestamp                                                                                            | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `list_jobs`

List jobs (services a customer buys, one-time or recurring) with filters: customerId, propertyId, status (pending, scheduled, paused, canceled, completed), or crew (teamId, the crew doing the job's next visit). Each job has its price, cadence, crew, and next visit date. Returns at most 50 jobs and a nextCursor for the next page.

|        |             |
| ------ | ----------- |
| Needs  | `jobs:read` |
| Effect | Read-only   |

| Argument         | Type                                                             | Required | Description                                                                                                                                                                                                                                                                                                                                                                                               |
| ---------------- | ---------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`          | integer 1-50                                                     | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                                                                                                                                                                                                                           |
| `cursor`         | string                                                           | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                                                                                                                                                                                                                                 |
| `customerId`     | id                                                               | no       | Only this customer's jobs.                                                                                                                                                                                                                                                                                                                                                                                |
| `propertyId`     | id                                                               | no       | Only jobs at this property.                                                                                                                                                                                                                                                                                                                                                                               |
| `status`         | one of `pending`, `scheduled`, `paused`, `canceled`, `completed` | no       | Only jobs with this status.                                                                                                                                                                                                                                                                                                                                                                               |
| `teamId`         | id                                                               | no       | Only jobs this crew is doing: jobs whose `effectiveTeamId` is this crew (the next visit's own crew, or the job's crew when that visit has none or there is no upcoming visit).                                                                                                                                                                                                                            |
| `externalSource` | string                                                           | no       | With `externalId`: only the job with this id in your system.                                                                                                                                                                                                                                                                                                                                              |
| `externalId`     | string                                                           | no       | With `externalSource`: only the job with this id in your system.                                                                                                                                                                                                                                                                                                                                          |
| `updatedSince`   | timestamp                                                        | no       | ISO 8601 timestamp. Returns jobs changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. A job's `updatedAt` changes only when the job itself changes: `nextVisitDate`, `nextVisitId`, `effectiveTeamId`, and `address` come from its visits and property, so sync visits from their own list. |

#### `pause_job`

Pause a scheduled job, indefinitely or until pausedUntil (YYYY-MM-DD, the workspace's timezone), with an optional reason. Pending, canceled, and completed jobs cannot be paused; repeating the same pause changes nothing. Use resume\_job to resume it.

|        |              |
| ------ | ------------ |
| Needs  | `jobs:write` |
| Effect | Changes data |

| Argument      | Type   | Required | Description                                                                                                                            |
| ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`          | id     | yes      | The object's id.                                                                                                                       |
| `pausedUntil` | string | no       | Pause until this date, `YYYY-MM-DD` in the workspace's timezone; today or later. Omit it to pause indefinitely.                        |
| `reason`      | string | no       | Why the job is paused, shown in the app.                                                                                               |
| `requestKey`  | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `resume_job`

Resume a paused job today or on resumeDate (YYYY-MM-DD, the workspace's timezone): its open visits are replaced by a new series starting on that date. Resuming a job that is already scheduled changes nothing; a pending job must be scheduled with schedule\_job instead. Pass the same requestKey when retrying.

|        |                                                          |
| ------ | -------------------------------------------------------- |
| Needs  | `jobs:write`                                             |
| Effect | Changes data; destructive (the app would ask to confirm) |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `resumeDate` | string | no       | The date the job's visits start again, `YYYY-MM-DD` in the workspace's timezone; today or later. Omit it to resume today.              |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `schedule_job`

Schedule a pending job: creates its visits starting on startDate (YYYY-MM-DD, the workspace's timezone, today or later), one visit for a one-time job or a series for a recurring one, on the job's crew or the teamId given. Only pending jobs can be scheduled. The workspace's job-scheduled automations, which may email or text the customer, run only if the token has automations:trigger. Pass the same requestKey when retrying.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `jobs:write`                                                    |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                                                                                                                          |
| ------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`         | id     | yes      | The object's id.                                                                                                                                                                                                                     |
| `startDate`  | string | yes      | The first visit's date, `YYYY-MM-DD` in the workspace's timezone; today or later. A recurring job's later visits follow its cadence from here.                                                                                       |
| `teamId`     | id     | no       | The crew for the visits this creates. Omit it to use the job's crew. For a recurring job with no crew yet, this crew also becomes the job's crew. Visits given the job's own crew store none of their own and follow the job's crew. |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                                                                               |

#### `update_job`

Change a job's name, description, or crew (teamId, recurring jobs only; null removes the crew). Upcoming open visits that follow the job's crew move with it; visits pinned to the previous crew are unpinned; if the job had no crew, every pinned upcoming visit is unpinned. Visits pinned to another crew keep their pin, and finished visits never change. Prices cannot be changed with this tool.

|        |              |
| ------ | ------------ |
| Needs  | `jobs:write` |
| Effect | Changes data |

| Argument      | Type           | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ------------- | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`          | id             | yes      | The object's id.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `name`        | string         | no       | A new name for the job.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `description` | string or null | no       | A new description, or null to clear it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `teamId`      | id or null     | no       | Recurring jobs only: the crew that owns the job, or null for none. Only upcoming open visits (pending, scheduled, or rescheduled, dated today or later) change. If the job had a crew, visits pinned to that previous crew are unpinned and follow the job's crew; visits pinned to any other crew, including the new one, keep their pin. If the job had no crew, every pinned upcoming open visit is unpinned and follows the new crew. Setting the job's current crew again unpins visits pinned to it. With null, visits pinned to the previous crew are left with no crew. Finished and past visits never change. |

### Leads

#### `create_lead`

Create a lead (a request for service) with a name, email, service address, and optionally phone, company, services requested, and notes. It behaves like a lead from the website form: staff are notified, and the workspace's automations, which may email or text the lead, run only if the token has automations:trigger. If the email belongs to an existing customer, the token also needs customers:write. The lead's source reads API in the app. Pass the same requestKey when retrying so a retry never creates a second lead.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `leads:write`                                                   |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument            | Type           | Required | Description                                                                                                                                                              |
| ------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `firstName`         | string         | yes      | First name.                                                                                                                                                              |
| `lastName`          | string         | yes      | Last name.                                                                                                                                                               |
| `email`             | string         | yes      | Email address. Required: the app uses it to match the lead to an existing customer.                                                                                      |
| `phone`             | string         | no       | Phone number, such as `(406) 555-0142`. US numbers may omit the country code.                                                                                            |
| `companyName`       | string or null | no       | Company name, when the lead is a business.                                                                                                                               |
| `address`           | string         | yes      | The service address on one line, such as `412 Elm St, Bozeman, MT 59715`.                                                                                                |
| `servicesRequested` | list of string | no       | What the lead asked for, such as `Weekly mowing`. Duplicates are removed.                                                                                                |
| `specialRequests`   | string         | no       | Anything else the lead said, shown on the lead in the app.                                                                                                               |
| `externalReference` | object         | no       | Your id for this object. It is saved with the object in the same request; if another object already has it, nothing is created and the response is 409 `already_exists`. |
| `requestKey`        | string         | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                   |

#### `dismiss_lead`

Dismiss a lead by id: set it aside so it no longer counts as open (status becomes dismissed). With automations:trigger, the workspace's automations may react to a dismissed lead, for example by emailing or texting it. Dismissing an already dismissed lead changes nothing; a lead that is already a customer cannot be dismissed. restore\_lead undoes it.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `leads:write`                                                   |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `get_lead`

Get one lead (a request for service) by id, with contact details, address, what they asked for, status, and stage.

|        |              |
| ------ | ------------ |
| Needs  | `leads:read` |
| Effect | Read-only    |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_leads`

List leads (requests for service) newest first, with optional filters: status (pending or dismissed), lifecycleStage (lead, prospect, customer), and source (intake\_form, manual, csv, api). Returns at most 50 leads and a nextCursor for the next page.

|        |              |
| ------ | ------------ |
| Needs  | `leads:read` |
| Effect | Read-only    |

| Argument         | Type                                         | Required | Description                                                                                                                                                                                            |
| ---------------- | -------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`          | integer 1-50                                 | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`         | string                                       | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `status`         | one of `pending`, `dismissed`                | no       | Only leads with this status.                                                                                                                                                                           |
| `lifecycleStage` | one of `lead`, `prospect`, `customer`        | no       | Only leads at this stage.                                                                                                                                                                              |
| `source`         | one of `intake_form`, `manual`, `csv`, `api` | no       | Only leads that arrived this way.                                                                                                                                                                      |
| `externalSource` | string                                       | no       | With `externalId`: only the lead with this id in your system.                                                                                                                                          |
| `externalId`     | string                                       | no       | With `externalSource`: only the lead with this id in your system.                                                                                                                                      |
| `updatedSince`   | timestamp                                    | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `restore_lead`

Restore a dismissed lead by id so it is open again (status becomes pending). Restoring a lead that is already open changes nothing.

|        |               |
| ------ | ------------- |
| Needs  | `leads:write` |
| Effect | Changes data  |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `update_lead`

Change a lead's name, company, email, phone, address, hours estimate, or square footage. Pass the lead's id and only the fields to change; null clears company, phone, hours, or square footage. A new address needs addressLat and addressLng; moving it elsewhere clears the lead's property map and measurements, so it is refused unless confirmClearPropertyMap is true. Ask the user before confirming.

|        |                                                          |
| ------ | -------------------------------------------------------- |
| Needs  | `leads:write`                                            |
| Effect | Changes data; destructive (the app would ask to confirm) |

| Argument                  | Type                       | Required | Description                                                                                                                                                                                                                                                                                  |
| ------------------------- | -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | id                         | yes      | The object's id.                                                                                                                                                                                                                                                                             |
| `firstName`               | string                     | no       | First name.                                                                                                                                                                                                                                                                                  |
| `lastName`                | string                     | no       | Last name.                                                                                                                                                                                                                                                                                   |
| `companyName`             | string or null             | no       | Company name, when the lead is a business. `null` clears it.                                                                                                                                                                                                                                 |
| `email`                   | string                     | no       | Email address. Changing it does not move the lead to another customer account; `customerId` stays as it is.                                                                                                                                                                                  |
| `phone`                   | string or null             | no       | Phone number, such as `(406) 555-0142`. US numbers may omit the country code. `null` clears it.                                                                                                                                                                                              |
| `address`                 | string                     | no       | The service address on one line. A changed address needs `addressLat` and `addressLng`, which place it on the map. Moving it to another spot clears the lead's property map, its measurements, and a square footage taken from that map; send `confirmClearPropertyMap: true` to allow that. |
| `addressLat`              | number -90-90              | no       | The address's latitude. Only with `address`.                                                                                                                                                                                                                                                 |
| `addressLng`              | number -180-180            | no       | The address's longitude. Only with `address`.                                                                                                                                                                                                                                                |
| `estimatedHours`          | number 0-10000 or null     | no       | The office's estimate of the work in hours. `null` clears it.                                                                                                                                                                                                                                |
| `sqFootage`               | number 0-100000000 or null | no       | Square footage typed in by hand. `null` clears it, so a reviewed measurement of the property, if any, applies again. When the lead is linked to a customer's property, the property's square footage changes too, which needs `customers:write`.                                             |
| `confirmClearPropertyMap` | boolean                    | no       | Set `true` to allow an address change that clears the lead's property map, measurements, or measured square footage. Without it such a change is refused with `property_map_would_clear` and nothing changes.                                                                                |

### Payments

#### `get_payment`

Get one payment by id: the invoice and customer it belongs to, its amount in US dollars, how it was paid (online, cash, check, ach, other), any reference such as a check number, the amount refunded so far (succeeded refunds at the time of the call), and when it was paid.

|        |                 |
| ------ | --------------- |
| Needs  | `payments:read` |
| Effect | Read-only       |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_payments`

List payments with filters: invoiceId or customerId. Each payment has its amount in US dollars, how it was paid (online, cash, check, ach, other), the amount refunded so far (succeeded refunds at the time of the call), and when it was paid. Returns at most 50 payments, newest first, and a nextCursor for the next page.

|        |                 |
| ------ | --------------- |
| Needs  | `payments:read` |
| Effect | Read-only       |

| Argument       | Type         | Required | Description                                                                                                                                                                                     |
| -------------- | ------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`        | integer 1-50 | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                 |
| `cursor`       | string       | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                       |
| `invoiceId`    | id           | no       | Only payments against this invoice.                                                                                                                                                             |
| `customerId`   | id           | no       | Only this customer's payments.                                                                                                                                                                  |
| `createdSince` | timestamp    | no       | ISO 8601 timestamp. Returns objects created at or after it, oldest first. Keep the largest `createdAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `record_offline_payment`

Record a cash, check, or other offline payment that pays an invoice in full (amount must equal the invoice total), with an optional paidOn date (YYYY-MM-DD) and reference such as a check number. The invoice becomes paid. Never charges a card. Workspace automations for paid invoices run only if the token has automations:trigger. Pass a requestKey when retrying so a retry never records the payment twice.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `payments:write`                                                |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type                            | Required | Description                                                                                                                                                                                                            |
| ------------ | ------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id                              | yes      | The object's id.                                                                                                                                                                                                       |
| `amount`     | number                          | yes      | Amount received, in US dollars. It must equal the invoice's `total`: recording a payment settles the invoice in full, as Mark paid does in the app.                                                                    |
| `method`     | one of `cash`, `check`, `other` | yes      | How the customer paid outside Shortcut.                                                                                                                                                                                |
| `paidOn`     | string                          | no       | The day the payment was received, `YYYY-MM-DD`, no later than today in the workspace's timezone. Defaults to now. The payment's `paidAt` is stored as midnight UTC of that date, as the app stores a chosen paid date. |
| `reference`  | string                          | no       | A reference such as a check number.                                                                                                                                                                                    |
| `requestKey` | string                          | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                                                                 |

#### `reverse_payment`

Undo a manual (cash, check, or other offline) payment, with a reason that is recorded on the customer's notes. The payment is deleted and its invoice becomes unpaid again (or overdue when past due); workspace automations that start on an invoice change may run if the token has automations:trigger. Online payments cannot be undone here. This cannot be undone, so confirm with the user first. Pass a requestKey when retrying.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `payments:write`, `invoices:read`                                                                           |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `reason`     | string | yes      | Why the payment is being undone. It is recorded on the customer's notes, as in the app.                                                |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

### Products

#### `create_product`

Add a product (a priced good such as mulch or stone) to the catalog with a name, unit label, and default unit price, and optionally a description, taxable, and display. Names must be unique regardless of case. Pass the same requestKey when retrying so a retry never creates a second product.

|        |                  |
| ------ | ---------------- |
| Needs  | `products:write` |
| Effect | Changes data     |

| Argument           | Type                          | Required | Description                                                                                                                            |
| ------------------ | ----------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `name`             | string                        | yes      | The product's name; unique in the workspace regardless of case.                                                                        |
| `unitLabel`        | string                        | yes      | The unit it is sold in, such as `yard` or `bag`.                                                                                       |
| `defaultUnitPrice` | number 0-10000000             | yes      | Default price per unit in US dollars.                                                                                                  |
| `description`      | string or null                | no       | Description shown on estimates and invoices; null clears it.                                                                           |
| `taxable`          | boolean                       | no       | Whether sales tax applies by default. Defaults to true.                                                                                |
| `defaultDisplay`   | one of `itemized`, `included` | no       | `itemized` (the default) shows the product as its own line; `included` folds it into the service.                                      |
| `requestKey`       | string                        | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `get_product`

Get one product from the catalog by id, with its unit, default price, tax setting, and status.

|        |                 |
| ------ | --------------- |
| Needs  | `products:read` |
| Effect | Read-only       |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_products`

List the workspace's products (priced goods such as mulch, stone, or plants that are added to estimates and visits) with unit and default price. Filter by status (active or archived). Returns at most 50 products and a nextCursor for the next page.

|        |                 |
| ------ | --------------- |
| Needs  | `products:read` |
| Effect | Read-only       |

| Argument       | Type                        | Required | Description                                                                                                                                                                                            |
| -------------- | --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50                | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string                      | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `status`       | one of `active`, `archived` | no       | Only active or only archived products.                                                                                                                                                                 |
| `updatedSince` | timestamp                   | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `update_product`

Change a product's name, unit label, default unit price, description, taxable, or display, or archive it (archived: true) or restore it (archived: false). Only the fields you pass change. Lines already on estimates and visits keep their prices.

|        |                  |
| ------ | ---------------- |
| Needs  | `products:write` |
| Effect | Changes data     |

| Argument           | Type                          | Required | Description                                                              |
| ------------------ | ----------------------------- | -------- | ------------------------------------------------------------------------ |
| `id`               | id                            | yes      | The object's id.                                                         |
| `name`             | string                        | no       | The product's name; unique in the workspace regardless of case.          |
| `unitLabel`        | string                        | no       | The unit it is sold in, such as `yard` or `bag`.                         |
| `defaultUnitPrice` | number 0-10000000             | no       | Default price per unit in US dollars.                                    |
| `description`      | string or null                | no       | Description shown on estimates and invoices; null clears it.             |
| `taxable`          | boolean                       | no       | Whether sales tax applies by default.                                    |
| `defaultDisplay`   | one of `itemized`, `included` | no       | How the product shows to the customer.                                   |
| `archived`         | boolean                       | no       | True archives the product so it is no longer offered; false restores it. |

### Services

#### `create_service`

Add a standard or snow service to the catalog with a name, price structure (flat, per\_sqft, per\_hour, per\_man\_hour), and rate or pricing tiers; snow services also need snow terms. Names must be unique regardless of case. Chemical services cannot be created here. Pass the same requestKey when retrying so a retry never creates a second service. If the workspace syncs with QuickBooks, the change is queued for sync.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `services:write`                                                |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument            | Type                                                  | Required | Description                                                                                                                                |
| ------------------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`              | string                                                | yes      | The service's name; unique in the workspace regardless of case.                                                                            |
| `description`       | string or null                                        | no       | Description shown on estimates and invoices; null clears it.                                                                               |
| `priceStructure`    | one of `per_hour`, `per_sqft`, `flat`, `per_man_hour` | yes      | How the price is computed: `flat` per visit, `per_sqft` by lawn area, `per_hour` per crew hour, or `per_man_hour` per person-hour on site. |
| `rate`              | number or null                                        | no       | The price in US dollars. Required unless `pricingTiers` or a snow `depthLadder` sets the price.                                            |
| `pricingTiers`      | list of object or null                                | no       | Square-footage brackets for `per_sqft` services, ascending, the last one open-ended. When set, the brackets replace `rate`.                |
| `completionMessage` | string or null                                        | no       | The message customers get when a visit of this service is completed; null or blank uses the default.                                       |
| `snow`              | object                                                | no       | Snow terms. Required for snow services and refused on standard services.                                                                   |
| `serviceType`       | one of `standard`, `snow`                             | no       | `standard` (the default) or `snow`. Chemical services are created in the app and cannot be created through the API.                        |
| `requestKey`        | string                                                | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.     |

#### `deactivate_service`

Deactivate a standard or snow service so it is no longer offered for new estimates and jobs. If open estimates or jobs that are not canceled still use it, the call is refused with the counts; confirm with the user, then pass force: true. Existing jobs keep the service. Chemical services are read-only. If the workspace syncs with QuickBooks, the change is queued for sync.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `services:write`                                                                                            |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type    | Required | Description                                                                                                                            |
| ------------ | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id      | yes      | The object's id.                                                                                                                       |
| `force`      | boolean | no       | Deactivate even when open estimates or jobs that are not canceled use the service.                                                     |
| `requestKey` | string  | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `get_service`

Get one service from the catalog by id, with its price structure, rate or pricing tiers, status, and snow terms for snow services.

|        |                 |
| ------ | --------------- |
| Needs  | `services:read` |
| Effect | Read-only       |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_services`

List the workspace's service catalog (what it sells: mowing, aeration, snow plowing, chemical applications), with prices and status. Filter by status (active or deactivated) or serviceType (standard, snow, chemical). Returns at most 50 services and a nextCursor for the next page.

|        |                 |
| ------ | --------------- |
| Needs  | `services:read` |
| Effect | Read-only       |

| Argument       | Type                                  | Required | Description                                                                                                                                                                                            |
| -------------- | ------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50                          | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string                                | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `status`       | one of `active`, `deactivated`        | no       | Only services with this status.                                                                                                                                                                        |
| `serviceType`  | one of `standard`, `snow`, `chemical` | no       | Only services of this type.                                                                                                                                                                            |
| `updatedSince` | timestamp                             | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `reactivate_service`

Reactivate a deactivated standard or snow service so it can be offered on new estimates and jobs again. Chemical services are read-only. If the workspace syncs with QuickBooks, the change is queued for sync.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `services:write`                                                |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `update_service`

Change a standard or snow service's name, description, price structure, rate, pricing tiers, completion message, or snow terms. Only the fields you pass change. Existing jobs keep their own prices. Chemical services are read-only. If the workspace syncs with QuickBooks, the change is queued for sync.

|        |                                                                 |
| ------ | --------------------------------------------------------------- |
| Needs  | `services:write`                                                |
| Effect | Changes data; can reach people or systems outside the workspace |

| Argument            | Type                                                  | Required | Description                                                                                                                                |
| ------------------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                | id                                                    | yes      | The object's id.                                                                                                                           |
| `name`              | string                                                | no       | The service's name; unique in the workspace regardless of case.                                                                            |
| `description`       | string or null                                        | no       | Description shown on estimates and invoices; null clears it.                                                                               |
| `priceStructure`    | one of `per_hour`, `per_sqft`, `flat`, `per_man_hour` | no       | How the price is computed: `flat` per visit, `per_sqft` by lawn area, `per_hour` per crew hour, or `per_man_hour` per person-hour on site. |
| `rate`              | number or null                                        | no       | The price in US dollars. Required unless `pricingTiers` or a snow `depthLadder` sets the price.                                            |
| `pricingTiers`      | list of object or null                                | no       | Square-footage brackets for `per_sqft` services, ascending, the last one open-ended. When set, the brackets replace `rate`.                |
| `completionMessage` | string or null                                        | no       | The message customers get when a visit of this service is completed; null or blank uses the default.                                       |
| `snow`              | object                                                | no       | Snow terms. Required for snow services and refused on standard services.                                                                   |

### Staff

#### `get_user`

Get one staff user (company admin or employee) by id, with name, email, role, status, and crew.

|        |              |
| ------ | ------------ |
| Needs  | `users:read` |
| Effect | Read-only    |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_users`

List the workspace's staff (company admins and employees) with name, email, role, status, and crew. Filter by role (admin or employee), status, or teamId. Customers are not users. Returns at most 50 users and a nextCursor for the next page.

|        |              |
| ------ | ------------ |
| Needs  | `users:read` |
| Effect | Read-only    |

| Argument       | Type                                   | Required | Description                                                                                                                                                                                            |
| -------------- | -------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50                           | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string                                 | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `role`         | one of `admin`, `employee`             | no       | Only users with this role.                                                                                                                                                                             |
| `status`       | one of `active`, `invited`, `inactive` | no       | Only users with this status.                                                                                                                                                                           |
| `teamId`       | id                                     | no       | Only users on this crew.                                                                                                                                                                               |
| `updatedSince` | timestamp                              | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

### Tags

#### `create_tag`

Create a tag (a label for customers) with a name up to 60 characters. Fails if a tag with the same name, ignoring case, exists; use list\_tags to find it instead.

|        |              |
| ------ | ------------ |
| Needs  | `tags:write` |
| Effect | Changes data |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `name`       | string | yes      | The tag's name, up to 60 characters. Names are unique in the workspace, ignoring case.                                                 |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `delete_tag`

Permanently delete a tag and remove it from every customer and lead wearing it. Workspace automations that start when a tag is removed may run if the token has automations:trigger. This cannot be undone; confirm with the user first.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `tags:write`                                                                                                |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_tags`

List the workspace's tags (labels attached to customers), with their ids. Use the ids with set\_customer\_tags.

|        |             |
| ------ | ----------- |
| Needs  | `tags:read` |
| Effect | Read-only   |

| Argument       | Type         | Required | Description                                                                                                                                                                                            |
| -------------- | ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `limit`        | integer 1-50 | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                        |
| `cursor`       | string       | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                              |
| `updatedSince` | timestamp    | no       | ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. |

#### `rename_tag`

Rename a tag; every customer wearing it shows the new name. Fails if another tag already has the name.

|        |              |
| ------ | ------------ |
| Needs  | `tags:write` |
| Effect | Changes data |

| Argument | Type   | Required | Description                                                                            |
| -------- | ------ | -------- | -------------------------------------------------------------------------------------- |
| `id`     | id     | yes      | The object's id.                                                                       |
| `name`   | string | yes      | The tag's name, up to 60 characters. Names are unique in the workspace, ignoring case. |

### Visits

#### `assign_visit`

Assign one scheduled visit to a crew (teamId). The visit moves to the end of that crew's route for its day; assigning the job's own crew makes the visit follow the job's crew again (a split visit's portion always keeps its crew id). Crews are notified of the route change. Pass the same requestKey when retrying.

|        |                |
| ------ | -------------- |
| Needs  | `visits:write` |
| Effect | Changes data   |

| Argument     | Type   | Required | Description                                                                                                                                                                                                                                           |
| ------------ | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                                                                                                                                      |
| `teamId`     | id     | yes      | The crew to do the visit. The visit joins the end of that crew's route for its day. Assigning the job's own crew clears the visit's own crew, so it follows the job's crew again, except on a portion of a split visit, which always stores its crew. |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                                                                                                |

#### `cancel_visit`

Cancel one open visit (and every crew's portion of a split visit); the job and its other visits are unchanged. Past-dated visits are refused. The workspace's job-canceled automations, which may email or text the customer, run only if the token has automations:trigger. This cannot be undone, so confirm with the user first. Pass the same requestKey when retrying.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `visits:write`                                                                                              |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |

#### `complete_visit`

Complete a visit as the app does. About five minutes later billing creates its invoice, queues delivery to the customer, and charges a saved card when autopay is on; the result lists those effects and finalizeAt. Read the invoice later with get\_visit (invoiceId) or list\_invoices. Only this visit unless completeStop is true. Confirm with the user first. Needs visits:complete and visits:read; without automations:trigger the completion and billing start no automation or review request (later invoice changes, such as a payment, still can). Retry with the same requestKey

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `visits:complete`, `visits:read`                                                                            |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument       | Type                              | Required | Description                                                                                                                                                                                                             |
| -------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`           | id                                | yes      | The object's id.                                                                                                                                                                                                        |
| `completeStop` | boolean or one of `true`, `false` | no       | `true` also completes the stop's other open services (same customer, date, crew, and address) as one batch, billed on one invoice, the way the crew app finishes a visit. Omitted or `false` completes only this visit. |
| `requestKey`   | string                            | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                                                                  |

#### `get_visit`

Get one visit by id: its date (YYYY-MM-DD, the workspace's timezone), status, job, customer, address, crew (effectiveTeamId), route position, and arrival and completion times.

|        |               |
| ------ | ------------- |
| Needs  | `visits:read` |
| Effect | Read-only     |

| Argument | Type | Required | Description      |
| -------- | ---- | -------- | ---------------- |
| `id`     | id   | yes      | The object's id. |

#### `list_visits`

List visits (scheduled services) with filters: from and to dates (YYYY-MM-DD, the workspace's timezone, inclusive), crew (teamId), status, customerId, or jobId. Returns at most 50 visits and a nextCursor for the next page. For one day's schedule grouped by crew, use get\_schedule instead.

|        |               |
| ------ | ------------- |
| Needs  | `visits:read` |
| Effect | Read-only     |

| Argument       | Type                                                                                                 | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------- | ---------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `limit`        | integer 1-50                                                                                         | no       | How many items to return, 1-50. Defaults to 50.                                                                                                                                                                                                                                                                                                                                                                                                       |
| `cursor`       | string                                                                                               | no       | The `meta.nextCursor` from the previous page. Omit it for the first page.                                                                                                                                                                                                                                                                                                                                                                             |
| `from`         | string                                                                                               | no       | Only visits on or after this date, `YYYY-MM-DD` in the workspace's timezone.                                                                                                                                                                                                                                                                                                                                                                          |
| `to`           | string                                                                                               | no       | Only visits on or before this date, `YYYY-MM-DD` in the workspace's timezone.                                                                                                                                                                                                                                                                                                                                                                         |
| `teamId`       | id                                                                                                   | no       | Only visits this crew is doing (the visit's own crew, or its job's crew when the visit has none).                                                                                                                                                                                                                                                                                                                                                     |
| `status`       | one of `pending`, `scheduled`, `completed`, `canceled`, `rescheduled`, `needs_reschedule`, `skipped` | no       | Only visits with this status.                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `customerId`   | id                                                                                                   | no       | Only this customer's visits.                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `jobId`        | id                                                                                                   | no       | Only this job's visits.                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `updatedSince` | timestamp                                                                                            | no       | ISO 8601 timestamp. Returns visits changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`. A visit's `updatedAt` changes only when the visit itself changes: `jobName`, `address`, `customerId`, and an inherited `effectiveTeamId` come from its job and property and do not change it, so sync jobs and properties from their own lists. |

#### `reschedule_visit`

Move a visit to a new date (YYYY-MM-DD, the workspace's timezone, today or later). scope this\_only moves just this visit; this\_and\_future deletes this and all later untouched visits of the job, creates a new series from the date, and sets the job to scheduled (clearing a pause), so confirm that with the user. Started visits cannot be moved. The workspace's job-rescheduled automations, which may email or text the customer, run only if the token has automations:trigger. Pass the same requestKey when retrying.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `visits:write`                                                                                              |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type                                  | Required | Description                                                                                                                                                                                                                                                                                                                  |
| ------------ | ------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id                                    | yes      | The object's id.                                                                                                                                                                                                                                                                                                             |
| `date`       | string                                | yes      | The new date, `YYYY-MM-DD` in the workspace's timezone; today or later.                                                                                                                                                                                                                                                      |
| `scope`      | one of `this_only`, `this_and_future` | no       | `this_only` (the default) moves this visit. `this_and_future` replaces this visit and every later visit of its job that has no history with a new series starting on `date`, as the app's "This and following" does, and sets the job to scheduled, clearing any pause; it fails if any of those visits already has history. |
| `placement`  | one of `start`, `end`                 | no       | `this_only` only: put the visit at the start or end of its crew's route that day. Omitted, the workspace setting decides (a visit carried over from an earlier day goes first, anything else last).                                                                                                                          |
| `requestKey` | string                                | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice.                                                                                                                                                                                       |

#### `skip_visit`

Skip one open visit: it is closed like a cancel, and the job's later visits stay scheduled. This action sends no message itself; automations the workspace built on visit changes run only if the token has automations:trigger. Past-dated visits are refused. This cannot be undone, so confirm with the user first. Pass the same requestKey when retrying.

|        |                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Needs  | `visits:write`                                                                                              |
| Effect | Changes data; destructive (the app would ask to confirm); can reach people or systems outside the workspace |

| Argument     | Type   | Required | Description                                                                                                                            |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | id     | yes      | The object's id.                                                                                                                       |
| `requestKey` | string | no       | Any unique string for this action, such as a UUID. Retrying with the same requestKey returns the first result instead of acting twice. |
