{"openapi":"3.0.3","info":{"title":"Workspace369 Builder API","version":"1.0.0","description":"The Workspace369 Builder API is plain HTTP access to the same tools the Workspace369 MCP server exposes, so scripts, automations and AI builders can work with clients, proposals, invoices, contracts, projects, tasks, requests and calendar events. Workspace369 (https://workspace369.com/) is an all-in-one workspace for client work. Every call runs the same permission checks, approval holds, audit and billing as MCP. Available on the Specialist plan and up. Authenticate with a personal access token (mcp_pat_...) in the Authorization header. Guide: https://docs.workspace369.com/v/2026.3/build-with-ai/call-workspace369-over-http-builder-api/","termsOfService":"https://workspace369.com/terms-of-service/","contact":{"name":"Workspace369 support","url":"https://workspace369.com/","email":"support@workspace369.com"},"x-logo":{"url":"https://workspace369.com/favicon/android-chrome-512x512.png","altText":"Workspace369"}},"externalDocs":{"description":"Call Workspace369 over HTTP (Builder API) guide","url":"https://docs.workspace369.com/v/2026.3/build-with-ai/call-workspace369-over-http-builder-api/"},"servers":[{"url":"https://mcp.workspace369.com","description":"Production"}],"tags":[{"name":"tools","description":"Every external tool as POST /v1/tools/{name}, with the full input schema."},{"name":"clients","description":"Search, read, create and update clients."},{"name":"proposals","description":"Search, read, draft, update and send proposals."},{"name":"invoices","description":"Search, read, draft, update and send invoices."},{"name":"contracts","description":"Search, read, draft and send contracts."},{"name":"projects","description":"Search, read, create and update projects."},{"name":"tasks","description":"Search, read, create and update tasks."},{"name":"requests","description":"Search, read, create and update client requests."},{"name":"calendar","description":"Search, read and create calendar events."}],"security":[{"bearerAuth":[]}],"paths":{"/v1/tools/workspace_get_context":{"post":{"operationId":"workspace_get_context","summary":"Get workspace context","description":"Return the current workspace (`workspace`: id, name, plan), the caller's `permissions` and their `token_balance`. Call it first to confirm which workspace the connection is on and what the caller may do; then use workspace_schema for the data model and workspace_business_summary for headline counts. Read-only; takes no arguments.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"workspace:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"workspace":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"plan":{"type":"string"}},"required":["id","name","plan"],"additionalProperties":false},"permissions":{"type":"array","items":{"type":"string"}},"token_balance":{"type":"number","nullable":true},"google":{"type":"string","enum":["connected","needs_reconnect","not_connected"]}},"required":["workspace","permissions"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/workspace_schema":{"post":{"operationId":"workspace_schema","summary":"Get workspace data model","description":"Describe the record types you can work with through this server (clients, requests, proposals, contracts, invoices, projects, tasks, calendar events, products): the tools that read and write each, the fields their create tool accepts, and this workspace's client stages, client custom field definitions, calendar categories and lead sources (definitions only, never record values). Call it after workspace_get_context and before building screens. For task statuses and custom fields use task_board_schema.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"workspace:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"record_types":{"type":"array","items":{"type":"string","enum":["clients","requests","proposals","contracts","invoices","projects","tasks","calendar_events","products"]},"maxItems":9,"description":"Limit the answer to these record types. Omit for all of them."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"workspace_id":{"type":"string"},"record_types":{"type":"array","items":{"type":"object","additionalProperties":{}}},"notes":{"type":"array","items":{"type":"string"}}},"required":["workspace_id","record_types","notes"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/clients_search":{"post":{"operationId":"clients_search","summary":"Search clients","description":"List clients in the workspace, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `query` matches name, email or company. `lead_source`, `client_type`, `stage` (a pipeline stage id or name) and `tags` (matches any) are applied after the page is cut, so a filtered page can be short while more matches exist; keep following `nextCursor`. Archived clients are excluded. Scoped members see only their assigned clients.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"clients:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches name, email or company."},"lead_source":{"type":"string","description":"Only clients with this lead source."},"client_type":{"type":"string","enum":["business","individual"],"description":"Only business or individual clients."},"stage":{"type":"string","description":"Only clients in this pipeline stage (id or name, see workspace_schema clients.stages)."},"tags":{"type":"array","items":{"type":"string"},"description":"Only clients having any of these tags."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"clients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"},"address":{"type":"string"},"client_type":{"type":"string"},"lead_source":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"lifecycle_stage":{"type":"string"},"stage_id":{"type":"string"},"archived":{"type":"boolean"},"email_opted_out":{"type":"boolean"},"sms_opted_out":{"type":"boolean"},"blacklisted":{"type":"boolean"},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}},"custom_fields_unavailable":{"type":"boolean"}},"required":["id","name"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["clients"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/clients_get":{"post":{"operationId":"clients_get","summary":"Get a client","description":"Fetch one client by id, with its `custom_fields` values (key to value). Returns `{ client: null }` if it does not exist or is outside a scoped member's assigned clients. Archived clients are returned with `archived: true`. Read-only. Find ids with clients_search; change a client with clients_update.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"clients:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Client id (from clients_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"},"address":{"type":"string"},"client_type":{"type":"string"},"lead_source":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"lifecycle_stage":{"type":"string"},"stage_id":{"type":"string"},"archived":{"type":"boolean"},"email_opted_out":{"type":"boolean"},"sms_opted_out":{"type":"boolean"},"blacklisted":{"type":"boolean"},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}},"custom_fields_unavailable":{"type":"boolean"}},"required":["id","name"],"additionalProperties":false,"nullable":true}},"required":["client"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/clients_create":{"post":{"operationId":"clients_create","summary":"Create a client","description":"Create a client, or a prospect when `lifecycle_stage` is \"prospect\". A name is required: `name`, `first_name`/`last_name`, or `company`. `client_type` defaults to business for a company-only client, otherwise individual. Phone numbers are stored as E.164: give the country code; a 10-digit number is read as US/Canada and an unreadable number is refused. Use `addresses` for several addresses (exactly one is primary; the first if none is flagged), or the flat address fields for one. Addresses are checked against Google Places: an agreeing match is stored geocoded, anything else is stored as written and reported as unverified. Scoped members' new clients are assigned to them. `custom_fields` ({key: value}) is validated against the workspace's definitions; an unknown field or a bad value refuses the create. A repeat call with the same `idempotency_key` returns the first client (`deduped: true`).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"clients:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Full name; for a person this alone is enough."},"first_name":{"type":"string","description":"First name."},"last_name":{"type":"string","description":"Last name."},"email":{"type":"string","description":"Primary email address."},"phone":{"type":"string","description":"Primary phone, with country code (e.g. +44 20 7123 4567); a 10-digit number is read as US/Canada."},"company":{"type":"string","description":"Company name."},"address":{"type":"string","description":"Street address line (single-address shorthand)."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"client_type":{"type":"string","enum":["business","individual"],"description":"business or individual; defaults to business for a company-only client."},"lifecycle_stage":{"type":"string","enum":["client","prospect"],"description":"\"prospect\" creates a lead listed under Prospects; \"client\" (default) a client."},"lead_source":{"type":"string","description":"Where the client came from, matched against the workspace's lead sources (lead_sources_list); defaults to the workspace default."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."},"property":{"type":"string","description":"Unit or suite, for the single-address shorthand."},"country":{"type":"string","description":"Country, for the single-address shorthand."},"addresses":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","description":"Street line."},"property":{"type":"string","description":"Unit or suite."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"country":{"type":"string","description":"Country."},"place_id":{"type":"string","description":"Google Places id, if you already hold one."},"label":{"type":"string","description":"Label such as Home or Office."},"is_primary":{"type":"boolean","description":"Mark as the primary address."}},"additionalProperties":false},"maxItems":20,"description":"Several addresses (max 20); wins over the flat address fields. Exactly one ends up primary."},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"enum":["null"]}]},"description":"Custom field values as {key: value}, using the keys (or labels) from workspace_schema clients.custom_field_definitions. Values are checked against each field's type (text, number, boolean, date YYYY-MM-DD, select option); an unknown field or a bad value is refused."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["client","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/clients_update":{"post":{"operationId":"clients_update","summary":"Update a client","description":"Update a client by `id`. Only the fields passed change. `lifecycle_stage` \"client\" promotes a prospect, \"prospect\" demotes. `phone: \"\"` removes the primary phone. Email, phone and single-address updates replace only the primary entry and keep the others; `addresses` replaces the whole address list (the only way to remove or reorder one) and goes through the same Google Places check as on create. `custom_fields` ({key: value}, validated against the workspace's definitions; null clears a value) merges into the client's existing values. Returns the merged client, or an error if the client does not exist or is outside a scoped member's assigned clients.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"clients:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Client id (from clients_search)."},"name":{"type":"string","minLength":1,"description":"Full name."},"first_name":{"type":"string","description":"First name."},"last_name":{"type":"string","description":"Last name."},"email":{"type":"string","description":"Replaces the primary email."},"phone":{"type":"string","description":"Replaces the primary phone, with country code; \"\" removes it."},"company":{"type":"string","description":"Company name."},"address":{"type":"string","description":"Street address line (replaces the primary address)."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"client_type":{"type":"string","enum":["business","individual"],"description":"business or individual."},"lifecycle_stage":{"type":"string","enum":["client","prospect"],"description":"\"client\" promotes a prospect; \"prospect\" demotes a client."},"lead_source":{"type":"string","description":"Where the client came from, matched against the workspace's lead sources."},"property":{"type":"string","description":"Unit or suite, for the single-address shorthand."},"country":{"type":"string","description":"Country, for the single-address shorthand."},"addresses":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","description":"Street line."},"property":{"type":"string","description":"Unit or suite."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"country":{"type":"string","description":"Country."},"place_id":{"type":"string","description":"Google Places id, if you already hold one."},"label":{"type":"string","description":"Label such as Home or Office."},"is_primary":{"type":"boolean","description":"Mark as the primary address."}},"additionalProperties":false},"maxItems":20,"description":"Replaces the client's whole address list (max 20)."},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"enum":["null"]}]},"description":"Custom field values as {key: value}, using the keys (or labels) from workspace_schema clients.custom_field_definitions. Values are checked against each field's type (text, number, boolean, date YYYY-MM-DD, select option); an unknown field or a bad value is refused. null or \"\" clears a value."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["client"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/clients_move_stage":{"post":{"operationId":"clients_move_stage","summary":"Move a client to a stage","description":"Move a client to another stage of the workspace's client pipeline, by stage id or name (see workspace_schema clients.stages). A lead-group stage makes it a prospect; any other stage makes it a client. Moving to the stage it is already in changes nothing. Archived and out-of-scope clients are refused.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"clients:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Client id (from clients_search)."},"stage":{"type":"string","minLength":1,"description":"Target stage: its id or name, as listed by workspace_schema (clients.stages)."}},"required":["id","stage"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"stage_id":{"type":"string"},"stage":{"type":"string"},"lifecycle_stage":{"type":"string"}},"required":["id","name","stage_id","stage","lifecycle_stage"],"additionalProperties":false},"previous_stage_id":{"type":"string"},"moved":{"type":"boolean"}},"required":["client","previous_stage_id","moved"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/notes_search":{"post":{"operationId":"notes_search","summary":"Search notes","description":"List notes, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `scope` \"workspace\" (default) returns workspace and client notes; \"personal\" returns the caller's own personal notes. Filters: `query` (title/preview), `folder_id`, `tag` (case-insensitive substring), `client_id` (notes attached to that client). Filters apply after the page is cut, so keep following `nextCursor`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"notes:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches title and preview."},"scope":{"type":"string","enum":["workspace","personal"],"description":"workspace (default): workspace and client notes; personal: the caller's own notes."},"folder_id":{"type":"string","description":"Only notes in this folder."},"tag":{"type":"string","description":"Only notes whose tags contain this text (case-insensitive)."},"client_id":{"type":"string","description":"Only notes attached to this client."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"notes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"preview":{"type":"string"},"visibility":{"type":"string"},"folderId":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"number"},"clientIds":{"type":"array","items":{"type":"string"}}},"required":["id","title"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["notes"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/notes_get":{"post":{"operationId":"notes_get","summary":"Get a note","description":"Fetch one note by id. Returns `{ note: null }` if it does not exist, is trashed, or is outside this workspace (another workspace or a user's personal notes). Read-only. Find ids with notes_search; edit with notes_update.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"notes:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Note id (from notes_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"preview":{"type":"string"},"visibility":{"type":"string"},"folderId":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"number"},"clientIds":{"type":"array","items":{"type":"string"}}},"required":["id","title"],"additionalProperties":false,"nullable":true}},"required":["note"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/notes_create":{"post":{"operationId":"notes_create","summary":"Create a note","description":"Create a note. `body` accepts simple markdown (headings, `- ` and `1. ` lists, bold, italic, underline, strikethrough, links), which becomes the editor's formatting. By default the note is a workspace note visible to the team; `is_personal: true` makes it private to the caller. `client_ids` takes ONE client id and writes the note into that client's Notes tab (needs permission to edit clients; it is then not in the workspace Notes screen). `folder_id` must be a folder in the target space; without it the note goes to that space's default folder. A repeat call with the same `idempotency_key` returns the first note (`deduped: true`).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"notes:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"Note title."},"body":{"type":"string","description":"Note text; simple markdown becomes the editor's formatting."},"folder_id":{"type":"string","description":"Folder in the target space; omit for its default notes folder."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the note."},"is_personal":{"type":"boolean","description":"true: a private note only the caller sees; default is a workspace note."},"client_ids":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Exactly one client id: writes the note into that client's Notes tab."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["title"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"folder_id":{"type":"string"}},"required":["id","title","folder_id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["note","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_search":{"post":{"operationId":"invoices_search","summary":"Search invoices","description":"List invoices, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Proposals and estimates are excluded (use proposals_search). `query` matches number, title, client name or PO number; `number` looks up one invoice by its human number (e.g. '26-6') and returns its `id`. Archived invoices are excluded unless `include_archived` is true. There is no 'Overdue' status; use each row's `is_overdue`, `due_date` and `balance_due`. `total` and `balance_due` are null without the invoices.view_prices permission. Scoped members see only their assigned clients.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches invoice number, title, client name or PO number."},"status":{"type":"string","description":"Exact stored invoice status, case-insensitive (e.g. Draft, Pending, Paid). Overdue is not a status."},"clientId":{"type":"string","description":"Only this client's invoices."},"number":{"type":"string","description":"Human invoice number (e.g. '26-6'); returns that invoice and its `id`."},"include_archived":{"type":"boolean","description":"Include archived invoices (excluded by default)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"title":{"type":"string"},"total":{"type":"number","nullable":true},"currency":{"type":"string"},"invoice_date":{"type":"number"},"due_date":{"type":"number"},"balance_due":{"type":"number","nullable":true},"is_paid":{"type":"boolean"},"is_overdue":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["invoices"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_get":{"post":{"operationId":"invoices_get","summary":"Get an invoice","description":"Fetch one invoice by `id` or by `invoice_number` (e.g. '26-6'). Returns `{ invoice: null }` if it does not exist, is a proposal/estimate, or is outside a scoped member's clients; if two invoices share a number it refuses and asks for the `id`. Includes `line_items` (up to 100, each with the `line_number` that invoices_update_draft's `update_services` addresses by position) and the true `line_item_count`. `content_locked` / `content_lock_reason` show whether the invoice is locked by a recorded payment or credit (its items and prices then change only through a change order in the app); `change_orders_pending` counts change orders awaiting the client. Monetary fields are null without the invoices.view_prices permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Invoice document id. Pass this or `invoice_number`."},"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'. Pass this or `id`."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"title":{"type":"string"},"total":{"type":"number","nullable":true},"currency":{"type":"string"},"invoice_date":{"type":"number"},"due_date":{"type":"number"},"balance_due":{"type":"number","nullable":true},"is_paid":{"type":"boolean"},"is_overdue":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"},"line_items":{"type":"array","items":{"type":"object","properties":{"line_number":{"type":"number"},"name":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"product_id":{"type":"string"}},"required":["line_number","name","quantity","unit_price","total"],"additionalProperties":false}},"line_item_count":{"type":"number"},"public_link":{"type":"string"}},"required":["id"],"additionalProperties":false,"nullable":true}},"required":["invoice"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_create_draft":{"post":{"operationId":"invoices_create_draft","summary":"Create a draft invoice","description":"Create a draft invoice for a client. It is saved as a draft and never sent. Needs `client_id` and at least one line item: `{product_id, quantity}` (catalogue product; `unit_price` overrides its price) or `{description, unit_price, quantity}` (one-off). `unit_price` is the price of one unit; line totals are computed. `details` is the line's printed description and accepts simple markdown. A draft without a `title` is named \"Invoice for <client>\". The number comes from the workspace's invoice sequence (`number` sets one explicitly). `due_in_days` (0 = due on receipt) or `due_date` (MM/DD/YYYY) set the due date; `payment_term` is the printed label only. Tax is `tax_percent` or `tax_amount`, discount is `discount_percent` or `discount_amount` (not both of either); tax applies after the discount. `notes` prints on the invoice. The workspace's Invoice Defaults (due terms, tax, discount, deposit, notes) apply unless `apply_workspace_defaults` is false, and explicit values override them (see invoices_get_defaults). The invoice inherits its visibility from the client. A repeat call with the same `idempotency_key` returns the first invoice (`deduped: true`).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"client_id":{"type":"string","minLength":1,"description":"Client the invoice is for; must belong to this workspace."},"line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."}},"additionalProperties":false},"minItems":1,"description":"Invoice lines: {product_id, quantity} or {description, unit_price, quantity}."},"currency":{"type":"string","description":"Currency code; defaults to the workspace currency."},"title":{"type":"string","description":"Short title naming the work; without it the draft is called \"Invoice for <client>\"."},"number":{"type":"string","description":"Explicit invoice number; omit to use the workspace sequence."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."},"timezone":{"type":"string","maxLength":64,"description":"IANA time zone that decides which day \"today\" is for the dates."},"invoice_date":{"type":"string","minLength":1,"maxLength":10,"description":"Issue date, MM/DD/YYYY; defaults to today on create."},"due_date":{"type":"string","minLength":1,"maxLength":10,"description":"Due date, MM/DD/YYYY. Use this or `due_in_days`."},"due_in_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days from the issue date until due; 0 = due on receipt."},"payment_term":{"type":"string","maxLength":120,"description":"Printed term label (e.g. \"Net 30\"); does not compute the due date."},"tax_percent":{"type":"number","minimum":0,"maximum":100,"description":"Tax as a percentage of the post-discount subtotal. Use this or `tax_amount`."},"tax_amount":{"type":"number","minimum":0,"description":"Tax as a fixed amount. Use this or `tax_percent`."},"deposit_percent":{"type":"number","minimum":0,"maximum":100,"description":"Request a deposit of this percentage of the total; 0 disables it."},"apply_workspace_defaults":{"type":"boolean","description":"Apply the workspace's Invoice Defaults (default true); explicit values override them."},"notes":{"type":"string","maxLength":5000,"description":"Notes printed on the invoice."},"discount_percent":{"type":"number","minimum":0,"maximum":100,"description":"Discount as a percentage of the subtotal. Use this or `discount_amount`."},"discount_amount":{"type":"number","minimum":0,"description":"Discount as a fixed amount. Use this or `discount_percent`."},"project_id":{"type":"string","minLength":1,"maxLength":200,"description":"Link the invoice to a project for job costing."}},"required":["client_id","line_items"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"total":{"type":"number","nullable":true},"invoice_date":{"type":"string"},"due_date":{"type":"string"},"project_id":{"type":"string"}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["invoice","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_send":{"post":{"operationId":"invoices_send","summary":"Send an invoice","description":"Send an invoice to its client by email or SMS, as the app's Send email sheet does. Identify it by `invoice_id` or `invoice_number` (e.g. '26-6'). `channel` is 'email' (default) or 'sms'; the recipient defaults to the client's email or phone. `to`, `cc` and `bcc` must be saved on the invoice's client or its contacts, or be a team member or the workspace; others are refused. Email uses the workspace's email settings and invoice template, with the invoice button and PDF attached; `template` (see email_send_options) replaces the template, and `subject` and `message` override its subject and body. If `from_inbox` is omitted, the workspace's AI & MCP inbox is used, else the only inbox the user can send from; with several and no default, nothing is sent and the result lists them. `cc`/`bcc` replace the default copies. At most 10 recipients per email from a starter inbox and 50 from the user's own domain or mailbox (To + Cc + Bcc, workspace addresses excluded); over the cap nothing is sent. SMS texts the invoice link, with `message` as a note. Refuses when the invoice has no link yet. Sends a real message and bills for it. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string","minLength":1,"description":"Invoice document id (from invoices_search). Pass this or invoice_number."},"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6' (from invoices_search). Pass this or invoice_id."},"channel":{"type":"string","enum":["email","sms"],"description":"email (default) or sms. Email goes through the sending inbox; SMS texts the invoice link."},"to":{"type":"string","description":"Recipient: an email address (channel email) or phone number (channel sms). Defaults to the client's email or phone."},"message":{"type":"string","description":"Email: the whole body, replacing the template's. SMS: a note in the text. Markdown: `# ` / `## ` / `### ` start a large / medium / small heading; `- ` or `1. ` starts a bullet or numbered item; inline `**bold**`, `*italic*`, `<u>underline</u>`, `~~strikethrough~~`, `[text](https://…)` links and `![alt](https://…)` images. Text without these markers goes out as plain paragraphs. Merge fields like `{{client.first_name}}`, `{{workspace.name}}` and `{{sender.name}}` are filled in."},"subject":{"type":"string","description":"Email only. Replaces the template's or default subject."},"template":{"type":"string","description":"Email only. A library template, by id or name, used instead of the default invoice template."},"from_inbox":{"type":"string","description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"cc":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Cc addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"bcc":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Bcc addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"channel":{"type":"string","enum":["email","sms"]},"to":{"type":"string"},"message_id":{"type":"string"},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"},"cc":{"type":"array","items":{"type":"string"}},"bcc":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"conversation_id":{"type":"string"},"body_source":{"type":"string","enum":["message","template","default"]},"template_id":{"type":"string"}},"required":["sent","channel","to","message_id"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_search":{"post":{"operationId":"proposals_search","summary":"Search proposals","description":"List proposals and estimates, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Invoices are excluded (use invoices_search). `query` matches title, number or client name; archived proposals are excluded unless `include_archived` is true. Each row carries `sent_at`, `viewed_at`, `view_count`, `accepted_at`, `declined_at` and a derived `opened_by_client`; these, not `status`, show whether the client has seen it. `total` is null without the invoices.view_prices permission. Scoped members see only their assigned clients.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches title, number or client name."},"status":{"type":"string","description":"Exact stored proposal status, case-insensitive."},"clientId":{"type":"string","description":"Only this client's proposals."},"include_archived":{"type":"boolean","description":"Include archived proposals (excluded by default)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"total":{"type":"number","nullable":true},"sub_total":{"type":"number","nullable":true},"discount_amount":{"type":"number","nullable":true},"tax_amount":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"sent_at":{"type":"number"},"viewed_at":{"type":"number"},"view_count":{"type":"number"},"accepted_at":{"type":"number"},"declined_at":{"type":"number"},"opened_by_client":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"},"line_items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"optional":{"type":"boolean"},"group":{"type":"string"},"product_id":{"type":"string"}},"required":["name","quantity","unit_price","total"],"additionalProperties":false}},"line_item_count":{"type":"number"},"public_link":{"type":"string"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["proposals"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_get":{"post":{"operationId":"proposals_get","summary":"Get a proposal","description":"Fetch one proposal or estimate by id. Returns `{ proposal: null }` if it does not exist, is an invoice, or is outside a scoped member's clients. Includes line items (name, quantity, rate, total, whether client-selectable), `design` (theme, colours, cover, title placement) and `sections` (ids, types, titles, text, images, highlights); change them with proposals_update_design and proposals_edit_sections. `content_locked` / `content_lock_reason` show whether it is locked (accepted, or deposit paid) and so changes only through a change order in the app; `change_orders_pending` counts change orders awaiting the client. `total` is null without the invoices.view_prices permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Proposal id (from proposals_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"total":{"type":"number","nullable":true},"sub_total":{"type":"number","nullable":true},"discount_amount":{"type":"number","nullable":true},"tax_amount":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"sent_at":{"type":"number"},"viewed_at":{"type":"number"},"view_count":{"type":"number"},"accepted_at":{"type":"number"},"declined_at":{"type":"number"},"opened_by_client":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"},"line_items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"optional":{"type":"boolean"},"group":{"type":"string"},"product_id":{"type":"string"}},"required":["name","quantity","unit_price","total"],"additionalProperties":false}},"line_item_count":{"type":"number"},"public_link":{"type":"string"},"design":{"type":"object","properties":{"theme":{"type":"string"},"accent_color":{"type":"string"},"page_background_color":{"type":"string"},"title_placement":{"type":"string"},"cover_image":{"type":"object","properties":{"url":{"type":"string"},"path":{"type":"string"},"source":{"type":"string"},"banner_id":{"type":"string"},"gallery_path":{"type":"string"},"storage_path":{"type":"string"}},"required":["url","path"],"additionalProperties":false,"nullable":true},"cover_image_style":{"type":"string"},"cover_focal_point":{"type":"number"}},"required":["theme","accent_color","page_background_color","title_placement","cover_image","cover_image_style","cover_focal_point"],"additionalProperties":false},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"structural":{"type":"boolean"},"title":{"type":"string","nullable":true},"highlighted":{"type":"boolean"},"body":{"type":"string"},"image_layout":{"type":"string"},"images":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"caption":{"type":"string"},"alt":{"type":"string"},"source":{"type":"string"},"banner_id":{"type":"string"},"gallery_path":{"type":"string"},"storage_path":{"type":"string"}},"required":["url","caption"],"additionalProperties":false}},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"description":{"type":"string"}},"required":["date","description"],"additionalProperties":false}},"terms_id":{"type":"string"}},"required":["id","type","structural","title","highlighted"],"additionalProperties":false}}},"required":["id","design","sections"],"additionalProperties":false,"nullable":true}},"required":["proposal"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_create_draft":{"post":{"operationId":"proposals_create_draft","summary":"Create a draft proposal","description":"Create a draft proposal for a client. It is saved as a draft and never sent. Needs `client_id` and `title`; numbered from the workspace's proposal sequence (PROP-NNN). `template_id` (see proposal_templates_list) starts from a saved template's sections, design, settings, line items and notes instead of the workspace defaults. Each `line_items` entry is `{product_id, quantity}` (catalogue product; name and price read server-side) or `{description, unit_price, quantity}` (one-off), where `unit_price` is the price of one unit; without line items the proposal quotes zero. `optional: true` marks a client-selectable add-on (only on `product_id` lines). `details` is a line's printed description and `body` seeds one text section; both accept simple markdown. `notes` is internal and not shown to the client. Totals and tax are computed. A discount cannot be set here; use proposals_update_draft. Signature, deposit and validity terms come from the proposal defaults (proposals_get_defaults). The proposal inherits its visibility from the client. A repeat call with the same `idempotency_key` returns the first proposal (`deduped: true`).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"client_id":{"type":"string","minLength":1,"description":"Client the proposal is for; must belong to this workspace."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Proposal title."},"body":{"type":"string","maxLength":20000,"description":"Text seeded into one text section."},"line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."},"optional":{"type":"boolean","description":"true: a client-selectable add-on on the public page; use only on `product_id` lines."},"group":{"type":"string","maxLength":80,"description":"Group label; adjacent lines sharing one render under a header."}},"additionalProperties":false},"maxItems":100,"description":"Priced lines: {product_id, quantity} or {description, unit_price, quantity}; `optional: true` marks a client-selectable add-on."},"currency":{"type":"string","maxLength":8,"description":"Currency code; defaults to the workspace currency."},"notes":{"type":"string","maxLength":5000,"description":"Internal notes; not shown to the client."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."},"template_id":{"type":"string","maxLength":100,"description":"Proposal template to start from (proposal_templates_list)."}},"required":["client_id","title"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"number":{"type":"string"},"sub_total":{"type":"number"},"total":{"type":"number"},"currency":{"type":"string"},"line_item_count":{"type":"number"},"requires_signature":{"type":"boolean"},"requires_deposit":{"type":"boolean"},"deposit_amount":{"type":"number"},"valid_until":{"type":"number","nullable":true}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["proposal","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_send":{"post":{"operationId":"proposals_send","summary":"Send a proposal","description":"Send a proposal to its client. Enqueues the send; the proposals worker mints the client link, marks the proposal sent and emails the client with the workspace's proposal email template. Requires `proposal_id`. Invoices or estimates, missing ids and proposals outside a scoped member's clients return 'not found' and nothing is sent. If `from_inbox` is omitted, the workspace's AI & MCP inbox is used, else the only inbox the user can send from; with several and no default, nothing is sent and the result lists them. The email goes to the client alone, so there is no Cc/Bcc to set. At most 10 recipients per email from a starter inbox and 50 from the user's own domain or mailbox (To + Cc + Bcc, workspace addresses excluded); over the cap nothing is sent. The result names the inbox and recipient. A repeat call with the same `idempotency_key` collapses onto one send. Sends a real email and bills for it. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","minLength":1,"description":"The proposal's id. Invoices and estimates are not accepted."},"from_inbox":{"type":"string","description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["proposal_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"proposal_id":{"type":"string"},"message_id":{"type":"string"},"to":{"type":"string"},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"}},"required":["sent","proposal_id","message_id"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/projects_search":{"post":{"operationId":"projects_search","summary":"Search projects","description":"List projects, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `query` matches name or client id; `status` and `clientId` narrow the results. Scoped members see only their assigned clients' projects. To read one in full use projects_get.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"projects:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches name or client id."},"status":{"type":"string","description":"Only projects with this stored status."},"clientId":{"type":"string","description":"Only this client's projects."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["projects"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/projects_get":{"post":{"operationId":"projects_get","summary":"Get a project","description":"Fetch one project by id. Returns `{ project: null }` if it does not exist or is outside a scoped member's assigned clients. Read-only. Find ids with projects_search; edit with projects_update.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"projects:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Project id (from projects_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false,"nullable":true}},"required":["project"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/projects_create":{"post":{"operationId":"projects_create","summary":"Create a project","description":"Create a project. Needs `project_name`. `status` is planning, in_progress, on_hold, completed or cancelled (display names like \"In Progress\" are accepted). `priority` is low, medium, high or critical. `start_date`/`end_date` are ISO-8601; a date-only value is that day in the workspace time zone. With a `client_id` the project inherits that client's visibility; a client-less project is visible to full members only. A repeat call with the same `idempotency_key` returns the first project (`deduped: true`). To change one use projects_update; to find one, projects_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"projects:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"project_name":{"type":"string","minLength":1,"description":"Project name."},"status":{"type":"string","description":"planning, in_progress, on_hold, completed or cancelled (display names like \"In Progress\" are accepted)."},"client_id":{"type":"string","description":"Client the project belongs to; the project inherits its visibility."},"description":{"type":"string","description":"Project description."},"start_date":{"type":"string","description":"ISO-8601 start; a date-only value is that day in the workspace time zone."},"end_date":{"type":"string","description":"ISO-8601 end; a date-only value is that day in the workspace time zone."},"budget":{"type":"number","minimum":0,"description":"Project budget."},"priority":{"type":"string","enum":["low","medium","high","critical"],"description":"low, medium, high or critical."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the project."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["project_name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["project","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_search":{"post":{"operationId":"tasks_search","summary":"Search tasks","description":"List tasks across the workspace's boards, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Filters: `query` (title), `boardId` (from task_boards_list), `status` (names normalized, `todo` matches `To-do`), `priority` (1 low, 2 medium, 3 high), `assignee_id` (a member id), `due_before` / `due_after` (ISO-8601 dates), `tags` (matches any) and `is_starred`. Overdue work is `assignee_id` with a `due_before` of now. Filters apply after the page is cut, so a filtered page can be short; keep following `nextCursor`. Rows carry an 80-character description preview; `include_full_descriptions: true` returns complete descriptions. Scoped members see only tasks on boards they can access.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches task titles."},"boardId":{"type":"string","description":"Only tasks on this board (task_boards_list)."},"status":{"type":"string","description":"Board status name; names are normalized (`todo` matches `To-do`)."},"priority":{"type":"integer","minimum":1,"maximum":3,"description":"1 low, 2 medium, 3 high."},"assignee_id":{"type":"string","description":"Workspace member id of the assignee."},"due_before":{"type":"string","description":"Only tasks due before this ISO-8601 date."},"due_after":{"type":"string","description":"Only tasks due after this ISO-8601 date."},"tags":{"type":"array","items":{"type":"string"},"description":"Only tasks having any of these tags."},"is_starred":{"type":"boolean","description":"true: only starred tasks."},"include_full_descriptions":{"type":"boolean","description":"Return complete descriptions instead of an 80-character preview."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"},"client_id":{"type":"string"},"priority":{"type":"number"},"due_date":{"type":"number"},"tags":{"type":"array","items":{"type":"string"}},"description":{"type":"string"},"assignees":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"is_starred":{"type":"boolean"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["tasks"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_create":{"post":{"operationId":"tasks_create","summary":"Create a task","description":"Create ONE task on a board. Needs `board_id` (from task_boards_list) and `title`. `status` is validated against the board's statuses (names normalized) and defaults to the board default; `priority` is 1 low, 2 medium, 3 high. `assignees` are workspace member ids. `subtasks` are checklist titles created with the task. `custom_fields` is `[{field, value}]` using the field ids, types and dropdown options from task_board_schema (dates ISO 8601, checkboxes true/false, numbers numeric). `start_date` and `due_date` are epoch milliseconds or null; `blocked_by` lists ids of tasks on the same board that must finish first. A task whose exact title (case- and whitespace-insensitive) already exists on the board is skipped and returned with `deduped: true`. `description` is plain text (markdown renders literally). Scoped members can create only on boards they can access. A repeat call with the same `idempotency_key` returns the first task.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board to create the task on (task_boards_list)."},"title":{"type":"string","minLength":1,"description":"Task title."},"status":{"type":"string","description":"Board status name; defaults to the board default."},"description":{"type":"string","description":"Plain-text description (markdown renders literally)."},"priority":{"type":"integer","minimum":1,"maximum":3,"description":"1 low, 2 medium, 3 high."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the task; on update this replaces the list."},"assignees":{"type":"array","items":{"type":"string","minLength":1},"description":"Workspace member ids; on update this replaces the list ([] clears)."},"is_starred":{"type":"boolean","description":"Whether the task is starred."},"custom_fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"description":"Custom field id or unique name (task_board_schema)."},"value":{"type":"string","description":"The value as text; numbers and booleans are accepted and coerced per the field type (dates ISO 8601)."}},"required":["field","value"],"additionalProperties":false},"description":"Custom field values as [{field, value}], using field ids and types from task_board_schema; on update they are merged into the stored values."},"estimated_hours":{"type":"number","minimum":0,"description":"Estimated hours."},"subtasks":{"type":"array","items":{"type":"string","minLength":1},"maxItems":100,"description":"Checklist titles created with the task."},"due_date":{"type":"integer","minimum":0,"nullable":true,"description":"Due date, epoch milliseconds; null means none (on update, clears it)."},"start_date":{"type":"integer","minimum":0,"nullable":true,"description":"Start date, epoch milliseconds; null means none (on update, clears it)."},"is_milestone":{"type":"boolean","description":"Show the task as a milestone on the Gantt chart."},"blocked_by":{"type":"array","items":{"type":"string","minLength":1},"description":"Ids of tasks on the same board that must finish first; on update this replaces the list."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["board_id","title"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"}},"required":["id","board_id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["task","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_update":{"post":{"operationId":"tasks_update","summary":"Update a task","description":"Update a task by `id` on its `board_id`. Only the fields passed change. `title`, `status` (validated against the board's statuses), `description` (null clears), `priority` (1-3), `estimated_hours` (null clears) and `is_starred` are replaced as given. `tags`, `assignees` and `blocked_by` REPLACE the stored list ([] clears). `custom_fields` ([{field, value}], using ids from task_board_schema) is merged into the stored values; `clear_custom_fields` lists field ids or unique names to remove (a required field cannot be cleared). `start_date`/`due_date` are epoch milliseconds (null clears). A blocker must be an existing task on the same board, and an edge that would create a dependency cycle is rejected. Subtask changes go through tasks_subtasks_update. Returns the merged task, or an error if the task does not exist or is on a board outside a scoped member's access.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Task id (from tasks_search)."},"board_id":{"type":"string","minLength":1,"description":"Board the task is on."},"title":{"type":"string","minLength":1,"description":"New title."},"status":{"type":"string","description":"Board status name."},"description":{"type":"string","nullable":true,"description":"New description (null clears it)."},"priority":{"type":"integer","minimum":1,"maximum":3,"description":"1 low, 2 medium, 3 high."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the task; on update this replaces the list."},"assignees":{"type":"array","items":{"type":"string","minLength":1},"description":"Workspace member ids; on update this replaces the list ([] clears)."},"is_starred":{"type":"boolean","description":"Whether the task is starred."},"custom_fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"description":"Custom field id or unique name (task_board_schema)."},"value":{"type":"string","description":"The value as text; numbers and booleans are accepted and coerced per the field type (dates ISO 8601)."}},"required":["field","value"],"additionalProperties":false},"description":"Custom field values as [{field, value}], using field ids and types from task_board_schema; on update they are merged into the stored values."},"estimated_hours":{"type":"number","minimum":0,"nullable":true,"description":"Estimated hours (null clears)."},"clear_custom_fields":{"type":"array","items":{"type":"string","minLength":1},"description":"Field ids or unique names to remove; a required field cannot be cleared."},"due_date":{"type":"integer","minimum":0,"nullable":true,"description":"Due date, epoch milliseconds; null means none (on update, clears it)."},"start_date":{"type":"integer","minimum":0,"nullable":true,"description":"Start date, epoch milliseconds; null means none (on update, clears it)."},"is_milestone":{"type":"boolean","description":"Show the task as a milestone on the Gantt chart."},"blocked_by":{"type":"array","items":{"type":"string","minLength":1},"description":"Ids of tasks on the same board that must finish first; on update this replaces the list."}},"required":["id","board_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"}},"required":["id","board_id"],"additionalProperties":false}},"required":["task"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_comments_list":{"post":{"operationId":"tasks_comments_list","summary":"Read a task's comments","description":"List the comments on a task, newest first, with author and time. Takes `board_id` and `task_id` from tasks_search. Attachments are reported as a count, not urls. Read-only. Returns `comments`; add one with tasks_comment_add.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board the task is on."},"task_id":{"type":"string","minLength":1,"description":"Task id (from tasks_search)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Comments to return (default 50, max 100)."}},"required":["board_id","task_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"author_id":{"type":"string"},"author_name":{"type":"string"},"content":{"type":"string"},"created_at":{"type":"number"},"updated_at":{"type":"number"},"is_edited":{"type":"boolean"},"is_pinned":{"type":"boolean"},"mentioned_user_ids":{"type":"array","items":{"type":"string"}},"attachment_count":{"type":"number"},"resolved_at":{"type":"number"}},"required":["id","author_id","author_name","content"],"additionalProperties":false}}},"required":["comments"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_comment_add":{"post":{"operationId":"tasks_comment_add","summary":"Comment on a task","description":"Add a comment to a task, attributed to the person the caller acts for; it also appears in the task's activity feed. Takes `board_id` and `task_id` from tasks_search plus `content`. @-mentions are not resolved: the text is posted as plain text. The comment is posted inside the workspace and nothing is sent to a client. Returns the new `comment`. Each call adds another comment.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board the task is on."},"task_id":{"type":"string","minLength":1,"description":"Task id (from tasks_search)."},"content":{"type":"string","minLength":1,"maxLength":5000,"description":"Comment text (plain text; @-mentions are not resolved)."}},"required":["board_id","task_id","content"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"comment":{"type":"object","properties":{"id":{"type":"string"},"task_id":{"type":"string"},"created_at":{"type":"number"}},"required":["id","task_id","created_at"],"additionalProperties":false}},"required":["comment"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/task_boards_create":{"post":{"operationId":"task_boards_create","summary":"Create a task board","description":"Create a task board with the standard To-do / In Progress / Done columns. If the name is taken it is numbered (\"Launch (1)\") and the response says so. It cannot rename, delete or reconfigure a board. Writes one new board and returns `board` and `renamed` (true when the name was numbered). Check task_boards_list first to avoid near-duplicates; each call creates a board.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"Board name."}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"board":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"is_default":{"type":"boolean"},"statuses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"is_final":{"type":"boolean"}},"required":["id","name","is_final"],"additionalProperties":false}}},"required":["id","name","is_default","statuses"],"additionalProperties":false},"renamed":{"type":"boolean"}},"required":["board","renamed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/calendar_list_events":{"post":{"operationId":"calendar_list_events","summary":"List calendar events","description":"List calendar events (schedules), paged (up to `limit`, default 25, max 100, plus `nextCursor`). `from` / `to` (ISO dates) filter by start time: a date-only value means the whole of that day in the workspace time zone (from = to = one date lists that day); a value with a time is an exact instant. All-day events (`is_all_day`) use UTC-midnight date markers: show the date, not a local clock time. `employee_id` keeps events assigned to that team member; `client_id` keeps one client's events. Cancelled events are excluded unless `include_cancelled` is true. Each row carries `is_cancelled`, `location`, `meeting_url`, `description`, `notes` and `is_recurring`; a Meet link that failed shows `meeting_link_status` / `meeting_link_error_code`. `google` is the caller's Google connection state. Scoped members see only their assigned clients' events plus team-wide ones; members restricted to assigned schedules see only events assigned to them.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"calendar:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","description":"Start of the range, ISO date; a date-only value means the whole day in the workspace time zone."},"to":{"type":"string","description":"End of the range, ISO date; a date-only value includes that whole day."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"employee_id":{"type":"string","description":"Only events assigned to this team member (team_members_list)."},"client_id":{"type":"string","description":"Only this client's events."},"include_cancelled":{"type":"boolean","description":"Include cancelled events (excluded by default)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"client_id":{"type":"string"},"client_name":{"type":"string"},"status":{"type":"string"},"is_cancelled":{"type":"boolean"},"location":{"type":"string"},"meeting_url":{"type":"string"},"meeting_link_status":{"type":"string"},"meeting_link_error_code":{"type":"string"},"description":{"type":"string"},"notes":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"is_all_day":{"type":"boolean"},"is_recurring":{"type":"boolean"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"},"google":{"type":"string","enum":["connected","needs_reconnect","not_connected"]}},"required":["events"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/booking_pages_list":{"post":{"operationId":"booking_pages_list","summary":"List booking pages","description":"List the workspace's booking pages. A page carries `public_link` only when it is active and has a slug; an inactive page has no usable link. Read-only; takes no arguments. Returns `pages`. Booking pages are read-only here.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"calendar:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"pages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"is_active":{"type":"boolean"},"is_default":{"type":"boolean"},"public_link":{"type":"string"}},"required":["id","name","slug","is_active","is_default"],"additionalProperties":false}}},"required":["pages"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/calendar_create_event":{"post":{"operationId":"calendar_create_event","summary":"Create a calendar event","description":"Create a calendar event (schedule). Needs `title` and `starts_at` (ISO date). `ends_at` defaults to one hour after `starts_at` and must be after it. For all-day events set `is_all_day: true`, pass YYYY-MM-DD dates (no timezone conversion) and `time_zone`; the default all-day end is the following date and explicit ends are exclusive (September 11 alone ends September 12). With a `client_id` the event inherits that client's visibility; a client-less event is visible to the whole team. `category` must be an existing name from calendar_categories_list. `reminders` are alarm metadata on the event (5_minutes_before, 15_minutes_before, 30_minutes_before, 1_hour_before, 2_hours_before, 1_day_before); they do not prove a notification was scheduled. `recurrence` is daily, weekly, biweekly or monthly, with `recurrence_count` or `recurrence_end_date`. `assigned_user_ids` are ids from team_members_list (omitted: assigned to the caller; `[]`: unassigned). `services` (name + quantity) returns a catalog-priced estimate in the response (`services_preview`, `estimate_total`); nothing is stored on the event. A repeat call with the same `idempotency_key` returns the first event (`deduped: true`).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"calendar:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"Event title."},"is_all_day":{"type":"boolean","description":"true for an all-day event; use YYYY-MM-DD dates."},"time_zone":{"type":"string","description":"IANA time zone for the event."},"starts_at":{"type":"string","minLength":1,"description":"Start, ISO date."},"ends_at":{"type":"string","description":"End, ISO date; defaults to one hour after the start. All-day ends are exclusive."},"client_id":{"type":"string","description":"Client the event is for; it inherits that client's visibility."},"description":{"type":"string","description":"Event description."},"category":{"type":"string","description":"An existing category name (calendar_categories_list)."},"reminders":{"type":"array","items":{"type":"string","enum":["5_minutes_before","15_minutes_before","30_minutes_before","1_hour_before","2_hours_before","1_day_before"]},"description":"Alarm metadata on the event; does not prove a notification was scheduled."},"recurrence":{"type":"string","enum":["none","daily","weekly","biweekly","monthly"],"description":"Repeat pattern; use with `recurrence_count` or `recurrence_end_date`."},"recurrence_count":{"type":"integer","minimum":1,"maximum":52,"description":"Number of occurrences."},"recurrence_end_date":{"type":"string","description":"Last date of the series, ISO date."},"assigned_user_ids":{"type":"array","items":{"type":"string"},"description":"Team member ids (team_members_list); omitted assigns the caller, [] leaves it unassigned."},"services":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Service name, looked up in the catalog."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."}},"required":["name"],"additionalProperties":false},"description":"Services (name + quantity) priced from the catalog; returned as a preview in the response and not stored on the event."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["title","starts_at"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"client_id":{"type":"string"},"is_all_day":{"type":"boolean"},"time_zone":{"type":"string"}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["event","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/time_entries_list":{"post":{"operationId":"time_entries_list","summary":"List time entries","description":"List time entries, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `startTime`/`endTime` (epoch ms) bound the entry start and are applied to each page, so keep following `nextCursor`. A scoped member sees only the entries they logged plus entries for their assigned clients. Read-only. To filter by client, project, task or billable status use time_entries_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"time_entries:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"startTime":{"type":"number","description":"Entries starting at or after this time, epoch ms."},"endTime":{"type":"number","description":"Entries starting at or before this time, epoch ms."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string"},"client_id":{"type":"string"},"project_id":{"type":"string"},"task_id":{"type":"string"},"start_time":{"type":"number"},"end_time":{"type":"number"},"duration_minutes":{"type":"number"},"billable":{"type":"boolean"},"is_running":{"type":"boolean"},"total_amount":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string"},"description":{"type":"string"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["entries"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/time_entries_search":{"post":{"operationId":"time_entries_search","summary":"Search time entries","description":"List time entries with filters, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `clientId`, `projectId`, `taskId` and `billable` narrow the results; `startTime`/`endTime` (epoch ms) bound the entry start. Filters are applied to each page, so keep following `nextCursor`. A scoped member sees only the entries they logged plus entries for their assigned clients. Read-only. For a plain date-range listing time_entries_list is enough.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"time_entries:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"startTime":{"type":"number","description":"Entries starting at or after this time, epoch ms."},"endTime":{"type":"number","description":"Entries starting at or before this time, epoch ms."},"clientId":{"type":"string","description":"Only this client's entries."},"projectId":{"type":"string","description":"Only this project's entries."},"taskId":{"type":"string","description":"Only this task's entries."},"billable":{"type":"boolean","description":"true: only billable entries; false: only non-billable."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string"},"client_id":{"type":"string"},"project_id":{"type":"string"},"task_id":{"type":"string"},"start_time":{"type":"number"},"end_time":{"type":"number"},"duration_minutes":{"type":"number"},"billable":{"type":"boolean"},"is_running":{"type":"boolean"},"total_amount":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string"},"description":{"type":"string"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["entries"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/time_entries_create":{"post":{"operationId":"time_entries_create","summary":"Log a time entry","description":"Log a completed time entry for the calling user (entries for other members are not supported). Needs `start_time` (epoch ms, within the window the server enforces) and `duration_minutes` (0-10080). `billable` defaults to true. A billable entry resolves the workspace's own rate (project, then member, then workspace default) when `hourly_rate` is omitted; a rate other than the resolved one needs the billable-rates edit permission. A non-billable entry always has rate 0. `total_amount` is computed (duration / 60 x hourly_rate when billable, else 0). A repeat call with the same `idempotency_key` returns the first entry (`deduped: true`). To change an entry use time_entries_update; to find entries, time_entries_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"time_entries:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"start_time":{"type":"integer","description":"Start, epoch ms (within the window the server enforces)."},"end_time":{"type":"integer","description":"End, epoch ms."},"duration_minutes":{"type":"integer","minimum":0,"maximum":10080,"description":"Duration in minutes (0-10080)."},"billable":{"type":"boolean","description":"Defaults to true."},"hourly_rate":{"type":"number","minimum":0,"maximum":100000,"description":"Omit to use the workspace's resolved rate; a different rate needs the billable-rates edit permission."},"currency":{"type":"string","maxLength":8,"description":"Currency code."},"description":{"type":"string","maxLength":5000,"description":"What was worked on."},"client_id":{"type":"string","description":"Client the time is for."},"project_id":{"type":"string","description":"Project the time is for."},"task_id":{"type":"string","description":"Task the time is for."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["start_time","duration_minutes"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"entry":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string"},"task_id":{"type":"string"},"task_name":{"type":"string"},"start_time":{"type":"number"},"end_time":{"type":"number"},"duration_minutes":{"type":"number"},"billable":{"type":"boolean"},"is_running":{"type":"boolean"},"hourly_rate":{"type":"number"},"total_amount":{"type":"number"},"currency":{"type":"string"},"description":{"type":"string"}},"required":["id","user_id","start_time","duration_minutes","billable","is_running","hourly_rate","total_amount"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["entry","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/time_entries_update":{"post":{"operationId":"time_entries_update","summary":"Update a time entry","description":"Update one of the caller's own time entries by `id`. Only the fields passed change. Editable: `start_time`/`end_time` (epoch ms), `duration_minutes`, `billable`, `hourly_rate`, `currency`, `description` and `client_id`/`project_id`/`task_id` (re-pointing also re-resolves the stored display name). `total_amount` is recomputed when duration, rate or billable change. Marking an entry non-billable clears its rate; marking a $0 entry billable applies the workspace's resolved rate; a different `hourly_rate` needs the billable-rates edit permission. A timer started in the app can be stopped (`is_running: false`) or paused and resumed (`is_paused`, `total_pause_ms`, `last_pause_at`); a stopped entry cannot be restarted. Billing, timesheet-status and client-scope fields cannot be set. Invoiced, submitted, approved and period-locked entries, other members' entries, and restarting a stopped timer are refused.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"time_entries:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Time entry id (from time_entries_list or time_entries_search)."},"start_time":{"type":"integer","description":"Start, epoch ms."},"end_time":{"type":"integer","description":"End, epoch ms."},"duration_minutes":{"type":"integer","minimum":0,"maximum":10080,"description":"Duration in minutes (0-10080)."},"billable":{"type":"boolean","description":"Whether the entry is billable."},"hourly_rate":{"type":"number","minimum":0,"maximum":100000,"description":"Hourly rate; a rate other than the resolved one needs the billable-rates edit permission."},"currency":{"type":"string","maxLength":8,"description":"Currency code."},"description":{"type":"string","maxLength":5000,"description":"What was worked on."},"client_id":{"type":"string","description":"Client the time is for."},"project_id":{"type":"string","description":"Project the time is for."},"task_id":{"type":"string","description":"Task the time is for."},"total_pause_ms":{"type":"integer","minimum":0,"maximum":604800000,"description":"For a timer started in the app: total paused time in ms."},"is_paused":{"type":"boolean","description":"For a running timer started in the app: pause or resume it."},"last_pause_at":{"type":"integer","nullable":true,"description":"For a timer started in the app: when it was last paused, epoch ms."},"is_running":{"type":"boolean","description":"false stops a running timer; a stopped entry cannot be restarted."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"entry":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string"},"task_id":{"type":"string"},"task_name":{"type":"string"},"start_time":{"type":"number"},"end_time":{"type":"number"},"duration_minutes":{"type":"number"},"billable":{"type":"boolean"},"is_running":{"type":"boolean"},"hourly_rate":{"type":"number"},"total_amount":{"type":"number"},"currency":{"type":"string"},"description":{"type":"string"}},"required":["id","user_id","start_time","duration_minutes","billable","is_running","hourly_rate","total_amount"],"additionalProperties":false}},"required":["entry"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/timesheets_list":{"post":{"operationId":"timesheets_list","summary":"List timesheet submissions","description":"List weekly timesheet submissions, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Each carries the member, the week's period, the approval `status` and server-computed totals (minutes, billable minutes, amount, entry count). `status` and `memberId` filters are applied to each page, so keep following `nextCursor`. Callers see only their own submissions unless they can approve timesheets. Read-only. Returns `submissions`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"time_entries:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"Only submissions with this approval status."},"memberId":{"type":"string","description":"Only this member's submissions."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"submissions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"member_uid":{"type":"string"},"member_name":{"type":"string"},"period_key":{"type":"string"},"period_start_ms":{"type":"number"},"period_end_ms":{"type":"number"},"status":{"type":"string"},"submitted_at":{"type":"number"},"submitted_by":{"type":"string"},"decided_at":{"type":"number"},"decided_by":{"type":"string"},"decision_reason":{"type":"string"},"total_minutes":{"type":"number"},"billable_minutes":{"type":"number"},"total_amount":{"type":"number"},"entry_count":{"type":"number"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["submissions"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/inbox_send_message":{"post":{"operationId":"inbox_send_message","summary":"Send an inbox message","description":"Send an email or SMS from the workspace inbox. Recipients (`to`, `cc`, `bcc`) must already be in the workspace: a client's or contact's saved address or number (pass `client_id`), a team member, the workspace's own address, or the contact of an existing conversation (`conversation_id`); others are refused, as is a client who opted out or is blacklisted. Email: `to` (one or more addresses, each with its own copy), `subject` and `body` (markdown), or a general library `template` (see email_send_options) whose subject and body apply unless overridden. If `from_inbox` is omitted, the workspace's AI & MCP inbox is used, else the only inbox the user can send from; with several and no default, nothing is sent and the result lists them. `cc`/`bcc` replace the default copies. At most 10 recipients per email from a starter inbox and 50 from the user's own domain or mailbox (To + Cc + Bcc, workspace addresses excluded); over the cap nothing is sent. SMS: `to` is one phone number and `body` the text; it needs `client_id` or `conversation_id`, and numbers that texted STOP or are blocked are refused. Sends a real, billed message. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"inbox:send","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"channel":{"type":"string","enum":["sms","email"],"description":"Delivery channel."},"to":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":50,"description":"Recipients. Email: one or more addresses, each getting its own copy and conversation. SMS: exactly one E.164 phone number."},"body":{"type":"string","description":"SMS text (required for sms). Email body, or use `template`. Markdown: `# ` / `## ` / `### ` start a large / medium / small heading; `- ` or `1. ` starts a bullet or numbered item; inline `**bold**`, `*italic*`, `<u>underline</u>`, `~~strikethrough~~`, `[text](https://…)` links and `![alt](https://…)` images. Text without these markers goes out as plain paragraphs. Merge fields like `{{client.first_name}}`, `{{workspace.name}}` and `{{sender.name}}` are filled in."},"conversation_id":{"type":"string","description":"An existing conversation of this workspace to thread into; its contact's address or number may be used as a recipient."},"subject":{"type":"string","description":"Email subject; else the template's, else \"(no subject)\"."},"template":{"type":"string","description":"Email only. A general library template, by id or name."},"client_id":{"type":"string","description":"The client written to. Email: fills `{{client.*}}` merge fields and makes the client's saved addresses valid recipients. SMS: the client whose saved number is texted."},"cc":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Cc addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"bcc":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Bcc addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"from_inbox":{"type":"string","description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["channel","to"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"channel":{"type":"string","enum":["sms","email"]},"to":{"type":"string"},"message_id":{"type":"string"},"conversation_id":{"type":"string"},"conversation_ids":{"type":"array","items":{"type":"string"}},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"},"cc":{"type":"array","items":{"type":"string"}},"bcc":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"template_id":{"type":"string"},"client_id":{"type":"string"}},"required":["sent","channel","to","message_id"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/search_workspace_messages":{"post":{"operationId":"search_workspace_messages","summary":"Search inbox messages","description":"Full-text search across individual inbox messages (email, SMS, call notes), e.g. to find the message where something was said. Returns up to `limit` matches (default 25, max 50), each with its `conversation_id`, plus `nextCursor` when more exist. Callers see only the channels and clients they have access to. Read-only. Searches message text only; find people with clients_search and policies or FAQs with knowledge_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"inbox:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Words to find in message text."},"limit":{"type":"integer","minimum":1,"maximum":50,"description":"Results per page (default 25, max 50)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string"},"conversation_path":{"type":"string"},"client_id":{"type":"string"},"channel":{"type":"string"},"direction":{"type":"string"},"sender":{"type":"string"},"subject":{"type":"string"},"preview":{"type":"string"},"timestamp":{"type":"number"}},"required":["id","conversation_id","conversation_path"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["messages"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/knowledge_search":{"post":{"operationId":"knowledge_search","summary":"Search the knowledge base","description":"Retrieve entries from the workspace's AI knowledge base (policies, procedures, pricing rules, FAQs). `query` runs a semantic search that falls back to keyword matching; `category` filters (e.g. \"Pricing\", \"FAQ\"); with neither it lists the newest entries. Returns up to `limit` entries (default 3, max 25), content truncated to 1500 characters. Read-only. Returns `entries` and the search `mode` used. For client records use clients_search; for notes, notes_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"knowledge:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Semantic search text; falls back to keyword matching."},"category":{"type":"string","description":"Only entries in this category (e.g. Pricing, Policies, FAQ)."},"limit":{"type":"integer","minimum":1,"maximum":25,"description":"Results per page (default 3, max 25)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"category":{"type":"string"},"updatedAt":{"type":"number"}},"required":["id","title","content"],"additionalProperties":false}},"mode":{"type":"string","enum":["semantic","keyword","category","list"]}},"required":["entries","mode"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/inbox_send_bulk":{"post":{"operationId":"inbox_send_bulk","summary":"Send a bulk SMS","description":"Send one SMS to many of the workspace's own clients in a single action. `recipients` is [{client_id, to?, name?}] (find ids with clients_search) and `body` is the same text for every recipient. `client_id` is required: the text goes to that client's phone on file, or to `to` only if it is a number saved on that client. Numbers that are not on a client record cannot be texted. Clients who opted out of texts or are blacklisted are excluded as the campaigns screen does and returned as `suppressed`, not `failed`. One confirmation covers the exact recipient list, and confirmable tools are rejected inside batch_apply. At most 30 recipients per call. Duplicate phone numbers are sent once and reported as duplicates. Each recipient returns its own outcome (queued, failed, duplicate or suppressed) with its conversation id; a failure does not stop later recipients. Requires the inbox SMS send permission. Sends real messages and bills for each. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"inbox:send","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"recipients":{"type":"array","items":{"type":"object","properties":{"client_id":{"type":"string","minLength":1,"description":"The client's id (from clients_search / clients_get). Required: only the workspace's own clients can be texted in bulk."},"to":{"type":"string","minLength":1,"description":"Optional. One of the phone numbers on this client's record. Omit to use the client's primary phone. Any other number is refused."},"name":{"type":"string","description":"Optional display name, echoed back in the result."}},"required":["client_id"],"additionalProperties":false},"minItems":1,"description":"The clients to text, at most 30 per call. Each entry names a client of this workspace."},"body":{"type":"string","minLength":1,"description":"The SMS text; the same message goes to every recipient."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["recipients","body"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"queued_count":{"type":"integer"},"failed_count":{"type":"integer"},"duplicate_count":{"type":"integer"},"suppressed_count":{"type":"integer"},"recipient_count":{"type":"integer"},"outcomes":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"client_id":{"type":"string"},"to":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["queued","failed","duplicate","suppressed"]},"conversation_id":{"type":"string"},"message_id":{"type":"string"},"message":{"type":"string"}},"required":["index","client_id","to","status"],"additionalProperties":false}}},"required":["queued_count","failed_count","duplicate_count","suppressed_count","recipient_count","outcomes"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/media_attach":{"post":{"operationId":"media_attach","summary":"Attach a workspace file","description":"Attach an already-uploaded workspace-storage file (by `storage_path`) to a schedule, an invoice, or an expense (`entity_type: \"expense\"`, id from expenses_list; this is how a receipt is attached). No file bytes are accepted: the app uploads and registers the file first. `kind: \"photo\"` (schedules only; `is_before` marks a before/after job photo) requires an image; `kind: \"document\"` attaches any registered file. Invoices resolve by `entity_id` or `entity_number` (ambiguous numbers are refused); proposals and estimates are not valid targets. Re-attaching the same path is a no-op (`deduped`).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"media:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entity_type":{"type":"string","enum":["schedule","invoice","expense"],"description":"What the file attaches to: a schedule, an invoice or an expense."},"entity_id":{"type":"string","minLength":1,"description":"Id of the schedule, invoice or expense."},"entity_number":{"type":"string","minLength":1,"description":"Human invoice number, as an alternative to `entity_id` for invoices."},"storage_path":{"type":"string","minLength":1,"description":"Path of the already-uploaded workspace-storage file."},"kind":{"type":"string","enum":["photo","document"],"description":"photo (images, schedules only) or document."},"is_before":{"type":"boolean","description":"For a photo: true marks it a \"before\" photo, false an \"after\" photo."},"description":{"type":"string","description":"Description of the file."}},"required":["entity_type","storage_path","kind"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"attached":{"type":"object","properties":{"entity_type":{"type":"string"},"entity_id":{"type":"string"},"path":{"type":"string"},"file_name":{"type":"string"},"kind":{"type":"string"},"photo_kind":{"type":"string"}},"required":["entity_type","entity_id","path","kind"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["attached","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/media_list":{"post":{"operationId":"media_list","summary":"List attached media","description":"List the files attached to a schedule, an invoice or an expense: photos and documents, with file name, description and before/after photo kind from the workspace storage registry. `kind` filters to photo, document or all (default). Returns storage paths, never file bytes. Read-only. Returns `media` and `count`; attach a file with media_attach.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"media:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entity_type":{"type":"string","enum":["schedule","invoice","expense"],"description":"Whose files to list: a schedule, an invoice or an expense."},"entity_id":{"type":"string","minLength":1,"description":"Id of the schedule, invoice or expense."},"kind":{"type":"string","enum":["photo","document","all"],"description":"photo (images only), document (non-images) or all (default)."}},"required":["entity_type","entity_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"media":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"url":{"type":"string"},"kind":{"type":"string"},"file_name":{"type":"string"},"content_type":{"type":"string"},"photo_kind":{"type":"string"},"description":{"type":"string"},"created_at":{"type":"number"}},"required":["path","kind"],"additionalProperties":false}},"count":{"type":"integer"}},"required":["media","count"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/expense_types_list":{"post":{"operationId":"expense_types_list","summary":"List expense types","description":"List the workspace's configured expense categories (id and name). expenses_create and expenses_update take a category name; an unknown category is allowed but flagged. Read-only; takes no arguments. Returns `expense_types` and `count`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"expenses:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"expense_types":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"count":{"type":"integer"}},"required":["expense_types","count"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/expenses_create":{"post":{"operationId":"expenses_create","summary":"Record an expense","description":"Record a business expense. Needs a positive `amount` (dollars) and a `category` (a name from expense_types_list; an unknown one is recorded with a warning). `date` is \"MM/dd/yyyy\" or \"yyyy-MM-dd\" and defaults to today. `receipt_number` is folded into the description. `project_id` links the expense to a project (from projects_search); `schedule_id` links it to a calendar job. Dates inside a closed accounting period are refused. A repeat call with the same `idempotency_key` reports a replay with `deduped`. Returns `expense` and `deduped`; an unknown category adds `category_warning`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"expenses:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Amount in dollars; must be positive."},"category":{"type":"string","minLength":1,"description":"Category name (expense_types_list); an unknown name is recorded with a warning."},"description":{"type":"string","description":"What the expense was for."},"date":{"type":"string","description":"\"MM/dd/yyyy\" or \"yyyy-MM-dd\"; defaults to today."},"schedule_id":{"type":"string","description":"Calendar job (schedule) to link the expense to."},"project_id":{"type":"string","description":"Project to put the expense on (projects_search)."},"vendor":{"type":"string","description":"Vendor name."},"receipt_number":{"type":"string","description":"Receipt number (folded into the description)."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["amount","category"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"expense":{"type":"object","properties":{"id":{"type":"string"},"amount":{"type":"number"},"date":{"type":"string"},"category":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"schedule_id":{"type":"string"},"project_id":{"type":"string"},"project_name":{"type":"string"}},"required":["id","amount","date","category","name"],"additionalProperties":false},"deduped":{"type":"boolean"},"category_note":{"type":"string"},"category_warning":{"type":"string"}},"required":["expense","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/expenses_update":{"post":{"operationId":"expenses_update","summary":"Update an expense","description":"Correct an expense by `expense_id` (from expenses_list). Only the fields passed change: `amount`, `category`, `description`, `date` (\"MM/dd/yyyy\" or \"yyyy-MM-dd\") or `project_id` (empty string unlinks it). Refused when the expense is in a closed accounting period or would be moved into one. It cannot delete an expense or change who recorded it. Returns `expense_id`, the applied `changes` and any category note or warning.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"expenses:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expense_id":{"type":"string","minLength":1,"description":"Expense id (expenses_list)."},"amount":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"New amount in dollars."},"category":{"type":"string","minLength":1,"description":"New category name (expense_types_list)."},"description":{"type":"string","description":"New description."},"date":{"type":"string","description":"New date, \"MM/dd/yyyy\" or \"yyyy-MM-dd\"."},"project_id":{"type":"string","description":"Project to link; an empty string unlinks it."}},"required":["expense_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"expense_id":{"type":"string"},"changes":{"type":"array","items":{"type":"string"}},"category_note":{"type":"string"},"category_warning":{"type":"string"}},"required":["expense_id","changes"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/expenses_list":{"post":{"operationId":"expenses_list","summary":"List expenses","description":"List recorded expenses, paged by `limit` (default 25, max 100) and `nextCursor`. Filters: `category` (case-insensitive name), `schedule_id`, `project_id`, and `period` (today, this_week, this_month, this_year or all; UTC calendar, weeks start Monday). `page_total_amount` sums this page only. Read-only. Returns `expenses`, `page_total_amount` and `nextCursor`; record one with expenses_create.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"expenses:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schedule_id":{"type":"string","description":"Only expenses linked to this calendar job."},"project_id":{"type":"string","description":"Only expenses on this project."},"period":{"type":"string","enum":["today","this_week","this_month","this_year","all"],"description":"today, this_week, this_month, this_year or all (UTC calendar; weeks start Monday)."},"category":{"type":"string","description":"Category name (case-insensitive)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"expenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"amount":{"type":"number"},"date":{"type":"string"},"category":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"schedule_id":{"type":"string"},"project_id":{"type":"string"},"has_receipt":{"type":"boolean"}},"required":["id","amount","date","category","name","has_receipt"],"additionalProperties":false}},"page_total_amount":{"type":"number"},"nextCursor":{"type":"string"}},"required":["expenses","page_total_amount"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/products_list":{"post":{"operationId":"products_list","summary":"List catalog services","description":"List the services/products in the catalog with pricing, paged (up to `limit`, default 25, max 100, plus `nextCursor`). By default only active, non-deleted services are returned; `status` (draft, archived or all) includes inactive ones. Each row's `id` is the argument for products_update. Read-only.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"products:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["active","draft","archived","all"],"description":"draft, archived or all, to include inactive services (default: active only)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"price":{"type":"number"},"price_type":{"type":"string"},"status":{"type":"string"}},"required":["id","name","price","price_type","status"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["products"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/products_create":{"post":{"operationId":"products_create","summary":"Add a catalog service","description":"Add a service/product to the catalog. Needs `name`, `price` and `price_type` (flat_rate, per_hour, per_unit or per_area). `active: false` creates a draft. A duplicate name is refused (use products_update). `description` accepts simple markdown (`# ` headings, `- ` and `1. ` lists, **bold**, *italic*, <u>underline</u>, ~~strikethrough~~, [links](https://…)). A repeat call with the same `idempotency_key` returns the first product. Returns `product` and `deduped`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"products:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Service name; a duplicate name is refused."},"price":{"type":"number","minimum":0,"description":"Price."},"price_type":{"type":"string","enum":["flat_rate","per_hour","per_unit","per_area"],"description":"flat_rate, per_hour, per_unit or per_area."},"description":{"type":"string","description":"Service description; simple markdown."},"active":{"type":"boolean","description":"false creates a draft instead of an active service."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["name","price","price_type"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"product":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"price":{"type":"number"},"price_type":{"type":"string"},"status":{"type":"string"}},"required":["id","name","price","price_type","status"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["product","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/products_update":{"post":{"operationId":"products_update","summary":"Update a catalog service","description":"Update a catalog service by `id` (from products_list). Only the fields passed (`name`, `price`, `price_type`, `description`, `active`) change. `active: false` moves it to draft; `true` re-activates it. Passing `description` replaces the stored description, including its rich formatting; it accepts simple markdown (`# ` headings, `- ` and `1. ` lists, **bold**, *italic*, <u>underline</u>, ~~strikethrough~~, [links](https://…)). Returns the updated `product`. To add a service use products_create.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"products:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Service id (products_list)."},"name":{"type":"string","minLength":1,"description":"New name."},"price":{"type":"number","minimum":0,"description":"New price."},"price_type":{"type":"string","enum":["flat_rate","per_hour","per_unit","per_area"],"description":"flat_rate, per_hour, per_unit or per_area."},"description":{"type":"string","description":"Replaces the description, including its formatting."},"active":{"type":"boolean","description":"false moves the service to draft; true re-activates it."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"product":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"price":{"type":"number"},"price_type":{"type":"string"},"status":{"type":"string"}},"required":["id","name","price","price_type","status"],"additionalProperties":false}},"required":["product"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/workspace_business_summary":{"post":{"operationId":"workspace_business_summary","summary":"Business summary","description":"Counts only: the authoritative client count, invoice figures (total count, unpaid count, unpaid outstanding sum), today's scheduled event count and the number of catalog services. Invoice figures come from a Firestore aggregation over the invoices collection, which also stores proposals and legacy estimates. A figure that cannot be answered authoritatively is `null` (\"unavailable\"), not zero. Optional `timezone` (IANA, e.g. 'America/New_York') picks which day 'today' means; default UTC.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"workspace:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timezone":{"type":"string","description":"IANA time zone that decides which day \"today\" is; default UTC."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"clients":{"type":"object","properties":{"count":{"type":"integer","nullable":true}},"required":["count"],"additionalProperties":false},"invoices":{"type":"object","properties":{"total_count":{"type":"integer","nullable":true},"unpaid_count":{"type":"integer","nullable":true},"unpaid_total":{"type":"number","nullable":true},"includes_proposals_and_estimates":{"type":"boolean"}},"required":["total_count","unpaid_count","unpaid_total","includes_proposals_and_estimates"],"additionalProperties":false},"schedule_today":{"type":"object","properties":{"count":{"type":"integer","nullable":true},"day_start_ms":{"type":"number"},"day_end_ms":{"type":"number"},"timezone":{"type":"string"}},"required":["count","day_start_ms","day_end_ms","timezone"],"additionalProperties":false},"services":{"type":"object","properties":{"count":{"type":"integer","nullable":true}},"required":["count"],"additionalProperties":false}},"required":["clients","invoices","schedule_today","services"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_get":{"post":{"operationId":"tasks_get","summary":"Get a task","description":"Get the details of one task on a board: description, status, priority, dates, tags, assignees, estimate, star state, custom-field values (resolved against the board schema) and subtasks. Needs `board_id` and the task `id` (or a `title`, accepted only when it identifies one unambiguous task; ambiguous titles are refused with the candidates).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board the task is on (task_boards_list)."},"id":{"type":"string","description":"Task id (preferred over `title`)."},"title":{"type":"string","description":"Task title; accepted only if it identifies one task."}},"required":["board_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"board_id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"status_id":{"type":"string"},"priority":{"type":"number"},"due_date":{"type":"number"},"start_date":{"type":"number"},"is_milestone":{"type":"boolean"},"blocked_by":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}},"assignees":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}},"required":["id","name","email"],"additionalProperties":false}},"estimated_hours":{"type":"number"},"is_starred":{"type":"boolean"},"subtasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"is_completed":{"type":"boolean"}},"required":["id","title","is_completed"],"additionalProperties":false}},"custom_fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"workflow_key":{"type":"string"},"type":{"type":"string"},"value":{}},"required":["id"],"additionalProperties":false}},"created_at":{"type":"number"},"updated_at":{"type":"number"}},"required":["id","board_id","is_milestone","blocked_by","tags","assignees","is_starred","subtasks","custom_fields"],"additionalProperties":false}},"required":["task"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/task_boards_list":{"post":{"operationId":"task_boards_list","summary":"List task boards","description":"List the workspace's task boards with their ordered statuses. Task writes need a `board_id` and a status name that exists on that board. Scoped members see only boards they can access. Read-only; takes no arguments. Returns `boards`; each `id` is the `board_id` the task tools take. For custom fields use task_board_schema; to add a board use task_boards_create.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"boards":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"is_default":{"type":"boolean"},"statuses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"is_final":{"type":"boolean"}},"required":["id","name","is_final"],"additionalProperties":false}}},"required":["id","statuses"],"additionalProperties":false}}},"required":["boards"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/task_board_schema":{"post":{"operationId":"task_board_schema","summary":"Get a board's field schema","description":"Get the writable field schema for one task board: its statuses, built-in task fields, and board-specific custom fields with types, required state, ids and allowed dropdown options. Use it for `estimated_hours` and `custom_fields` on task writes. Board tags are listed by task_board_tags_list. Read-only. Returns `board`, `statuses`, `built_in_fields`, `custom_fields` and `defaults`. Call it before tasks_create or tasks_update when setting custom fields.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board id (task_boards_list)."}},"required":["board_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"board":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id"],"additionalProperties":false},"statuses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"is_final":{"type":"boolean"}},"required":["id","name","is_final"],"additionalProperties":false}},"built_in_fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"rule":{"type":"string"}},"required":["field","rule"],"additionalProperties":false}},"custom_fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workflow_key":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"required":{"type":"boolean"},"options":{"type":"array","items":{"type":"string"}}},"required":["id","workflow_key","name","type","required","options"],"additionalProperties":false}},"defaults":{"type":"object","properties":{"priority":{"type":"number"},"status_id":{"type":"string"},"due_offset_days":{"type":"number"}},"required":["priority"],"additionalProperties":false}},"required":["board","statuses","built_in_fields","custom_fields","defaults"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/task_board_tags_list":{"post":{"operationId":"task_board_tags_list","summary":"List a board's tags","description":"Search or page the tag catalog of one accessible task board, including tags not used by currently loaded tasks. Pass `next_after_id` as `after_id` with the same board and query to continue; pages are live, not a snapshot. If `catalog_ready` is false the catalog is not initialized.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"maxLength":200,"description":"Board id (task_boards_list)."},"query":{"type":"string","maxLength":160,"description":"Filter tags by name."},"after_id":{"type":"string","minLength":1,"maxLength":200,"description":"The `next_after_id` value from the previous response, passed back unchanged; omit for the first page."},"limit":{"type":"integer","minimum":1,"maximum":25,"description":"Tags per page (default 25, max 25)."}},"required":["board_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string"},"catalog_ready":{"type":"boolean"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"name":{"type":"string","minLength":1,"maxLength":160}},"required":["id","name"],"additionalProperties":false}},"matching_count":{"type":"integer"},"has_more":{"type":"boolean"},"next_after_id":{"type":"string"}},"required":["board_id","catalog_ready","tags","matching_count","has_more"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/tasks_subtasks_update":{"post":{"operationId":"tasks_subtasks_update","summary":"Update a task's subtasks","description":"Add checklist items to an existing task and/or complete or reopen existing ones. Locate the task by `id` + `board_id`. `add` appends titles (titles already on the checklist are skipped and reported). `set_completion` ({subtasks: [titles], completed}) is all-or-nothing: every title must match exactly one existing subtask, otherwise nothing changes. Returns the full checklist. To create a task with a checklist, pass `subtasks` to tasks_create.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Task id (from tasks_search)."},"board_id":{"type":"string","minLength":1,"description":"Board the task is on."},"add":{"type":"array","items":{"type":"string","minLength":1},"description":"Checklist titles to append; titles already present are skipped."},"set_completion":{"type":"object","properties":{"subtasks":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"Titles of existing subtasks."},"completed":{"type":"boolean","description":"true completes them; false reopens them."}},"required":["subtasks","completed"],"additionalProperties":false,"description":"{subtasks: [titles], completed} to complete or reopen existing subtasks; all-or-nothing."}},"required":["id","board_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"}},"required":["id","board_id"],"additionalProperties":false},"subtasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"is_completed":{"type":"boolean"}},"required":["id","title","is_completed"],"additionalProperties":false}},"added_titles":{"type":"array","items":{"type":"string"}},"skipped_titles":{"type":"array","items":{"type":"string"}},"completion_updated_titles":{"type":"array","items":{"type":"string"}}},"required":["task","subtasks","added_titles","skipped_titles","completion_updated_titles"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/calendar_categories_list":{"post":{"operationId":"calendar_categories_list","summary":"List calendar categories","description":"List the calendar categories configured in the workspace. Only these names exist; a calendar event's `category` must be one of them. Read-only; takes no arguments. Returns `categories`. Call before calendar_create_event or calendar_update_event to pick a valid `category`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"calendar:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"}},"required":["id","name","color"],"additionalProperties":false}}},"required":["categories"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/calendar_check_availability":{"post":{"operationId":"calendar_check_availability","summary":"Check team availability","description":"Check which team members are available on a date, from their working hours and that day's calendar events. The day is bounded in the workspace time zone (a member's own time zone override wins for that member) and the answer states the zone. `date` is required; `employee_ids` (from team_members_list) narrows the check. Returns available members (with working hours) and unavailable members (booked, with conflicts, or not a working day). For one person's weekly hours use team_member_availability_get; for events, calendar_list_events.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"calendar:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string","minLength":1,"description":"The day to check, ISO date (YYYY-MM-DD)."},"employee_ids":{"type":"array","items":{"type":"string"},"description":"Team member ids (from team_members_list) to check; omit for everyone."}},"required":["date"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string"},"day_of_week":{"type":"string"},"time_zone":{"type":"string"},"available":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"working_hours":{"type":"array","items":{"type":"string"}},"time_zone":{"type":"string"}},"required":["id","name","working_hours","time_zone"],"additionalProperties":false}},"unavailable":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"working_hours":{"type":"array","items":{"type":"string"}},"time_zone":{"type":"string"},"reason":{"type":"string","enum":["booked","not_working_day"]},"conflicts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"}},"required":["id","title"],"additionalProperties":false}}},"required":["id","name","working_hours","time_zone","reason","conflicts"],"additionalProperties":false}}},"required":["date","day_of_week","time_zone","available","unavailable"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/calendar_update_event":{"post":{"operationId":"calendar_update_event","summary":"Update a calendar event","description":"Edit or reschedule an existing calendar event by `event_id` (new events: calendar_create_event; bulk client moves: calendar_events_reschedule_batch). Only the fields passed change. `starts_at` / `ends_at` are ISO dates; `starts_at` alone moves the event and keeps its duration. All-day moves use date strings with exclusive ends; set `is_all_day` to convert. `notes` replaces the Notes block and `description` the description (\"\" clears either). `add_reminders` appends, skipping any reminder already set; `clear_reminders: true` removes them all. `status: \"cancelled\"` soft-cancels (record kept). A recurring event (`is_recurring`) needs `occurrence_scope: \"all_events\"`, which changes the whole series; other scopes are done in the Calendar screen. `recurrence` (none, daily, weekly, biweekly, monthly, with `recurrence_count` or `recurrence_end_date`) makes a one-off event repeat, re-patterns a series, or with `none` makes it one event; a pattern shorter than the event is refused, and a series on specific weekdays can only have its count changed. An event someone has open in the app is refused as being edited. Linked reminders fire for the first occurrence only on biweekly series.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"calendar:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event_id":{"type":"string","minLength":1,"description":"Id of the event, from calendar_list_events."},"is_all_day":{"type":"boolean","description":"Convert between a timed and an all-day event; supply starts_at with it."},"time_zone":{"type":"string","description":"IANA zone used for linked relative reminders."},"title":{"type":"string","minLength":1,"description":"New title."},"starts_at":{"type":"string","description":"New start, ISO date. Alone, it moves the event and keeps its duration."},"ends_at":{"type":"string","description":"New end, ISO date."},"notes":{"type":"string","description":"Replaces the event's Notes block; \"\" clears it."},"description":{"type":"string","description":"Replaces the description; \"\" clears it."},"add_reminders":{"type":"array","items":{"type":"string","enum":["5_minutes_before","15_minutes_before","30_minutes_before","1_hour_before","2_hours_before","1_day_before"]},"description":"Reminders to append to the existing ones."},"clear_reminders":{"type":"boolean","description":"true removes all reminders."},"occurrence_scope":{"type":"string","enum":["all_events"],"description":"Required when the event repeats. Only \"all_events\" (the whole series) is supported; single occurrences and series splits are done on the Calendar screen."},"status":{"type":"string","enum":["confirmed","tentative","cancelled"],"description":"cancelled is a soft cancel that keeps the record."},"recurrence":{"type":"string","enum":["none","daily","weekly","biweekly","monthly"],"description":"Repeat pattern; none turns a series into a single event. Use with `recurrence_count` or `recurrence_end_date`."},"recurrence_count":{"type":"integer","minimum":1,"maximum":52,"description":"Number of occurrences."},"recurrence_end_date":{"type":"string","description":"Last date of the series, ISO date."}},"required":["event_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"}},"required":["id"],"additionalProperties":false},"changes":{"type":"array","items":{"type":"string"}}},"required":["changes"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/calendar_events_reschedule_batch":{"post":{"operationId":"calendar_events_reschedule_batch","summary":"Reschedule a batch of events","description":"Move many calendar events at once as one reviewable action. Pass exactly one mode: `from_date` (ISO date) moves that day's client-linked events to `to_date`, or `client_id` moves that client's upcoming events to `to_date`. Days and times are local to `time_zone` (IANA; default the workspace time zone). Each event keeps its local time of day and duration; `start_time` (\"HH:MM\", 24h, local) re-anchors the day, preserving inter-event gaps unless `preserve_order: false` stacks them at the same time. At most 30 events move per call; if more match, the call refuses with the count. Recurring series and events someone has open in the app are skipped and counted. The result lists every move (old to new start).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"calendar:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from_date":{"type":"string","description":"Move the client-linked events on this day (ISO date) to `to_date`. Use this or `client_id`."},"client_id":{"type":"string","description":"Move this client's upcoming events to `to_date`. Use this or `from_date`."},"to_date":{"type":"string","minLength":1,"description":"Target day, ISO date."},"start_time":{"type":"string","description":"\"HH:MM\" (24h, local) to re-anchor the day; gaps between events are preserved."},"preserve_order":{"type":"boolean","description":"false stacks the events at the same time instead of keeping their gaps."},"time_zone":{"type":"string","description":"IANA time zone for the days and times; defaults to the workspace's."}},"required":["to_date"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"moved":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"old_start":{"type":"number"},"new_start":{"type":"number"}},"required":["id","title","old_start","new_start"],"additionalProperties":false}},"moved_count":{"type":"number"},"time_zone":{"type":"string"},"excluded_count":{"type":"number"},"recurring_skipped_count":{"type":"number"},"locked_skipped_count":{"type":"number"}},"required":["moved","moved_count"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/team_members_list":{"post":{"operationId":"team_members_list","summary":"List team members","description":"List the workspace's team members: the assignable `id`, name, email, role, invitation status and active availability days of each. Ids are used for event assignees and calendar_check_availability. Read-only; takes no arguments. Returns `members`. To find one person by name or email use team_members_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"team:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"status":{"type":"string"},"available_days":{"type":"array","items":{"type":"string"}}},"required":["id","name","email","role","status","available_days"],"additionalProperties":false}}},"required":["members"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/team_members_search":{"post":{"operationId":"team_members_search","summary":"Find a team member","description":"Find a team member by name or email. An unambiguous match returns that member (id, name, email, role, status); an ambiguous query returns up to 5 candidates. Read-only. Returns `match` (the one member, when unambiguous) or `candidates`. For the full roster use team_members_list.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"team:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"description":"Name or email."}},"required":["query"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"match":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"status":{"type":"string"},"available_days":{"type":"array","items":{"type":"string"}}},"required":["id","name","email","role","status","available_days"],"additionalProperties":false},"candidates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"status":{"type":"string"},"available_days":{"type":"array","items":{"type":"string"}}},"required":["id","name","email","role","status","available_days"],"additionalProperties":false}}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/team_member_availability_get":{"post":{"operationId":"team_member_availability_get","summary":"Get team member availability","description":"Read a team member's weekly working hours. `member_id` selects one member; omit it for the whole roster. All seven days are always returned; `active: false` is a non-working day. Slot times are wall-clock times in `time_zone`; `time_zone_source` is `member` (their own zone), `workspace`, or `default` (a UTC fallback nobody set). Read-only. Returns `members`; change hours with team_member_availability_set.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"team:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"member_id":{"type":"string","description":"Team member id; omit for the whole roster."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"calendar_color":{"type":"string"},"time_zone":{"type":"string"},"time_zone_source":{"type":"string","enum":["member","workspace","default"]},"days":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"active":{"type":"boolean"},"slots":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","description":"Start time, 12-hour clock, e.g. \"8:00 AM\"."},"end":{"type":"string","description":"End time, 12-hour clock, e.g. \"5:00 PM\"."}},"required":["start","end"],"additionalProperties":false}}},"required":["day","active","slots"],"additionalProperties":false}}},"required":["id","name","email","calendar_color","time_zone","time_zone_source","days"],"additionalProperties":false}}},"required":["members"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/team_member_availability_set":{"post":{"operationId":"team_member_availability_set","summary":"Set team member availability","description":"Change a team member's working availability, one day at a time, and/or the time zone those hours are in. Only the days passed change (days you omit are left as they are); clearing a day means naming it with `active: false` or empty `slots`, and an active day needs at least one slot. Times are 12-hour strings like \"8:00 AM\" in the member's time zone. `time_zone` must be an IANA zone naming a place (e.g. \"America/Denver\"); fixed offsets like \"+05:00\" or \"EST\" are refused. Pass `days`, `time_zone`, or both. The member is not notified. Any caller holding `team.edit_permissions` may edit any member, including the workspace owner, as in the app. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"team:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"member_id":{"type":"string","minLength":1,"description":"Team member id (from team_members_list)."},"days":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"description":"Day of the week, in any letter case."},"active":{"type":"boolean","description":"false marks a non-working day."},"slots":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","description":"Start time, 12-hour clock, e.g. \"8:00 AM\"."},"end":{"type":"string","description":"End time, 12-hour clock, e.g. \"5:00 PM\"."}},"required":["start","end"],"additionalProperties":false},"description":"Working-hour slots; empty with active false closes the day."}},"required":["day"],"additionalProperties":false},"minItems":1,"description":"The days to change; days not listed are left as they are."},"time_zone":{"type":"string","description":"IANA zone naming a place (e.g. America/Denver) that the hours are in."}},"required":["member_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"member":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"time_zone":{"type":"string"},"time_zone_source":{"type":"string","enum":["member","workspace","default"]},"days":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"active":{"type":"boolean"},"slots":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","description":"Start time, 12-hour clock, e.g. \"8:00 AM\"."},"end":{"type":"string","description":"End time, 12-hour clock, e.g. \"5:00 PM\"."}},"required":["start","end"],"additionalProperties":false}}},"required":["day","active","slots"],"additionalProperties":false}}},"required":["id","name","email","time_zone","time_zone_source","days"],"additionalProperties":false}},"required":["member"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/team_member_activity_list":{"post":{"operationId":"team_member_activity_list","summary":"List a team member's activity","description":"List what a team member has recently done in the workspace (the audit trail behind Team > Member Activity): the action, the record touched, when, and the names of the fields that changed. It reports which fields changed, not what they changed to: old and new values are not served. Messages and Ask AI sessions are listed without a name, because their stored name is their content; use `target_id` to refer to them. `since` / `until` are epoch milliseconds; `limit` defaults to 25, max 100.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"team:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"member_id":{"type":"string","minLength":1,"description":"Team member id (from team_members_list)."},"limit":{"type":"integer","description":"Maximum number of results to return (default 25, max 100)."},"since":{"type":"integer","description":"Only activity after this time, epoch ms."},"until":{"type":"integer","description":"Only activity before this time, epoch ms."}},"required":["member_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"target_type":{"type":"string"},"target_id":{"type":"string"},"target_name":{"type":"string"},"timestamp":{"type":"number"},"changed_fields":{"type":"array","items":{"type":"string"}}},"required":["action","target_type","target_id","target_name","timestamp","changed_fields"],"additionalProperties":false}}},"required":["entries"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_create_from_schedule":{"post":{"operationId":"invoices_create_from_schedule","summary":"Invoice a scheduled job","description":"Create an invoice for one scheduled job (calendar event). `schedule_id` comes from calendar_list_events. The invoice takes its client and line items from the schedule and its connected estimate/proposal when one exists (a declined optional add-on is left off); otherwise it starts empty and lines are added with invoices_update_draft. Dates, due date, payment term, notes and terms come from the workspace's Invoice Defaults (invoices_get_defaults). It is created as Pending with a public pay link, linked back to the schedule, and numbered from the workspace sequence. A schedule that already has an invoice is refused. `mark_as_paid` also records a payment for the full total, using `payment_type` (Cash, Check, Credit Card, Bank Transfer or Other). This tool does not edit statuses of existing invoices; payments_record records payments. Nothing is charged and nothing is sent to the client. A recorded payment sends the invoice.* webhook events to any webhook URLs the workspace has set up. A repeat call with the same `idempotency_key` returns the first invoice.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schedule_id":{"type":"string","minLength":1,"description":"Calendar event (schedule) to invoice, from calendar_list_events."},"mark_as_paid":{"type":"boolean","description":"Also record a payment for the full total."},"payment_type":{"type":"string","enum":["Cash","Check","Credit Card","Bank Transfer","Other"],"description":"Payment method recorded when mark_as_paid is true; default Other."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["schedule_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"schedule_id":{"type":"string"},"total":{"type":"number"},"number":{"type":"string"},"due_date":{"type":"string"}},"required":["id","status","client_id","schedule_id","total"],"additionalProperties":false},"deduped":{"type":"boolean"},"marked_paid":{"type":"boolean"}},"required":["invoice","deduped","marked_paid"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_batch_from_schedules":{"post":{"operationId":"invoices_batch_from_schedules","summary":"Invoice scheduled jobs in a range","description":"Create invoices for every scheduled job in a date range in one action. `from_date` and optional `to_date` are ISO dates. Schedules are enumerated server-side; those that already have an invoice are skipped (`exclude_already_invoiced: false` includes them), as are cancelled appointments and schedules with no client. Each invoice gets the workspace's Invoice Defaults. At most 25 invoices are created per call (`max_invoices` lowers it), and the result reports how many eligible schedules remain. `mark_as_paid` (+ `payment_type`) records a real payment per invoice. `notify_email` and/or `notify_sms` send each client their invoice with its public pay link and bill for each message; emails go out as invoices_send sends them, with `email_message` replacing the body and `sms_message` adding a note to the text. `from_inbox` names the sending inbox; when omitted it is the workspace's inbox for AI & MCP emails or the only usable one, and with several and no default the call is refused before anything is created and the result lists them. A retry with the same `idempotency_key` reuses the invoices already created. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from_date":{"type":"string","minLength":1,"description":"Start of the date range, an ISO date such as 2026-08-27."},"to_date":{"type":"string","minLength":1,"description":"End of the range (ISO date, inclusive). Defaults to `from_date`."},"exclude_already_invoiced":{"type":"boolean","description":"Skip schedules that already have an invoice. Default true."},"mark_as_paid":{"type":"boolean","description":"Record a real payment against every created invoice."},"payment_type":{"type":"string","description":"Payment type recorded with `mark_as_paid`."},"notify_email":{"type":"boolean","description":"Email each invoiced client their invoice. This is a real send and bills for each message."},"notify_sms":{"type":"boolean","description":"Text each invoiced client their invoice link. This is a real send and bills for each message."},"email_message":{"type":"string","description":"Replaces the standard invoice email body; the invoice button and PDF are still included."},"from_inbox":{"type":"string","description":"The inbox the notification emails go out from, by label or address. With several inboxes and no default, the call is refused before anything is created."},"sms_message":{"type":"string","description":"A note added to the notification SMS."},"max_invoices":{"type":"integer","minimum":1,"maximum":25,"description":"Create at most this many invoices in this call. Default and maximum 25."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["from_date"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"created":{"type":"array","items":{"type":"object","properties":{"schedule_id":{"type":"string"},"invoice_id":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"number":{"type":"string"},"total":{"type":"number"},"deduped":{"type":"boolean"},"marked_paid":{"type":"boolean"},"notified_email":{"type":"boolean"},"notified_sms":{"type":"boolean"},"error":{"type":"string"}},"required":["schedule_id"],"additionalProperties":false}},"created_count":{"type":"number"},"skipped_already_invoiced":{"type":"number"},"skipped_no_client":{"type":"number"},"skipped_cancelled":{"type":"number"},"remaining_beyond_cap":{"type":"number"},"grand_total":{"type":"number"}},"required":["created","created_count","skipped_already_invoiced","skipped_no_client","skipped_cancelled","remaining_beyond_cap","grand_total"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_update_draft":{"post":{"operationId":"invoices_update_draft","summary":"Update a draft invoice","description":"Edit an existing invoice by `invoice_id` or `invoice_number`. Changeable: `notes` (replaced), discount (`discount_percent` or `discount_amount`; 0 removes it), tax (`tax_percent` or `tax_amount`), `deposit_percent`, `invoice_date` / `due_date` (MM/DD/YYYY) or `due_in_days`, `payment_term` (printed label only), and `project_id` / `unlink_project`. Lines: `add_services` (same shape as invoices_create_draft), `remove_services` (by line name) and `update_services` (edit a line in place by `line_number`: `description`, `details`, `quantity`, `unit_price`). Line numbers are positions from invoices_get, resolved after `remove_services` and before `add_services`; an out-of-range number is refused and nothing is written. Totals, tax and paid state are re-derived. It sends nothing. Only drafts are editable by default; a sent invoice is refused unless `allow_non_draft: true`, since the edit changes what the customer sees at the public invoice link. A locked invoice (a payment or credit recorded, or any sent invoice when the workspace locks on send) is always refused. Payment state (see payments_record), status, number, client and currency never change.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string","minLength":1,"description":"Invoice document id. Pass this or `invoice_number`."},"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'. Pass this or `invoice_id`."},"notes":{"type":"string","description":"Replaces the notes printed on the invoice."},"discount_percent":{"type":"number","minimum":0,"maximum":100,"description":"Discount as a percentage; 0 removes it. Use this or `discount_amount`."},"discount_amount":{"type":"number","minimum":0,"description":"Discount as a fixed amount; 0 removes it. Use this or `discount_percent`."},"add_services":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."}},"additionalProperties":false},"description":"Lines to add: {product_id, quantity} or {description, unit_price, quantity}."},"remove_services":{"type":"array","items":{"type":"string","minLength":1},"description":"Line names to remove (case-insensitive substring match)."},"update_services":{"type":"array","items":{"type":"object","properties":{"line_number":{"type":"integer","minimum":1,"maximum":200,"description":"1-based position of the line, as returned by invoices_get."},"description":{"type":"string","minLength":1,"maxLength":500,"description":"New line name."},"details":{"type":"string","maxLength":5000,"description":"New printed description; \"\" clears it."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"New number of units."},"unit_price":{"type":"number","minimum":0,"description":"New price of one unit."}},"required":["line_number"],"additionalProperties":false},"maxItems":50,"description":"Edit existing lines in place by `line_number` (from invoices_get)."},"timezone":{"type":"string","maxLength":64,"description":"IANA time zone that decides which day \"today\" is for the dates."},"invoice_date":{"type":"string","minLength":1,"maxLength":10,"description":"Issue date, MM/DD/YYYY; defaults to today on create."},"due_date":{"type":"string","minLength":1,"maxLength":10,"description":"Due date, MM/DD/YYYY. Use this or `due_in_days`."},"due_in_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days from the issue date until due; 0 = due on receipt."},"payment_term":{"type":"string","maxLength":120,"description":"Printed term label (e.g. \"Net 30\"); does not compute the due date."},"tax_percent":{"type":"number","minimum":0,"maximum":100,"description":"Tax as a percentage of the post-discount subtotal. Use this or `tax_amount`."},"tax_amount":{"type":"number","minimum":0,"description":"Tax as a fixed amount. Use this or `tax_percent`."},"deposit_percent":{"type":"number","minimum":0,"maximum":100,"description":"Request a deposit of this percentage of the total; 0 disables it."},"project_id":{"type":"string","minLength":1,"maxLength":200,"description":"Link the invoice to a project."},"unlink_project":{"type":"boolean","description":"true removes the project link."},"allow_non_draft":{"type":"boolean","description":"Allow editing an already-sent (unlocked) invoice; it changes what the customer sees."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"total":{"type":"number","nullable":true}},"required":["id","status","total"],"additionalProperties":false,"nullable":true},"changed":{"type":"boolean"},"changes":{"type":"array","items":{"type":"string"}}},"required":["invoice","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoice_payments_list":{"post":{"operationId":"invoice_payments_list","summary":"List invoice payments","description":"List the payments recorded against one invoice (amount, method, date, status, reference, notes) plus the invoice total, total paid and remaining balance. Identify the invoice by `invoice_id` or `invoice_number` (e.g. '26-6'). Proposals/estimates, unknown identifiers and invoices outside a scoped member's clients all return 'not found'. Monetary fields are null without the invoices.view_prices permission. Read-only. For totals only use invoice_payments_summary; to record a payment use payments_record.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string","minLength":1,"description":"Invoice document id. Pass this or `invoice_number`."},"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string"},"payments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"amount":{"type":"number","nullable":true},"refund_amount":{"type":"number","nullable":true},"net_amount":{"type":"number","nullable":true},"method":{"type":"string"},"status":{"type":"string"},"date":{"type":"number"},"reference":{"type":"string"},"notes":{"type":"string"}},"required":["id","amount","refund_amount","net_amount","method","status","date"],"additionalProperties":false}},"invoice_total":{"type":"number","nullable":true},"total_paid":{"type":"number","nullable":true},"remaining_balance":{"type":"number","nullable":true}},"required":["invoice_id","payments","invoice_total","total_paid","remaining_balance"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoice_payments_summary":{"post":{"operationId":"invoice_payments_summary","summary":"Invoice payment summary","description":"Payment summary for one invoice: total received, refunded, net, payment count, amounts by method, invoice total and remaining balance. Identify the invoice by `invoice_id` or `invoice_number`. Proposals/estimates, unknown identifiers and out-of-scope invoices return 'not found'. Monetary fields are null (and by-method omitted) without the invoices.view_prices permission. Read-only. For the individual payments use invoice_payments_list.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string","minLength":1,"description":"Invoice document id. Pass this or `invoice_number`."},"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string"},"status":{"type":"string"},"payment_count":{"type":"number"},"total_received":{"type":"number","nullable":true},"total_refunded":{"type":"number","nullable":true},"net_received":{"type":"number","nullable":true},"invoice_total":{"type":"number","nullable":true},"remaining_balance":{"type":"number","nullable":true},"by_method":{"type":"object","additionalProperties":{"type":"number"}}},"required":["invoice_id","status","payment_count","total_received","total_refunded","net_received","invoice_total","remaining_balance"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/payments_record":{"post":{"operationId":"payments_record","summary":"Record an invoice payment","description":"Record a payment against an invoice (full, general or partial); this is how an invoice becomes paid. Identify the invoice by `invoice_id` or `invoice_number`. Needs a positive `amount` and a `payment_method` (Cash, Check, Credit Card, Bank Transfer or Other). `payment_date` (\"YYYY-MM-DD\") defaults to now; a date inside a closed accounting period is refused. The amount cannot exceed the outstanding balance. `partial: true` requires an amount below the invoice total. `installment_id` settles a payment-plan installment. The invoice's paid state is re-derived server-side; invoice pricing is not edited. The payment lands in the invoice's activity log and sends the invoice.* webhook events to any webhook URLs the workspace has set up, as a payment recorded in the app does. Nothing is charged and nothing is sent to the client. A repeat call with the same `idempotency_key` does not record the payment twice.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_id":{"type":"string","minLength":1,"description":"Invoice document id. Pass this or `invoice_number`."},"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'."},"amount":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Amount received; positive and not above the outstanding balance."},"payment_method":{"type":"string","enum":["Cash","Check","Credit Card","Bank Transfer","Other"],"description":"How the payment was made."},"notes":{"type":"string","description":"Notes about the payment."},"payment_reference":{"type":"string","description":"Reference such as a check number or transaction id."},"partial":{"type":"boolean","description":"true for a partial payment; the amount must then be below the invoice total."},"payment_date":{"type":"string","minLength":1,"maxLength":40,"description":"When the money came in, YYYY-MM-DD; defaults to now. A closed accounting period is refused."},"installment_id":{"type":"string","minLength":1,"maxLength":200,"description":"Payment-plan installment this payment settles."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["amount","payment_method"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"payment":{"type":"object","properties":{"id":{"type":"string"},"amount":{"type":"number"},"method":{"type":"string"},"date":{"type":"number"},"installment_id":{"type":"string"}},"required":["id","amount","method"],"additionalProperties":false},"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"client_name":{"type":"string"},"status":{"type":"string"},"is_paid":{"type":"boolean"},"total_paid":{"type":"number"},"balance_due":{"type":"number"}},"required":["id","status","is_paid","total_paid","balance_due"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["payment","invoice"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/notes_update":{"post":{"operationId":"notes_update","summary":"Update a note","description":"Update a note by `id` (from notes_search): `title`, `body` (replaces the whole body; markdown becomes the editor's formatting) or `tags` (REPLACES the tag list). Only the fields passed change. Works on workspace notes, client notes (needs permission to edit clients) and the caller's personal notes. Trashed notes are not editable, and a password-protected note's `body` cannot be changed here. Returns the updated `note`. To add a new note use notes_create.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"notes:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Note id (notes_search)."},"title":{"type":"string","minLength":1,"description":"New title."},"body":{"type":"string","description":"New full text; replaces the whole body."},"tags":{"type":"array","items":{"type":"string"},"description":"Replaces the tag list."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"folder_id":{"type":"string"}},"required":["id","title","folder_id"],"additionalProperties":false}},"required":["note"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/projects_update":{"post":{"operationId":"projects_update","summary":"Update a project","description":"Update a project by `id` (from projects_search): `name`, `description`, `status` (planning, in_progress, on_hold, completed, cancelled), `budget`, `priority` (low, medium, high, critical) or `notes`. Only the fields passed change. Progress cannot be set; it is derived from task completion. Moving to in_progress or completed stamps the actual start/end dates. Returns the updated `project`. To add a project use projects_create.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"projects:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Project id (projects_search)."},"name":{"type":"string","minLength":1,"description":"New name."},"description":{"type":"string","description":"New description."},"status":{"type":"string","enum":["planning","in_progress","on_hold","completed","cancelled"],"description":"planning, in_progress, on_hold, completed or cancelled."},"budget":{"type":"number","minimum":0,"description":"New budget."},"priority":{"type":"string","enum":["low","medium","high","critical"],"description":"low, medium, high or critical."},"notes":{"type":"string","description":"New notes."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false}},"required":["project"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/reminders_create":{"post":{"operationId":"reminders_create","summary":"Create a reminder","description":"Create a reminder: a notification that fires at a single point in time. It is not a calendar event, which occupies a time range with a start and an end. A standalone reminder needs a `title` and an ISO-8601 `remind_at`. For a reminder tied to a calendar event, pass the `event_id` from calendar_create_event or calendar_list_events and `minutes_before` (1440 = 24 hours); this creates a workspace reminder linked to the event and notifies the caller by default. `event_id` with `remind_at` sets an absolute time instead. For all-day events, `time_zone` applies: 24 hours before means 24 elapsed hours before midnight at the start of that date in that zone, not 9 AM. `reminder_type` is `personal` (default, notifies only the caller) or `workspace` (notifies the team members in `recipients` via `channels`, default push). Recipients are team-member names or emails; a non-member email must be saved on the client named in `client_id` or be a workspace address, otherwise the reminder is refused. Unmatched recipients are listed in `unresolved_recipients`. `recurrence` repeats it daily, weekly, monthly or yearly. A repeat call with the same `idempotency_key` is safe.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"reminders:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"What to be reminded of."},"remind_at":{"type":"string","minLength":1,"description":"When to fire, an ISO-8601 datetime. Natural language is refused."},"event_id":{"type":"string","minLength":1,"description":"A calendar event's id (from calendar_create_event or calendar_list_events) to link the reminder to."},"minutes_before":{"type":"integer","minimum":0,"maximum":525600,"description":"With `event_id`: how long before the event to fire, in minutes (1440 = 24 hours)."},"time_zone":{"type":"string","description":"IANA time zone used to place a reminder for an all-day event."},"description":{"type":"string","description":"Longer text shown with the reminder."},"priority":{"type":"string","enum":["low","medium","high"],"description":"Reminder priority."},"reminder_type":{"type":"string","enum":["personal","workspace"],"description":"`personal` (default) notifies only the caller; `workspace` notifies the team members in `recipients`."},"recipients":{"type":"array","items":{"type":"string"},"description":"Team-member names or emails to notify. A non-member email must be saved on `client_id` or be a workspace address."},"client_id":{"type":"string","description":"A client whose saved emails may be named in `recipients`."},"channels":{"type":"array","items":{"type":"string","enum":["push","email","sms"]},"description":"Delivery channels for workspace reminders. Default push."},"recurrence":{"type":"string","enum":["none","daily","weekly","monthly","yearly"],"description":"Repeat the reminder: none, daily, weekly, monthly or yearly."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["title"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"reminder":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"remind_at":{"type":"number"},"event_id":{"type":"string"},"event_title":{"type":"string"},"scope":{"type":"string","enum":["personal","workspace"]},"priority":{"type":"string"},"channels":{"type":"array","items":{"type":"string"}},"recurrence":{"type":"string"},"recipients":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["teamMember","custom"]},"name":{"type":"string"},"email":{"type":"string"}},"required":["type"],"additionalProperties":false}},"unresolved_recipients":{"type":"array","items":{"type":"string"}}},"required":["id","title","remind_at","scope","priority","channels"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["reminder","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/reminders_list":{"post":{"operationId":"reminders_list","summary":"List reminders","description":"List the caller's reminders, sorted by time (up to `limit`, default 25, max 100), with the ids reminders_close needs. `filter`: upcoming (default; pending, future), overdue (pending, past), completed (ticked off via reminders_close with intent `complete`) or all (everything not canceled). `scope`: personal, workspace or all (default). Each row has `done`; the status value `sent` means delivered, not done. Read-only. Returns `reminders`; to change one use reminders_update.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"reminders:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filter":{"type":"string","enum":["upcoming","overdue","completed","all"],"description":"upcoming (default), overdue, completed or all."},"scope":{"type":"string","enum":["personal","workspace","all"],"description":"personal, workspace or all (default)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"reminders":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"remind_at":{"type":"number"},"event_id":{"type":"string"},"event_title":{"type":"string"},"scope":{"type":"string","enum":["personal","workspace"]},"status":{"type":"string"},"done":{"type":"boolean"},"priority":{"type":"string"},"description":{"type":"string"},"recurrence":{"type":"string"},"recipient_count":{"type":"number"}},"required":["id","title","scope","status","done","priority"],"additionalProperties":false}}},"required":["reminders"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/reminders_close":{"post":{"operationId":"reminders_close","summary":"Close a reminder","description":"Close a reminder by `id` (from reminders_list) so it will not fire. `intent` `complete` ticks it off (shown under Completed); `cancel` dismisses it (shown under Canceled, struck through). For a recurring reminder, `complete` closes the whole series, not only the occurrence that is due. Returns the closed `reminder`. To change a reminder instead of closing it, use reminders_update.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"reminders:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Reminder id (reminders_list)."},"intent":{"type":"string","enum":["complete","cancel"],"description":"complete ticks it off; cancel dismisses it."}},"required":["id","intent"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"reminder":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"intent":{"type":"string"}},"required":["id","title","status","intent"],"additionalProperties":false}},"required":["reminder"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/reminders_update":{"post":{"operationId":"reminders_update","summary":"Update a reminder","description":"Change an existing reminder by `id` (from reminders_list): `title`, `description`, `remind_at` (ISO-8601), `priority` or `channels`. Only the fields passed change. There is no separate snooze action: moving `remind_at` postpones a reminder and re-arms delivery, so one that already fired fires again at the new time. Editing keeps the reminder's id and its link to the invoice or task it came from, whereas closing and re-creating gives a new id and files the original under Canceled. A completed or canceled reminder cannot be edited. Times are ISO-8601 only.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"reminders:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The reminder's id (from reminders_list)."},"title":{"type":"string","minLength":1,"description":"New title."},"description":{"type":"string","description":"New description."},"remind_at":{"type":"string","description":"New time, an ISO-8601 datetime. Moving it postpones the reminder and re-arms delivery."},"priority":{"type":"string","enum":["low","medium","high"],"description":"New priority."},"channels":{"type":"array","items":{"type":"string","enum":["push","email","sms"]},"description":"New delivery channels."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"reminder":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"remind_at":{"type":"number"}},"required":["id","title"],"additionalProperties":false},"changes":{"type":"array","items":{"type":"string"}}},"required":["reminder","changes"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_update_draft":{"post":{"operationId":"proposals_update_draft","summary":"Update a draft proposal","description":"Edit an existing draft proposal, identified by `proposal_id`. Changeable: `title`, internal `notes` (replaced), `add_line_items` (same grammar as proposals_create_draft), `remove_line_items` (by line name), discount (`discount_percent` or `discount_amount`; 0 removes it), signature requirement, deposit (`deposit_percent` or `deposit_amount`; `require_deposit: false` removes it) and expiry (`valid_for_days`; 0 removes it). When lines, discount or deposit change, subtotal, tax (at the proposal's rate, or a product's own rate, on the post-discount subtotal), total and deposit are re-derived server-side; other edits leave the money unchanged. Only drafts are editable: a sent, accepted or declined proposal is refused (recall a sent one to draft with proposals_update_status or in the app), and an accepted or deposit-paid proposal is locked and changes only through a change order in the app. It cannot send, accept, decline, convert, delete, change the client or tax rate, or edit layout, theme or sections. Repeating `add_line_items` adds the lines twice.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","minLength":1,"description":"Draft proposal id (from proposals_create_draft or proposals_search)."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"New title."},"notes":{"type":"string","maxLength":5000,"description":"Replaces the internal notes."},"add_line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."},"optional":{"type":"boolean","description":"true: a client-selectable add-on on the public page; use only on `product_id` lines."},"group":{"type":"string","maxLength":80,"description":"Group label; adjacent lines sharing one render under a header."}},"additionalProperties":false},"maxItems":100,"description":"Lines to add: {product_id, quantity} or {description, unit_price, quantity}."},"remove_line_items":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":50,"description":"Line names to remove."},"discount_percent":{"type":"number","minimum":0,"maximum":100,"description":"Discount as a percentage; 0 removes it. Use this or `discount_amount`."},"discount_amount":{"type":"number","minimum":0,"description":"Discount as a fixed amount; 0 removes it."},"require_signature":{"type":"boolean","description":"Whether accepting requires a signature."},"deposit_percent":{"type":"number","minimum":0,"maximum":100,"description":"Deposit as a percentage of the total. Use this or `deposit_amount`."},"deposit_amount":{"type":"number","minimum":0,"description":"Deposit as a fixed amount."},"require_deposit":{"type":"boolean","description":"false removes the deposit requirement."},"valid_for_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days until the proposal expires; 0 removes the expiry."}},"required":["proposal_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"currency":{"type":"string"},"sub_total":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"line_item_count":{"type":"number"},"requires_signature":{"type":"boolean"},"requires_deposit":{"type":"boolean"},"valid_until":{"type":"number","nullable":true}},"required":["id","status","sub_total","total","deposit_amount","line_item_count","requires_signature","requires_deposit","valid_until"],"additionalProperties":false,"nullable":true},"changed":{"type":"boolean"},"changes":{"type":"array","items":{"type":"string"}}},"required":["proposal","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_update_status":{"post":{"operationId":"proposals_update_status","summary":"Record a proposal's outcome","description":"Record what happened to a sent proposal: `intent` \"accepted\" or \"declined\" when the client answered off-system (call, meeting, email), or \"draft\" to recall it so it can be edited again. `reason` is recorded only on a decline. Only a sent proposal can change state, the same rule as the Proposals screen. Marking accepted does not store a signature or typed name; those are written only when the client accepts through the public link. A locked proposal (accepted, or deposit paid) cannot be recalled or declined. This does not send anything and does not create an invoice.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","minLength":1,"description":"Sent proposal id (from proposals_search)."},"intent":{"type":"string","enum":["accepted","declined","draft"],"description":"accepted or declined (the client answered off-system), or draft to recall it."},"reason":{"type":"string","maxLength":500,"description":"Recorded only on a decline."}},"required":["proposal_id","intent"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string"},"title":{"type":"string"},"client_name":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"previous_status":{"type":"string"}},"required":["proposal_id","status","previous_status"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_get_defaults":{"post":{"operationId":"proposals_get_defaults","summary":"Get proposal defaults","description":"Read the acceptance terms of proposals: whether accepting requires a signature, whether it requires a deposit (and how much), and when it expires. With no arguments it returns the workspace defaults that seed new proposals (including `validity_days`); with `proposal_id` it also returns that proposal's effective terms (`valid_until` is an actual date) and the deposit amount resolved against its current total. Monetary values are null without the invoices.view_prices permission; whether a deposit is required is always visible. Scoped members see only their assigned clients.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","minLength":1,"description":"Also return this proposal's effective terms."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"workspace_defaults":{"type":"object","properties":{"require_signature":{"type":"boolean"},"require_deposit":{"type":"boolean"},"deposit_type":{"type":"string"},"deposit_value":{"type":"number","nullable":true},"valid_until":{"type":"number","nullable":true},"validity_days":{"type":"number","nullable":true},"theme":{"type":"string"},"accent_color":{"type":"string"},"notes_footer":{"type":"string"}},"required":["require_signature","require_deposit","deposit_type","deposit_value","valid_until","validity_days","theme","accent_color","notes_footer"],"additionalProperties":false},"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"require_signature":{"type":"boolean"},"require_deposit":{"type":"boolean"},"deposit_type":{"type":"string"},"deposit_value":{"type":"number","nullable":true},"valid_until":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"uses_workspace_defaults":{"type":"boolean"}},"required":["id","require_signature","require_deposit","deposit_type","deposit_value","valid_until","total","deposit_amount","uses_workspace_defaults"],"additionalProperties":false,"nullable":true}},"required":["workspace_defaults"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_design_options":{"post":{"operationId":"proposals_design_options","summary":"List proposal design options","description":"List what a proposal's design can be set to: themes (font, default accent), accent presets, page backgrounds, cover styles, title placements, gallery layouts, section types, the 18 cover banners (id, name, preview_url) and the photo gallery categories. `gallery_category` pages through that category's photos (12 at a time; pass `cursor` = next_cursor for more); a photo's `path` is the `gallery_path` for proposals_update_design or proposals_edit_sections. It changes nothing.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"gallery_category":{"type":"string","enum":["abstract","cosmic","desktop","earth","mystic-gradients","paper-glass","radiant","tahoe-desktop"],"description":"Page through this gallery category's photos."},"cursor":{"type":"string","maxLength":200,"description":"The `next_cursor` value from the previous gallery response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"themes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"font":{"type":"string"},"default_accent":{"type":"string"}},"required":["id","name","font","default_accent"],"additionalProperties":false}},"accent_presets":{"type":"array","items":{"type":"string"}},"page_backgrounds":{"type":"array","items":{"type":"object","properties":{"hex":{"type":"string"},"name":{"type":"string"},"is_default":{"type":"boolean"}},"required":["hex","name","is_default"],"additionalProperties":false}},"cover_image_styles":{"type":"array","items":{"type":"string"}},"title_placements":{"type":"array","items":{"type":"string"}},"image_layouts":{"type":"array","items":{"type":"string"}},"section_types":{"type":"array","items":{"type":"string"}},"banners":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"preview_url":{"type":"string","nullable":true}},"required":["id","name","preview_url"],"additionalProperties":false}},"gallery_categories":{"type":"array","items":{"type":"string"}},"gallery":{"type":"object","properties":{"images":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"title":{"type":"string"},"preview_url":{"type":"string"}},"required":["path","title","preview_url"],"additionalProperties":false}},"next_cursor":{"type":"string","nullable":true}},"required":["images","next_cursor"],"additionalProperties":false}},"required":["themes","accent_presets","page_backgrounds","cover_image_styles","title_placements","image_layouts","section_types","banners","gallery_categories"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_update_design":{"post":{"operationId":"proposals_update_design","summary":"Change a proposal's design","description":"Change how a draft proposal looks (the editor's Design tab). `theme` (modern, minimal, classic or bold) sets fonts and spacing. Changing `theme` without `accent_color` resets the accent to the theme's default, as the editor does; pass both to keep a custom colour. `accent_color` is hex. `page_background_color` is the backdrop around the paper (hex or \"default\"). `title_placement`: on_image puts the title over the cover; below_image shows the image as a banner with the title under it. `cover_image`: source: \"banner\" + banner_id, source: \"gallery\" + gallery_path, source: \"workspace_file\" + storage_path, source: \"url\" + an https image link (downloaded into the workspace), or source: \"none\" to remove it. `cover_image_style`: fill, inset or fade. `cover_focal_point`: 0 (top) to 100 (bottom). Options come from proposals_design_options. Only drafts can be changed. Returns `previous_design`, so a change can be undone by sending those values back. A call that fetches a web link is held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","x-approval-conditional":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","minLength":1,"description":"Draft proposal id (from proposals_create_draft or proposals_search)."},"theme":{"type":"string","enum":["modern","minimal","classic","bold"],"description":"Theme id; sets fonts and spacing."},"accent_color":{"type":"string","maxLength":16,"description":"Accent colour, hex."},"page_background_color":{"type":"string","maxLength":16,"description":"Backdrop around the paper: hex or \"default\"."},"title_placement":{"type":"string","enum":["on_image","below_image"],"description":"on_image puts the title over the cover; below_image puts it under a banner."},"cover_image":{"type":"object","properties":{"source":{"type":"string","enum":["banner","gallery","workspace_file","url","none"]},"banner_id":{"type":"string","enum":["sage-arches","terracotta-studio","coastal-layers","midnight-orbit","paper-fold","botanical-study","cobalt-grid","sandstone-steps","rose-colonnade","lagoon-gate","ochre-fan","indigo-tide","olive-terraces","plum-ridge","slate-cairn","canyon-mesa","pine-hollow","graphite-contours"],"description":"With source \"banner\": the banner id (proposals_design_options)."},"gallery_path":{"type":"string","maxLength":300,"description":"With source \"gallery\": the photo's path (proposals_design_options)."},"storage_path":{"type":"string","maxLength":500,"description":"With source \"workspace_file\": path of an image in the workspace's files."},"url":{"type":"string","maxLength":2000,"description":"With source \"url\": an https image link, downloaded into the workspace."}},"required":["source"],"additionalProperties":false,"description":"Cover image source; source \"none\" removes it."},"cover_image_style":{"type":"string","enum":["fill","inset","fade"],"description":"How the cover is drawn."},"cover_focal_point":{"type":"integer","minimum":0,"maximum":100,"description":"0 (top) to 100 (bottom)."}},"required":["proposal_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string"},"design":{"type":"object","properties":{"theme":{"type":"string"},"accent_color":{"type":"string"},"page_background_color":{"type":"string"},"title_placement":{"type":"string"},"cover_image":{"type":"object","properties":{"url":{"type":"string"},"path":{"type":"string"},"source":{"type":"string"},"banner_id":{"type":"string"},"gallery_path":{"type":"string"},"storage_path":{"type":"string"}},"required":["url","path"],"additionalProperties":false,"nullable":true},"cover_image_style":{"type":"string"},"cover_focal_point":{"type":"number"}},"required":["theme","accent_color","page_background_color","title_placement","cover_image","cover_image_style","cover_focal_point"],"additionalProperties":false},"previous_design":{"type":"object","properties":{"theme":{"type":"string"},"accent_color":{"type":"string"},"page_background_color":{"type":"string"},"title_placement":{"type":"string"},"cover_image":{"type":"object","properties":{"url":{"type":"string"},"path":{"type":"string"},"source":{"type":"string"},"banner_id":{"type":"string"},"gallery_path":{"type":"string"},"storage_path":{"type":"string"}},"required":["url","path"],"additionalProperties":false,"nullable":true},"cover_image_style":{"type":"string"},"cover_focal_point":{"type":"number"}},"required":["theme","accent_color","page_background_color","title_placement","cover_image","cover_image_style","cover_focal_point"],"additionalProperties":false},"changes":{"type":"array","items":{"type":"string"}}},"required":["proposal_id","design","previous_design","changes"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_edit_sections":{"post":{"operationId":"proposals_edit_sections","summary":"Edit a proposal's sections","description":"Add, change, reorder or remove a draft proposal's sections (the editor's blocks); proposals_get returns the section ids. Four fixed sections lead every proposal (cover, header, line_items = the pricing table, totals): they cannot be removed or moved, and only the pricing table's `title` changes. Content sections: text (markdown `body`), timeline (`timeline` rows of {date, description}), terms (plain-text `body`, or `terms_id` from the terms library) and images (`images` replaces the gallery; `image_layout` grid, masonry, hero, stacked, showcase, comparison or carousel). Each image is {source, caption?, alt?} with source banner, gallery, workspace_file or url (an https link, downloaded into the workspace). `highlighted` tints a content section with the accent. `after_section_id` places an added or moved section (a fixed section's id = top of the content). `from_section_template_id` inserts a saved section (proposal_templates_list). Up to 20 operations run in order, all or nothing. Only drafts can be changed. A call that fetches a web link is held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","x-approval-conditional":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","minLength":1,"description":"Draft proposal id (from proposals_create_draft or proposals_search)."},"operations":{"type":"array","items":{"type":"object","properties":{"op":{"type":"string","enum":["add","update","remove","move"]},"section_id":{"type":"string","maxLength":100},"type":{"type":"string","enum":["text","timeline","terms","images"]},"from_section_template_id":{"type":"string","maxLength":100},"after_section_id":{"type":"string","maxLength":100},"title":{"type":"string","maxLength":200},"body":{"type":"string","maxLength":20000},"highlighted":{"type":"boolean"},"image_layout":{"type":"string","enum":["grid","masonry","hero","stacked","showcase","comparison","carousel"]},"images":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","enum":["banner","gallery","workspace_file","url"],"description":"Where the image comes from: a cover banner, a gallery photo, a workspace file, or an https url."},"banner_id":{"type":"string","enum":["sage-arches","terracotta-studio","coastal-layers","midnight-orbit","paper-fold","botanical-study","cobalt-grid","sandstone-steps","rose-colonnade","lagoon-gate","ochre-fan","indigo-tide","olive-terraces","plum-ridge","slate-cairn","canyon-mesa","pine-hollow","graphite-contours"],"description":"With source \"banner\": the banner id (proposals_design_options)."},"gallery_path":{"type":"string","maxLength":300,"description":"With source \"gallery\": the photo's path (proposals_design_options)."},"storage_path":{"type":"string","maxLength":500,"description":"With source \"workspace_file\": path of an image in the workspace's files."},"url":{"type":"string","maxLength":2000,"description":"With source \"url\": an https image link, downloaded into the workspace."},"caption":{"type":"string","maxLength":500},"alt":{"type":"string","maxLength":180}},"required":["source"],"additionalProperties":false},"maxItems":24},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","maxLength":80},"description":{"type":"string","maxLength":1000}},"required":["date","description"],"additionalProperties":false},"maxItems":50},"terms_id":{"type":"string","maxLength":100}},"required":["op"],"additionalProperties":false},"minItems":1,"maxItems":20,"description":"Up to 20 operations, run in order, all or nothing."}},"required":["proposal_id","operations"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string"},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"title":{"type":"string","nullable":true},"highlighted":{"type":"boolean"},"count":{"type":"number"}},"required":["id","type","title","highlighted"],"additionalProperties":false}},"added":{"type":"array","items":{"type":"string"}},"changes":{"type":"array","items":{"type":"string"}}},"required":["proposal_id","sections","added","changes"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_list":{"post":{"operationId":"proposal_templates_list","summary":"List proposal templates","description":"List the workspace's proposal templates (id, name, theme, accent, section and line counts) and saved sections (id, name, type). `kind`: proposal, section or all (default). Templates start a proposal via proposals_create_draft `template_id`, apply to a draft via proposal_templates_apply, and saved sections insert via proposals_edit_sections `from_section_template_id`. Read-only.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["proposal","section","all"],"description":"proposal, section or all (default)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal_templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"used_count":{"type":"number"},"updated_at":{"type":"number"},"theme":{"type":"string"},"accent_color":{"type":"string"},"section_count":{"type":"number"},"line_item_count":{"type":"number"}},"required":["id","name","description","used_count","updated_at","theme","accent_color","section_count","line_item_count"],"additionalProperties":false}},"section_templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"used_count":{"type":"number"}},"required":["id","name","type","used_count"],"additionalProperties":false}}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_save_from_proposal":{"post":{"operationId":"proposal_templates_save_from_proposal","summary":"Save a proposal as a template","description":"Saves a proposal's sections, design, settings and line items as a new reusable proposal template and returns its `template_id`. The proposal itself is not changed. Each call creates another template. To save a single section use proposal_templates_save_section. Use this tool to keep a finished proposal as a starting point; apply a saved one with proposal_templates_apply. It creates a template and changes nothing existing. Needs the proposals.manage_templates permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","maxLength":100,"description":"The proposal to save from."},"name":{"type":"string","minLength":1,"maxLength":120,"description":"The new template's name."},"description":{"type":"string","maxLength":500,"description":"The new template's description."}},"required":["proposal_id","name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_save_section":{"post":{"operationId":"proposal_templates_save_section","summary":"Save a proposal section as a template","description":"Saves one content section of a proposal as a reusable section template and returns its `section_template_id`. The proposal itself is not changed. Each call creates another section template. To save the whole proposal use proposal_templates_save_from_proposal. Use this tool to keep one section for reuse; apply a saved one with proposal_templates_apply. It creates a template and changes nothing existing. Needs the proposals.manage_templates permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string","maxLength":100,"description":"The proposal the section is in."},"section_id":{"type":"string","maxLength":100,"description":"The section to save (proposals_get)."},"name":{"type":"string","minLength":1,"maxLength":120,"description":"The section template's name."}},"required":["proposal_id","section_id","name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"section_template_id":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_apply":{"post":{"operationId":"proposal_templates_apply","summary":"Apply a template to a draft proposal","description":"Replaces a draft proposal's sections, design and settings with a template's, and its line items too unless replace_line_items is false. Totals are re-derived; the client, title and notes are kept. Only drafts can be changed. Returns `proposal_id` and the re-derived `total` and `deposit_amount` (null without the invoices.view_prices permission). Overwrites the draft's content; find templates with proposal_templates_list. Needs permission to edit proposals, not to manage templates.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string","maxLength":100,"description":"The template's id (proposal_templates_list)."},"proposal_id":{"type":"string","maxLength":100,"description":"The draft proposal to apply it to."},"replace_line_items":{"type":"boolean","description":"Also replace the draft's line items (default true)."}},"required":["template_id","proposal_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal_id":{"type":"string"},"total":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_rename":{"post":{"operationId":"proposal_templates_rename","summary":"Rename a proposal template","description":"Renames a proposal template, or a saved section template when `template_kind` is section. Returns `template_id`. The template's content is unchanged. To use one on a draft call proposal_templates_apply. Needs the proposals.manage_templates permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string","maxLength":100,"description":"The template's id (proposal_templates_list)."},"name":{"type":"string","minLength":1,"maxLength":120,"description":"The new name."},"template_kind":{"type":"string","enum":["proposal","section"],"description":"proposal (default) for a whole-proposal template, section for a saved section."}},"required":["template_id","name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_duplicate":{"post":{"operationId":"proposal_templates_duplicate","summary":"Duplicate a proposal template","description":"Copies a proposal template into a new template, named `name` or after the original, and returns the copy's `template_id`. Each call makes another copy. Section templates cannot be duplicated. Needs the proposals.manage_templates permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string","maxLength":100,"description":"The template's id (proposal_templates_list)."},"name":{"type":"string","minLength":1,"maxLength":120,"description":"The copy's name."}},"required":["template_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposal_templates_delete":{"post":{"operationId":"proposal_templates_delete","summary":"Delete a proposal template","description":"Deletes a proposal template or section template from the library. Proposals already made from it are not changed. Returns `deleted`. Needs the proposals.manage_templates permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string","maxLength":100,"description":"The template's id (proposal_templates_list)."},"template_kind":{"type":"string","enum":["proposal","section"],"description":"proposal (default) for a whole-proposal template, section for a saved section."}},"required":["template_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/proposals_update_defaults":{"post":{"operationId":"proposals_update_defaults","summary":"Change proposal defaults","description":"Change the workspace's proposal defaults (Settings > Proposals): `theme` and `accent_color` for new proposals, `require_signature`, the deposit (`require_deposit`, `deposit_type` percentage or amount, `deposit_value`), `validity_days` (0 = no expiry) and `notes_footer` (pre-fills a new proposal's internal notes). Defaults apply to new blank proposals only; existing proposals and templates are unchanged. proposals_get_defaults reads the current values.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"theme":{"type":"string","enum":["modern","minimal","classic","bold"],"description":"Default theme for new proposals."},"accent_color":{"type":"string","maxLength":16,"description":"Default accent colour, hex."},"require_signature":{"type":"boolean","description":"Whether new proposals require a signature."},"require_deposit":{"type":"boolean","description":"Whether new proposals require a deposit."},"deposit_type":{"type":"string","enum":["percentage","amount"],"description":"percentage or amount."},"deposit_value":{"type":"number","minimum":0,"maximum":1000000,"description":"Deposit percentage or amount, per `deposit_type`."},"validity_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days new proposals stay open; 0 = no expiry."},"notes_footer":{"type":"string","maxLength":5000,"description":"Pre-fills a new proposal's internal notes."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"defaults":{"type":"object","properties":{"theme_key":{"type":"string"},"accent_color":{"type":"string"},"require_signature":{"type":"boolean"},"require_deposit":{"type":"boolean"},"deposit_type":{"type":"string"},"deposit_value":{"type":"number","nullable":true},"validity_days":{"type":"number"},"notes_footer":{"type":"string"}},"required":["theme_key","accent_color","require_signature","require_deposit","deposit_type","deposit_value","notes_footer"],"additionalProperties":false}},"required":["defaults"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/invoices_get_defaults":{"post":{"operationId":"invoices_get_defaults","summary":"Get invoice defaults","description":"Read the workspace's Invoice Defaults, the terms applied to every new invoice: payment timing (`due_in_days` and the `due_date_preview` an invoice created today would get), the payment-term label, tax (none, a percentage, a fixed amount, or the default tax code), discount, whether a deposit is requested and at what percentage, and the default notes. invoices_create_draft applies these unless told otherwise. Existing invoices are not affected. Rates and amounts are null without the invoices.view_prices permission (`prices_visible` says which); the modes are still returned. `tax_code_unresolved: true` means tax-code mode is selected but no active default tax code is set, so new invoices are untaxed. Changing these settings is not possible from any tool.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timezone":{"type":"string","maxLength":64,"description":"IANA time zone that decides which day \"today\" is for `due_date_preview`."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"defaults":{"type":"object","properties":{"due_in_days":{"type":"integer"},"due_date_preview":{"type":"string"},"payment_term":{"type":"string"},"tax":{"type":"object","properties":{"mode":{"type":"string","enum":["none","percentage","fixed","taxCode"]},"percent":{"type":"number","nullable":true},"amount":{"type":"number","nullable":true},"tax_code":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"total_rate":{"type":"number","nullable":true}},"required":["id","name","total_rate"],"additionalProperties":false,"nullable":true},"tax_code_unresolved":{"type":"boolean"}},"required":["mode","percent","amount","tax_code","tax_code_unresolved"],"additionalProperties":false},"discount":{"type":"object","properties":{"mode":{"type":"string","enum":["none","percentage","fixed"]},"percent":{"type":"number","nullable":true},"amount":{"type":"number","nullable":true}},"required":["mode","percent","amount"],"additionalProperties":false},"deposit":{"type":"object","properties":{"enabled":{"type":"boolean"},"percent":{"type":"number","nullable":true}},"required":["enabled","percent"],"additionalProperties":false},"notes":{"type":"string"},"terms_conditions_id":{"type":"string"},"pdf_template_name":{"type":"string"},"accepted_payment_methods":{"type":"string"},"attachment_count":{"type":"integer"},"is_empty":{"type":"boolean"}},"required":["due_in_days","due_date_preview","payment_term","tax","discount","deposit","notes","terms_conditions_id","pdf_template_name","accepted_payment_methods","attachment_count","is_empty"],"additionalProperties":false},"prices_visible":{"type":"boolean"}},"required":["defaults","prices_visible"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/after_payment_get":{"post":{"operationId":"after_payment_get","summary":"Read the after-payment page","description":"Read the after-payment page (Settings > After payment) clients see once they pay an invoice, pay link, proposal deposit or booking: the note, the next steps in payer order, the redirect (seconds 0 = a Continue link), where it shows, whether a review link is set, and 30-day views and clicks per step. after_payment_update takes the step ids.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"page":{"type":"object","properties":{"title":{"type":"string"},"message":{"type":"string"},"message_hidden":{"type":"boolean"},"steps":{"type":"array","items":{"type":"object","properties":{"position":{"type":"number"},"id":{"type":"string"},"kind":{"type":"string"},"label":{"type":"string"},"url":{"type":"string"},"source":{"type":"string"},"description":{"type":"string"},"hidden":{"type":"boolean"}},"required":["position","id","kind","label","url","source","description","hidden"],"additionalProperties":false}},"redirect":{"type":"object","properties":{"url":{"type":"string"},"seconds":{"type":"number"}},"required":["url","seconds"],"additionalProperties":false,"nullable":true},"surfaces":{"type":"object","additionalProperties":{"type":"boolean"}}},"required":["title","message","message_hidden","steps","redirect","surfaces"],"additionalProperties":false},"review_url_set":{"type":"boolean"},"stats_30d":{"type":"object","properties":{"days":{"type":"number"},"views":{"type":"number"},"clicks":{"type":"object","additionalProperties":{"type":"number"}}},"required":["days","views","clicks"],"additionalProperties":false}},"required":["page","review_url_set","stats_30d"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/after_payment_update":{"post":{"operationId":"after_payment_update","summary":"Change the after-payment page","description":"Change the after-payment page (Settings > After payment) with operations run in order, all or nothing; each field's description names the operations that use it. Up to 5 steps; links must be https. A review or portal step without a url uses the workspace's review link or the paying client's portal. Get step ids from after_payment_get. Owners and admins only.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"operations":{"type":"array","items":{"type":"object","properties":{"op":{"type":"string","enum":["set_note","add_step","edit_step","move_step","show_step","hide_step","remove_step","set_redirect","clear_redirect","set_surfaces"]},"step_id":{"type":"string","maxLength":24,"description":"The step to change (edit/move/show/hide/remove), from after_payment_get."},"position":{"type":"integer","minimum":1,"maximum":5,"description":"1 = first. add_step: where to insert (default last). move_step: where it goes."},"title":{"type":"string","maxLength":60,"description":"set_note: the note's heading; \"\" = \"A note from {business}\"."},"message":{"type":"string","maxLength":1000,"description":"set_note: plain text, line breaks kept; {first_name}, {business}, {number} and {amount} are filled in on the page."},"hidden":{"type":"boolean","description":"set_note: hide the note without deleting it."},"kind":{"type":"string","enum":["book","download","link","review","referral","portal","video"],"description":"add_step / edit_step: the step's type (its icon)."},"label":{"type":"string","maxLength":40,"description":"add_step / edit_step: the button text."},"url":{"type":"string","maxLength":2048,"description":"add_step / edit_step / set_redirect: an https link. Leave it out on a review or portal step to use the workspace's review link or the client's own portal."},"description":{"type":"string","maxLength":60,"description":"add_step / edit_step: one short line under the label."},"seconds":{"type":"integer","description":"set_redirect: 0 (a Continue link, no countdown), 5, 10 or 15."},"invoices":{"type":"boolean","description":"set_surfaces"},"pay_links":{"type":"boolean","description":"set_surfaces"},"proposals":{"type":"boolean","description":"set_surfaces"},"bookings":{"type":"boolean","description":"set_surfaces"}},"required":["op"],"additionalProperties":false},"minItems":1,"maxItems":20,"description":"Up to 20 operations, run in order, all or nothing."}},"required":["operations"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"page":{"type":"object","properties":{"title":{"type":"string"},"message":{"type":"string"},"message_hidden":{"type":"boolean"},"steps":{"type":"array","items":{"type":"object","properties":{"position":{"type":"number"},"id":{"type":"string"},"kind":{"type":"string"},"label":{"type":"string"},"url":{"type":"string"},"source":{"type":"string"},"description":{"type":"string"},"hidden":{"type":"boolean"}},"required":["position","id","kind","label","url","source","description","hidden"],"additionalProperties":false}},"redirect":{"type":"object","properties":{"url":{"type":"string"},"seconds":{"type":"number"}},"required":["url","seconds"],"additionalProperties":false,"nullable":true},"surfaces":{"type":"object","additionalProperties":{"type":"boolean"}}},"required":["title","message","message_hidden","steps","redirect","surfaces"],"additionalProperties":false}},"required":["page"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/requests_search":{"post":{"operationId":"requests_search","summary":"Search requests","description":"List inbound prospect submissions (leads from contact forms, Pages, Funnels and the inbound lead API), newest first, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `status` is new, reviewed, converted or archived (one at a time). `form_id` accepts an intake-form slug or a funnel id (funnel leads are identified by their `source`, 'funnel:{id}'). `query` matches name, email, phone and message. `form_id` and `query` are applied after paging, so a page can be short; keep following `nextCursor`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"requests:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["new","reviewed","converted","archived"],"description":"Only requests with this status."},"form_id":{"type":"string","minLength":1,"maxLength":200,"description":"Intake-form slug or funnel id."},"query":{"type":"string","maxLength":200,"description":"Matches name, email, phone and message."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","maxLength":200,"description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"number"},"source":{"type":"string"},"form_id":{"type":"string"},"message_preview":{"type":"string"},"converted_client_id":{"type":"string"},"assigned_to":{"type":"string"}},"required":["id","name","status","created_at"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["requests"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/requests_get":{"post":{"operationId":"requests_get","summary":"Get a request","description":"Fetch one inbound request by id, including the full message and the recorded consent (SMS consent, transactional/promotional consent, terms accepted, and the exact consent wording shown). Returns `{ request: null }` if the id does not exist in this workspace. Funnel answer content, internal comments, IP address and user agent are never returned. Read-only. Find ids with requests_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"requests:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":1500,"description":"Request id (from requests_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"request":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"number"},"source":{"type":"string"},"form_id":{"type":"string"},"message_preview":{"type":"string"},"converted_client_id":{"type":"string"},"assigned_to":{"type":"string"},"message":{"type":"string"},"source_url":{"type":"string"},"sms_consent":{"type":"boolean"},"sms_transactional_consent":{"type":"boolean"},"sms_promotional_consent":{"type":"boolean"},"terms_accepted":{"type":"boolean"},"consent_language":{"type":"string"},"funnel_id":{"type":"string"},"has_funnel_answers":{"type":"boolean"}},"required":["id","name","status","created_at","sms_consent","sms_transactional_consent","sms_promotional_consent","terms_accepted"],"additionalProperties":false,"nullable":true}},"required":["request"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/requests_forms_list":{"post":{"operationId":"requests_forms_list","summary":"List intake forms","description":"List the workspace's inbound intake forms, so a request's `form_id` can be resolved to a name: slug (document id and public URL segment), name, template, layout, active flag and timestamps. Active forms only unless `include_inactive` is true. Creating, editing, publishing or pausing a form is not available through this API; forms are edited in Workspace369 under Requests > Settings > Forms.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"requests:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"include_inactive":{"type":"boolean","description":"Include inactive forms (excluded by default)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"forms":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"template":{"type":"string"},"layout":{"type":"string"},"is_active":{"type":"boolean"},"created_at":{"type":"number"},"updated_at":{"type":"number"}},"required":["slug","name","template","layout","is_active","created_at","updated_at"],"additionalProperties":false}}},"required":["forms"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/requests_update_status":{"post":{"operationId":"requests_update_status","summary":"Update request status","description":"Mark an inbound request 'reviewed' or archive it. Archiving is terminal: there is no delete and no way back to 'new'. A converted request can be archived but not moved back to 'reviewed'. Converting is done by requests_convert_to_client. Returns `changed: false` if the request was already in the requested status. Sends nothing to the prospect; to reply use requests_respond.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"requests:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","minLength":1,"maxLength":1500,"description":"Request id (from requests_search)."},"status":{"type":"string","enum":["reviewed","archived"],"description":"reviewed, or archived (terminal)."}},"required":["request_id","status"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"request":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"previous_status":{"type":"string"}},"required":["id","status","previous_status"],"additionalProperties":false,"nullable":true},"changed":{"type":"boolean"}},"required":["request","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/requests_convert_to_client":{"post":{"operationId":"requests_convert_to_client","summary":"Convert a request to a client","description":"Turn an inbound request into a CRM client and mark the request converted. A new client lands in the Lead stage, owned by the request's assignee, with the lead source from the workspace's list (\"Website form · <form name>\" for a form request), the same as the Convert button in Requests. The client id is derived from the lead's email (or phone when there is no email), so converting the same person twice, or after the server auto-converted them, links to the same client (`created: false`). A request with neither an email nor a usable phone number is refused. Needs Clients write access as well as Requests write access. Creating the client can start workflow automations that run on new clients, which may message the prospect. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"requests:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","minLength":1,"maxLength":1500,"description":"Request id (from requests_search)."}},"required":["request_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"request":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"}},"required":["id","status"],"additionalProperties":false},"created":{"type":"boolean"}},"required":["client","request","created"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/requests_respond":{"post":{"operationId":"requests_respond","summary":"Reply to a request","description":"Reply to an inbound prospect by email or SMS. The recipient is read from the request itself: the To address cannot be overridden, no files are attached, and only that prospect is messaged. Email goes out as the app's Reply via email does: from an inbox, with the workspace's from-name, reply-to, signature and default Cc/Bcc; `subject` defaults to 'Re: your request' and `body` is markdown, with `{{client.*}}` merge fields filled from the request's name, email and phone. If `from_inbox` is omitted, the workspace's AI & MCP inbox is used, else the only inbox the user can send from; with several and no default, nothing is sent and the result lists them. `cc` and `bcc` are email-only, must be team, workspace or the request's client addresses, and are final lists that replace the defaults (the inbox's archive Bcc is always added). One email goes to at most 10 recipients from a starter inbox and 50 from the user's own domain or mailbox. SMS goes only to a lead who recorded SMS consent. A request marked 'new' becomes 'reviewed' after a successful send. This sends a real message to the prospect and bills for it. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"inbox:send","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"request_id":{"type":"string","minLength":1,"maxLength":1500,"description":"The request's id (from requests_search)."},"channel":{"type":"string","enum":["email","sms"],"description":"Delivery channel. SMS needs the lead's recorded SMS consent."},"body":{"type":"string","minLength":1,"maxLength":5000,"description":"The message. Email body or SMS text. Markdown: `# ` / `## ` / `### ` start a large / medium / small heading; `- ` or `1. ` starts a bullet or numbered item; inline `**bold**`, `*italic*`, `<u>underline</u>`, `~~strikethrough~~`, `[text](https://…)` links and `![alt](https://…)` images. Text without these markers goes out as plain paragraphs. Merge fields like `{{client.first_name}}`, `{{workspace.name}}` and `{{sender.name}}` are filled in."},"subject":{"type":"string","maxLength":200,"description":"Email only; ignored for SMS. Defaults to 'Re: your request'."},"from_inbox":{"type":"string","maxLength":320,"description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"cc":{"type":"array","items":{"type":"string","maxLength":320},"maxItems":50,"description":"Cc addresses; team, workspace or the request's client addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"bcc":{"type":"array","items":{"type":"string","maxLength":320},"maxItems":50,"description":"Bcc addresses; team, workspace or the request's client addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["request_id","channel","body"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"channel":{"type":"string","enum":["email","sms"]},"to":{"type":"string"},"message_id":{"type":"string"},"conversation_id":{"type":"string"},"request_status":{"type":"string"},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"},"cc":{"type":"array","items":{"type":"string"}},"bcc":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"}},"required":["sent","channel","to","message_id","request_status"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/lead_sources_list":{"post":{"operationId":"lead_sources_list","summary":"List lead sources","description":"List the workspace's lead sources (where new business comes from) and which one is the default for new clients. Read-only; takes no arguments. Returns `lead_sources` and `default_id`; change the default with lead_sources_set_default.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"clients:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"lead_sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"is_default":{"type":"boolean"}},"required":["id","name","is_default"],"additionalProperties":false}},"default_id":{"type":"string"}},"required":["lead_sources","default_id"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/lead_sources_set_default":{"post":{"operationId":"lead_sources_set_default","summary":"Set the default lead source","description":"Set which lead source new clients get when none is named (an empty `lead_source_id` clears it). This changes every client created afterwards. It does not create a lead source; pass an id from lead_sources_list. Returns `default_id`, `default_name` and `changed`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"clients:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lead_source_id":{"type":"string","description":"Lead source id (lead_sources_list); empty clears the default."}},"required":["lead_source_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"default_id":{"type":"string"},"default_name":{"type":"string"},"changed":{"type":"boolean"}},"required":["default_id","default_name","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/automations_list":{"post":{"operationId":"automations_list","summary":"List workflows","description":"List the workspace's workflows (the Workflows screen) with each one's trigger, action (its first step's action), category, step count, lifecycle (draft, active, paused), on/off state, last run's outcome and when it last fired. Each row carries `can_fire` and `blocked_reasons`, which show whether a workflow will actually run: a workflow can be stored and show as enabled yet never fire (its trigger has no live emitter, or its `status` was written as something other than a boolean).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"automations:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"automations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"trigger":{"type":"string"},"action":{"type":"string"},"category":{"type":"string"},"enabled":{"type":"boolean"},"can_fire":{"type":"boolean"},"blocked_reasons":{"type":"array","items":{"type":"string"}},"lifecycle":{"type":"string","enum":["draft","active","paused"]},"step_count":{"type":"number"},"last_run":{"type":"object","properties":{"at":{"type":"number"},"outcome":{"type":"string"},"run_number":{"type":"number"},"error":{"type":"string"}},"additionalProperties":false},"last_triggered_at":{"type":"number"},"created_at":{"type":"number"},"updated_at":{"type":"number"}},"required":["id","name","enabled","can_fire","blocked_reasons","lifecycle","step_count"],"additionalProperties":false}}},"required":["automations"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/automations_get":{"post":{"operationId":"automations_get","summary":"Get a workflow","description":"Fetch one workflow's full definition: trigger, conditions, action, recipients and follow-up sequence. `definition_warnings` lists problems; conditions are ANDed and fail closed, so an unresolvable field or unknown operator makes a workflow log a run and deliver nothing. Recipient addresses are never returned, only the recipient type and name. Returns `{ automation: null }` if the id does not exist in this workspace.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"automations:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Workflow id (from automations_list)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"automation":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"trigger":{"type":"string"},"action":{"type":"string"},"category":{"type":"string"},"enabled":{"type":"boolean"},"can_fire":{"type":"boolean"},"blocked_reasons":{"type":"array","items":{"type":"string"}},"lifecycle":{"type":"string","enum":["draft","active","paused"]},"step_count":{"type":"number"},"last_run":{"type":"object","properties":{"at":{"type":"number"},"outcome":{"type":"string"},"run_number":{"type":"number"},"error":{"type":"string"}},"additionalProperties":false},"last_triggered_at":{"type":"number"},"created_at":{"type":"number"},"updated_at":{"type":"number"},"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"operator":{"type":"string"},"value":{}},"required":["field","operator"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"member_id":{"type":"string"}},"required":["type"],"additionalProperties":false}},"steps":{"type":"array","items":{"type":"object","properties":{"order":{"type":"number"},"action":{"type":"string"},"delay_amount":{"type":"number"},"delay_unit":{"type":"string"}},"additionalProperties":false}},"message_subject":{"type":"string"},"has_message_body":{"type":"boolean"},"definition_warnings":{"type":"array","items":{"type":"string"}}},"required":["id","name","enabled","can_fire","blocked_reasons","lifecycle","step_count","conditions","recipients","steps","has_message_body","definition_warnings"],"additionalProperties":false,"nullable":true}},"required":["automation"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/automations_runs_list":{"post":{"operationId":"automations_runs_list","summary":"List workflow runs","description":"The workflow execution ledger. Filter by `automation_id` and/or `outcome`: delivered, failed, skipped (the workflow fired and delivered nothing: a failed condition, unresolved recipient, missing mailbox), stopped (hit a stopWorkflow condition) or waiting (a step is queued on a wait). Rows carry `type` (`execution` or `testRun`) when the log has one. Manual test runs are excluded unless `include_test_runs: true`. Message bodies, recipient addresses and phone numbers, and raw trigger entity data are never returned; automations_get shows the definition.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"automations:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"automation_id":{"type":"string","description":"Only runs of this workflow."},"outcome":{"type":"string","enum":["delivered","failed","skipped","stopped","waiting"],"description":"Only runs with this outcome."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"include_test_runs":{"type":"boolean","description":"Also return manual Test Runs (excluded by default)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"automation_id":{"type":"string"},"automation_name":{"type":"string"},"outcome":{"type":"string"},"type":{"type":"string","enum":["execution","testRun"]},"trigger_type":{"type":"string"},"channel":{"type":"string"},"sequence_number":{"type":"number"},"duration_ms":{"type":"number"},"created_at":{"type":"number"},"error_message":{"type":"string"},"stop_reason":{"type":"string"},"pipeline_steps":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string"},"detail":{"type":"string"}},"required":["name","status"],"additionalProperties":false}}},"required":["id","outcome","pipeline_steps"],"additionalProperties":false}}},"required":["runs"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/automations_disable":{"post":{"operationId":"automations_disable","summary":"Turn a workflow off","description":"Turn a workflow off so it stops firing. This also stops anything already queued: a follow-up step waiting on a delay re-checks the live workflow before it runs and is skipped once it is off. Turning it back on is automations_activate, which needs its own `automations:activate` scope. Disabling an already-off workflow is reported, not an error. Returns `id`, `name`, `disabled` and `already_off`.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"automations:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Workflow id (from automations_list)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"disabled":{"type":"boolean"},"already_off":{"type":"boolean"}},"required":["id","name","disabled","already_off"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/automations_test":{"post":{"operationId":"automations_test","summary":"Test a workflow","description":"Dry-runs a workflow and sends nothing: every step reports what it would do (who it would email or text, what it would change), on sample data or on a real record (`record_id`). If the workflow has saved changes that are not live yet, those are what is tested, as in the Workflows screen. The run is logged as a test run, readable with automations_runs_list and `include_test_runs: true`. Returns `run_id`, `outcome`, `tested` and `name`. No email or SMS is sent and no record changes; it only saves a test-run log. Use it before automations_activate.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"automations:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200,"description":"The workflow's id (automations_list)."},"record_id":{"type":"string","minLength":1,"maxLength":200,"description":"Test on this real record instead of sample data. It must be the kind of record the trigger runs on, and one you can view."},"record_type":{"type":"string","enum":["client","contact_request","invoice","proposal","contract","schedule","task"],"description":"The record's kind, when you pass record_id (a lead is contact_request, an appointment schedule)."},"board_id":{"type":"string","minLength":1,"maxLength":200,"description":"The task's board: required to test on a task."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":"string"},"outcome":{"type":"string"},"tested":{"type":"string","enum":["draft","live"]},"name":{"type":"string"}},"required":["run_id","outcome","tested","name"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contracts_search":{"post":{"operationId":"contracts_search","summary":"Search contracts","description":"List contracts, newest first (up to `limit`, default 25, max 50). Filter by `status_group` (draft; waiting = sent, in progress or sealing; completed; declined; voided; expired), `client_id`, and `archived` ('exclude' by default, or 'only'). `query` matches words in the title. One call scans at most 200 contracts; `scan_truncated: true` means more may match, so pass `next_cursor` to continue. Field values, signatures and signer IP addresses are never returned. Members limited to specific clients see only contracts in their book.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"contracts:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Words to find in the contract title."},"status_group":{"type":"string","enum":["draft","waiting","completed","declined","voided","expired"],"description":"waiting = sent, in progress or sealing."},"client_id":{"type":"string","minLength":1,"maxLength":128,"description":"Only this client's contracts."},"archived":{"type":"string","enum":["exclude","only"],"description":"Default exclude."},"limit":{"type":"integer","minimum":1,"maximum":50,"description":"Results per page (default 25, max 50)."},"cursor":{"type":"string","minLength":1,"maxLength":128,"description":"The `next_cursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contracts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false}},"next_cursor":{"type":"string","nullable":true},"scan_truncated":{"type":"boolean"}},"required":["contracts","next_cursor","scan_truncated"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contracts_get":{"post":{"operationId":"contracts_get","summary":"Get a contract","description":"Fetch one contract by `contract_id`: status, dates, verification and expiry settings, invitation subject, the sealed document's SHA-256 once completed, and each recipient's name, email, role, routing order and progress. Returns `{ contract: null }` if the id does not exist or is outside a scoped member's book. `send_request` is the latest send started with contracts_send: `queued` while it runs, `sent`, or `failed` with the `failure_code`; null when there is none. Field values, signature images and signer IP addresses are never returned.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"contracts:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contract_id":{"type":"string","minLength":1,"maxLength":128,"description":"Contract id (from contracts_search)."}},"required":["contract_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"},"source":{"type":"string","nullable":true},"template_id":{"type":"string","nullable":true},"proposal_id":{"type":"string","nullable":true},"invoice_id":{"type":"string","nullable":true},"verification":{"type":"string","nullable":true},"expires_after_days":{"type":"integer","nullable":true},"message_subject":{"type":"string","nullable":true},"voided_reason":{"type":"string","nullable":true},"declined_reason":{"type":"string","nullable":true},"sealed":{"type":"object","properties":{"sha256":{"type":"string"},"seal_level":{"type":"string","nullable":true},"sealed_at":{"type":"string","nullable":true}},"required":["sha256","seal_level","sealed_at"],"additionalProperties":false,"nullable":true},"send_request":{"type":"object","properties":{"status":{"type":"string","enum":["queued","sent","failed"]},"requested_at":{"type":"string","nullable":true},"finished_at":{"type":"string","nullable":true},"failure_code":{"type":"string","nullable":true}},"required":["status","requested_at","finished_at","failure_code"],"additionalProperties":false,"nullable":true},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","nullable":true},"role":{"type":"string"},"routing_order":{"type":"integer"},"status":{"type":"string"},"in_person":{"type":"boolean"},"invited_at":{"type":"string","nullable":true},"opened_at":{"type":"string","nullable":true},"verified_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"declined_at":{"type":"string","nullable":true}},"required":["id","name","email","role","routing_order","status","in_person","invited_at","opened_at","verified_at","completed_at","declined_at"],"additionalProperties":false}}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed","source","template_id","proposal_id","invoice_id","verification","expires_after_days","message_subject","voided_reason","declined_reason","sealed","send_request","recipients"],"additionalProperties":false,"nullable":true}},"required":["contract"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contract_templates_list":{"post":{"operationId":"contract_templates_list","summary":"List contract templates","description":"List the workspace's contract templates with their roles (key, label, signer/approver/viewer/cc, routing order, and whether the client, a fixed person or the sender fills it). `bulk_eligible`: exactly one client role and every other role fixed. `proposal_eligible`: also, the client role signs or approves first. Pass a template id to contracts_create_draft; to find contracts use contracts_search.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"contracts:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Maximum templates to return (max 100)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"kind":{"type":"string"},"roles":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"role":{"type":"string"},"routing_order":{"type":"integer"},"assignment":{"type":"string"}},"required":["key","label","role","routing_order","assignment"],"additionalProperties":false}},"bulk_eligible":{"type":"boolean"},"proposal_eligible":{"type":"boolean"}},"required":["id","name","description","kind","roles","bulk_eligible","proposal_eligible"],"additionalProperties":false}}},"required":["templates"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contracts_create_draft":{"post":{"operationId":"contracts_create_draft","summary":"Create a draft contract","description":"Create a DRAFT contract from a template. Pass `template_id` (see contract_templates_list) and `client_id` when the template has a client role; the client's primary email fills that role. Pass `recipients` for roles whose assignment is manual, as { role_key, name, email }; each email must be saved on the client (or its contacts), a team member or the workspace. Optional `title`, `message` (the invitation email subject and body) and `reminders` (the automatic reminder cadence: first after N days, then every N days, at most N). Nothing is sent: the draft can be reviewed in Workspace369 or sent with contracts_send. `unassigned_role_keys` lists roles that still need a person before the contract can be sent. Each call creates a new draft.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"contracts:write","x-billing-class":"mcp_tool_write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string","minLength":1,"maxLength":128,"description":"Contract template id (from contract_templates_list)."},"client_id":{"type":"string","minLength":1,"maxLength":128,"description":"Required when the template has a client role."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Optional contract title, 1-200 characters."},"message":{"type":"object","properties":{"subject":{"type":"string","maxLength":200},"body":{"type":"string","maxLength":5000}},"required":["subject","body"],"additionalProperties":false,"description":"Invitation email subject and body. Setting it also needs the contracts edit permission."},"recipients":{"type":"array","items":{"type":"object","properties":{"role_key":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":254}},"required":["role_key","name","email"],"additionalProperties":false},"maxItems":20,"description":"One entry per template role whose assignment is manual."},"reminders":{"type":"object","properties":{"first_after_days":{"type":"integer","minimum":1,"maximum":14,"description":"Days after the invitation before the first reminder."},"every_days":{"type":"integer","minimum":1,"maximum":14,"description":"Days between later reminders."},"max":{"type":"integer","minimum":0,"maximum":10,"description":"Most reminders per recipient; 0 turns automatic reminders off."}},"required":["first_after_days","every_days","max"],"additionalProperties":false,"description":"Automatic email reminders for this contract. Omit to use the template's defaults, then Settings → Contracts. Setting it also needs the contracts edit permission."}},"required":["template_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false},"unassigned_role_keys":{"type":"array","items":{"type":"string"}}},"required":["contract","unassigned_role_keys"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contracts_send":{"post":{"operationId":"contracts_send","summary":"Send a contract for signature","description":"Send a draft contract for signature: the document is frozen, the first routing group is emailed and the expiry clock starts. Needs `contract_id`. It uses one of the workspace's included monthly contracts if any remain; otherwise it costs Tokens, and nothing is sent if that charge fails. This emails real recipients and cannot be undone (voiding stops it). The send runs in the background (a contract from a text template is rendered first, which can take minutes), so the result `status: \"sending\"` confirms nothing yet: contracts_get shows whether it went out (status no longer draft; `send_request.failure_code` explains a failure). Calling again while a send is in progress starts nothing new (`deduplicated: true`). Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"contracts:send","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contract_id":{"type":"string","minLength":1,"maxLength":128,"description":"Draft contract id (from contracts_create_draft or contracts_search)."}},"required":["contract_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false},"status":{"type":"string","enum":["sending","sent"]},"deduplicated":{"type":"boolean"},"billing":{"type":"string","enum":["unlimited","included","tokens","already_charged"]},"tokens":{"type":"integer"}},"required":["contract","status","deduplicated","billing","tokens"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contracts_remind":{"post":{"operationId":"contracts_remind","summary":"Remind contract recipients","description":"Email a reminder to recipients who were invited and have not finished. `recipient_id` selects one recipient; omit it to remind everyone who is due. A recipient reminded in the last 24 hours (`too_soon`) or not waiting on an emailed link, such as one signing in person (`not_remindable`), is listed under `skipped`. This sends real email and cannot be undone. Returns `reminded_recipient_ids` and `skipped`. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"contracts:send","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contract_id":{"type":"string","minLength":1,"maxLength":128,"description":"Contract id (from contracts_search)."},"recipient_id":{"type":"string","minLength":1,"maxLength":128,"description":"Omit to remind everyone waiting on an emailed link."}},"required":["contract_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract_id":{"type":"string"},"reminded_recipient_ids":{"type":"array","items":{"type":"string"}},"skipped":{"type":"array","items":{"type":"object","properties":{"recipient_id":{"type":"string"},"reason":{"type":"string","enum":["too_soon","not_remindable"]}},"required":["recipient_id","reason"],"additionalProperties":false}}},"required":["contract_id","reminded_recipient_ids","skipped"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/contracts_void":{"post":{"operationId":"contracts_void","summary":"Void a contract","description":"Void an open contract (sent or in progress) so nobody can sign it. Requires `contract_id` and a `reason` of 5 to 1000 characters, recorded on the contract. A contract that is sealing, completed, declined, voided or expired cannot be voided. Recipients are emailed that it was voided. This cannot be undone; duplicate the contract in Workspace369 to start again. Returns the voided `contract`. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"contracts:send","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contract_id":{"type":"string","minLength":1,"maxLength":128,"description":"Contract id (from contracts_search)."},"reason":{"type":"string","minLength":5,"maxLength":1000,"description":"Recorded on the contract."}},"required":["contract_id","reason"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false}},"required":["contract"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/email_send_options":{"post":{"operationId":"email_send_options","summary":"Get email send options","description":"Call this before inbox_send_message, invoices_send or proposals_send; it sends nothing. Read how an email would go out: the inboxes the user can send from (label, address, starter or own domain/mailbox, per-email recipient cap, which is the workspace default and which the default for automatic emails), what happens when `from_inbox` is omitted (`when_from_inbox_omitted`; 'ask_user' means the send tools will not choose), the default Cc and Bcc the send tools add (automatic ones are marked, and each says whether it counts toward the cap), each inbox's compliance archive Bcc (always added, cannot be removed), from-name and reply-to overrides, whether a signature is added, the default invoice email template, and the template library (id, name, context: 'general' templates work with inbox_send_message and invoices_send, 'invoice' with invoices_send, 'proposal' templates apply to proposals automatically). In the send tools `cc` / `bcc` replace the defaults. Recipient cap: at most 10 people per email from a starter inbox and 50 from the user's own domain or mailbox, counting To + Cc + Bcc; the workspace's own addresses do not count. Requires the Send Email permission.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"inbox:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"inboxes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"address":{"type":"string"},"display":{"type":"string"},"tier":{"type":"string","enum":["starter","own"]},"recipient_cap":{"type":"integer"},"is_workspace_default":{"type":"boolean"},"is_ai_default":{"type":"boolean"},"from_name":{"type":"string"},"reply_to":{"type":"string"},"compliance_bcc":{"type":"string"},"invoice_template":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"nullable":true}},"required":["id","label","address","display","tier","recipient_cap","is_workspace_default","is_ai_default","from_name","reply_to","compliance_bcc","invoice_template"],"additionalProperties":false}},"ai_default_inbox":{"type":"string","nullable":true},"when_from_inbox_omitted":{"type":"string","enum":["ai_default","only_inbox","ask_user","no_inbox"]},"recipient_cap_without_inbox":{"type":"integer"},"default_cc":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"source":{"type":"string","enum":["default_cc","workspace_email","default_bcc","archive_bcc"]},"automatic":{"type":"boolean"},"counts_toward_cap":{"type":"boolean"}},"required":["address","source","automatic","counts_toward_cap"],"additionalProperties":false}},"default_bcc":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"source":{"type":"string","enum":["default_cc","workspace_email","default_bcc","archive_bcc"]},"automatic":{"type":"boolean"},"counts_toward_cap":{"type":"boolean"}},"required":["address","source","automatic","counts_toward_cap"],"additionalProperties":false}},"from_name_override":{"type":"string"},"reply_to_override":{"type":"string"},"insert_signature_by_default":{"type":"boolean"},"personal_signature_set":{"type":"boolean"},"default_invoice_template":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"nullable":true},"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"context":{"type":"string","enum":["invoice","proposal","general"]},"subject":{"type":"string"},"cc":{"type":"array","items":{"type":"string"}},"bcc":{"type":"array","items":{"type":"string"}}},"required":["id","name","context","subject","cc","bcc"],"additionalProperties":false}}},"required":["inboxes","ai_default_inbox","when_from_inbox_omitted","recipient_cap_without_inbox","default_cc","default_bcc","from_name_override","reply_to_override","insert_signature_by_default","personal_signature_set","default_invoice_template","templates"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/follow_ups_list":{"post":{"operationId":"follow_ups_list","summary":"List client follow-ups","description":"List the workspace's client follow-ups grouped as `overdue`, `today`, `this_week` (rest of the next 7 days) and `suggested`. Each item is the client's next follow-up as computed by the server: scheduled meetings, reminders and tasks first, then detected reasons (chase_payment = invoice past due, reply_owed = client message waiting over 24 h, onboarding_step = contract/deposit/kickoff missing, chase_proposal = proposal sent 3+ days and not accepted, renewal = retainer ends within 30 days), then `suggested` check-ins (quiet longer than the stage's cadence). `amount` + `currency`, when present, is the money behind the follow-up (only for callers who may see prices). `best_time`, when present, comes from the client's notes. `scope`: everyone (default) or mine (follow-ups naming the caller, or on clients they created or are assigned). `group`: overdue, today, this_week, suggested, or due (overdue + today). Scoped members see only their assigned clients; archived clients are excluded. Changes nothing.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"clients:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scope":{"type":"string","enum":["mine","everyone"],"description":"everyone (default) or mine."},"group":{"type":"string","enum":["overdue","today","this_week","suggested","due"],"description":"One of overdue, today, this_week, suggested, or due (overdue + today)."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"client_id":{"type":"string"},"client_name":{"type":"string"},"company_name":{"type":"string"},"group":{"type":"string","enum":["overdue","today","this_week","suggested"]},"type":{"type":"string"},"title":{"type":"string"},"reason":{"type":"string"},"reasons":{"type":"array","items":{"type":"string"}},"due_at":{"type":"string"},"channel":{"type":"string"},"suggested":{"type":"boolean"},"source":{"type":"string"},"source_ref":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"],"additionalProperties":false},"best_time":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"}},"required":["client_id","client_name","group","type","title","reason","reasons","due_at","suggested","source"],"additionalProperties":false}},"counts":{"type":"object","properties":{"overdue":{"type":"number"},"today":{"type":"number"},"this_week":{"type":"number"},"suggested":{"type":"number"}},"required":["overdue","today","this_week","suggested"],"additionalProperties":false},"time_zone":{"type":"string"},"truncated":{"type":"boolean"}},"required":["items","counts","time_zone","truncated"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/recurring_plans_search":{"post":{"operationId":"recurring_plans_search","summary":"Search recurring invoices","description":"List recurring invoice plans (an invoice that repeats on a schedule, paid by autopay or a pay link). Filters: `query` (plan or client name), `status` (draft, scheduled, active, paused, ended), `client_id`, `needs_attention` (failed payment, client must confirm with their bank, new card needed, draft to review, Stripe disconnected). Each plan has its cadence, next invoice date, autopay state and card, and any retry in progress. `summary` totals this page: active plans, plans needing attention and monthly recurring revenue (`monthly_amount` normalizes weekly/quarterly/yearly plans to a month). Amounts are null without the invoices.view_prices permission. Scoped members see only their clients. Paged: when the response has `nextCursor`, pass that value back as `cursor` for the next page; no `nextCursor` means the last page.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches the plan or client name."},"status":{"type":"string","enum":["draft","scheduled","active","paused","ended"],"description":"Only plans in this status."},"client_id":{"type":"string","description":"Only this client's plans."},"needs_attention":{"type":"boolean","description":"true: only plans with a failed payment, a bank confirmation or new card needed, a draft to review, or Stripe disconnected."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"plans":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"attention":{"type":"string","nullable":true},"client_id":{"type":"string"},"client_name":{"type":"string"},"cadence":{"type":"string"},"amount":{"type":"number","nullable":true},"monthly_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"next_invoice_date":{"type":"string","nullable":true},"collection":{"type":"string"},"autopay_state":{"type":"string"},"card":{"type":"object","properties":{"brand":{"type":"string"},"last4":{"type":"string"}},"required":["brand","last4"],"additionalProperties":false,"nullable":true},"retry":{"type":"object","properties":{"invoice_id":{"type":"string"},"attempt":{"type":"number"},"next_on":{"type":"string","nullable":true},"last_code":{"type":"string","nullable":true}},"required":["invoice_id","attempt","next_on","last_code"],"additionalProperties":false,"nullable":true},"waiting_on_client_invoice_id":{"type":"string","nullable":true},"cycles_sent":{"type":"number"},"last_invoice_id":{"type":"string","nullable":true}},"required":["id","name","status","attention","client_id","client_name","cadence","amount","monthly_amount","currency","next_invoice_date","collection","autopay_state","card","retry","waiting_on_client_invoice_id","cycles_sent","last_invoice_id"],"additionalProperties":false}},"summary":{"type":"object","properties":{"active":{"type":"number"},"needs_attention":{"type":"number"},"monthly_recurring_revenue":{"type":"number","nullable":true}},"required":["active","needs_attention","monthly_recurring_revenue"],"additionalProperties":false},"nextCursor":{"type":"string"}},"required":["plans","summary"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/recurring_plans_get":{"post":{"operationId":"recurring_plans_get","summary":"Get a recurring invoice","description":"Fetch one recurring invoice plan by `id` (from recurring_plans_search): everything a search row has, plus sending (auto or review), payment terms, how it ends, any pause or upcoming amount change, pending one-off lines, and its last few autopay charge attempts (status, decline code, next retry). Returns `{ plan: null }` if the id does not exist or is outside a scoped member's clients. Amounts are null without invoices.view_prices.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Plan id (recurring_plans_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"attention":{"type":"string","nullable":true},"client_id":{"type":"string"},"client_name":{"type":"string"},"cadence":{"type":"string"},"amount":{"type":"number","nullable":true},"monthly_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"next_invoice_date":{"type":"string","nullable":true},"collection":{"type":"string"},"autopay_state":{"type":"string"},"card":{"type":"object","properties":{"brand":{"type":"string"},"last4":{"type":"string"}},"required":["brand","last4"],"additionalProperties":false,"nullable":true},"retry":{"type":"object","properties":{"invoice_id":{"type":"string"},"attempt":{"type":"number"},"next_on":{"type":"string","nullable":true},"last_code":{"type":"string","nullable":true}},"required":["invoice_id","attempt","next_on","last_code"],"additionalProperties":false,"nullable":true},"waiting_on_client_invoice_id":{"type":"string","nullable":true},"cycles_sent":{"type":"number"},"last_invoice_id":{"type":"string","nullable":true},"sending":{"type":"string"},"due_in_days":{"type":"number"},"heads_up_always":{"type":"boolean"},"ends":{"type":"string"},"end_after_date":{"type":"string","nullable":true},"pause":{"type":"object","properties":{"from":{"type":"string","nullable":true},"until":{"type":"string","nullable":true}},"required":["from","until"],"additionalProperties":false,"nullable":true},"amount_change":{"type":"object","properties":{"effective_date":{"type":"string"},"amount":{"type":"number","nullable":true}},"required":["effective_date","amount"],"additionalProperties":false,"nullable":true},"pending_one_off_lines":{"type":"number"},"recent_attempts":{"type":"array","items":{"type":"object","properties":{"invoice_id":{"type":"string"},"attempt":{"type":"number"},"reason":{"type":"string"},"status":{"type":"string"},"decline_code":{"type":"string","nullable":true},"hard_decline":{"type":"boolean"},"next_retry_on":{"type":"string","nullable":true},"at":{"type":"number","nullable":true}},"required":["invoice_id","attempt","reason","status","decline_code","hard_decline","next_retry_on","at"],"additionalProperties":false}}},"required":["id","name","status","attention","client_id","client_name","cadence","amount","monthly_amount","currency","next_invoice_date","collection","autopay_state","card","retry","waiting_on_client_invoice_id","cycles_sent","last_invoice_id","sending","due_in_days","heads_up_always","ends","end_after_date","pause","amount_change","pending_one_off_lines","recent_attempts"],"additionalProperties":false,"nullable":true}},"required":["plan"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/retainers_search":{"post":{"operationId":"retainers_search","summary":"Search retainers","description":"List retainers: hour banks (`hours`), fixed monthly (`fixed`) and prepaid deposits (`prepaid`). Filters: `query` (retainer or client name), `status`, `client_id`, `type`. Each row has this cycle's hours (included plus any rolled-in, approved, pending approval and left; negative = extra hours), the extra-hour rate, the prepaid balance, the next invoice date, and `billing`: automatic, review_needed (an older retainer waiting for the studio to confirm billing) or manual. Hours and money are separate figures. Money fields are null without invoices.view_prices. Scoped members see only their clients. Paged: when the response has `nextCursor`, pass that value back as `cursor` for the next page; no `nextCursor` means the last page.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Matches the retainer or client name."},"status":{"type":"string","description":"Only retainers with this stored status, e.g. active or paused."},"client_id":{"type":"string","description":"Only this client's retainers."},"type":{"type":"string","enum":["hours","fixed","prepaid"],"description":"hours = hour bank, fixed = fixed monthly, prepaid = prepaid deposit."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"cursor":{"type":"string","description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"retainers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"attention":{"type":"string","nullable":true},"billing":{"type":"string","enum":["automatic","review_needed","manual"]},"collection":{"type":"string"},"autopay_state":{"type":"string"},"amount":{"type":"number","nullable":true},"currency":{"type":"string"},"billing_cycle":{"type":"string"},"included_hours":{"type":"number","nullable":true},"extra_hour_rate":{"type":"number","nullable":true},"cycle":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"},"approved_hours":{"type":"number"},"pending_hours":{"type":"number"},"included_hours":{"type":"number"},"rolled_in_hours":{"type":"number"},"hours_left":{"type":"number"}},"required":["start","end","approved_hours","pending_hours","included_hours","rolled_in_hours","hours_left"],"additionalProperties":false,"nullable":true},"prepaid_balance":{"type":"number","nullable":true},"next_invoice_date":{"type":"string","nullable":true}},"required":["id","name","client_id","client_name","type","status","attention","billing","collection","autopay_state","amount","currency","billing_cycle","included_hours","extra_hour_rate","cycle","prepaid_balance","next_invoice_date"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["retainers"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/retainers_get":{"post":{"operationId":"retainers_get","summary":"Get a retainer","description":"Fetch one retainer by `id` (from retainers_search): everything a search row has, plus how extra hours are handled (bill_next or track_only), what happens to unused hours, the prepaid top-up settings, the prepaid balance with the amount reserved for a refund in progress and what is still available (`prepaid_available` = balance - reserved), and its last 10 ledger entries in plain words. Returns `{ retainer: null }` if the id does not exist or is outside a scoped member's clients.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Retainer id (retainers_search)."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"retainer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"attention":{"type":"string","nullable":true},"billing":{"type":"string","enum":["automatic","review_needed","manual"]},"collection":{"type":"string"},"autopay_state":{"type":"string"},"amount":{"type":"number","nullable":true},"currency":{"type":"string"},"billing_cycle":{"type":"string"},"included_hours":{"type":"number","nullable":true},"extra_hour_rate":{"type":"number","nullable":true},"cycle":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"},"approved_hours":{"type":"number"},"pending_hours":{"type":"number"},"included_hours":{"type":"number"},"rolled_in_hours":{"type":"number"},"hours_left":{"type":"number"}},"required":["start","end","approved_hours","pending_hours","included_hours","rolled_in_hours","hours_left"],"additionalProperties":false,"nullable":true},"prepaid_balance":{"type":"number","nullable":true},"next_invoice_date":{"type":"string","nullable":true},"extra_hours":{"type":"string","nullable":true},"unused_hours":{"type":"string","nullable":true},"top_up":{"type":"object","properties":{"threshold":{"type":"number","nullable":true},"amount":{"type":"number","nullable":true},"automatic":{"type":"boolean"}},"required":["threshold","amount","automatic"],"additionalProperties":false,"nullable":true},"prepaid_reserved":{"type":"number","nullable":true},"prepaid_available":{"type":"number","nullable":true},"recent_ledger":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"description":{"type":"string"},"hours":{"type":"number","nullable":true},"amount":{"type":"number","nullable":true},"balance_after_hours":{"type":"number","nullable":true},"balance_after_amount":{"type":"number","nullable":true},"invoice_id":{"type":"string","nullable":true},"at":{"type":"number","nullable":true}},"required":["type","description","hours","amount","balance_after_hours","balance_after_amount","invoice_id","at"],"additionalProperties":false}}},"required":["id","name","client_id","client_name","type","status","attention","billing","collection","autopay_state","amount","currency","billing_cycle","included_hours","extra_hour_rate","cycle","prepaid_balance","next_invoice_date","extra_hours","unused_hours","top_up","prepaid_reserved","prepaid_available","recent_ledger"],"additionalProperties":false,"nullable":true}},"required":["retainer"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/recurring_plans_send_pay_link":{"post":{"operationId":"recurring_plans_send_pay_link","summary":"Send a recurring invoice's pay link","description":"Email the client the pay link for a recurring plan's open invoice (the one a failed autopay is retrying or waiting on, else the plan's latest unpaid invoice), as invoices_send sends an invoice: the workspace's template, signature and PDF, with the Pay button. Useful when autopay failed or the client must confirm with their bank. `plan_id` is required; `message` (markdown) replaces the default line about the card; `from_inbox` and `idempotency_key` work as in invoices_send. Refuses when the plan has no unpaid invoice. Sends a real email and uses one email credit. Held until the user approves it in the Workspace369 app.","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_send","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan_id":{"type":"string","minLength":1,"description":"The recurring plan's id (from recurring_plans_search)."},"message":{"type":"string","maxLength":5000,"description":"Markdown. Replaces the default line about the card."},"from_inbox":{"type":"string","description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["plan_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"channel":{"type":"string","enum":["email","sms"]},"to":{"type":"string"},"message_id":{"type":"string"},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"},"cc":{"type":"array","items":{"type":"string"}},"bcc":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"conversation_id":{"type":"string"},"body_source":{"type":"string","enum":["message","template","default"]},"template_id":{"type":"string"}},"required":["sent","channel","to","message_id"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/approvals_get":{"post":{"operationId":"approvals_get","summary":"Check an approval","description":"Check what became of a tool call that was held for the user's approval. Pass the `approval_id` the held call returned. Reports whether the user is still deciding, approved it (with the result), declined it, or let it expire. It cannot approve anything; only the user can, in the Workspace369 app. Read-only and free (no tokens charged).","tags":["tools"],"security":[{"bearerAuth":[]}],"x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"workspace:read","x-billing-class":"mcp_tool_read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"approval_id":{"type":"string","minLength":1,"maxLength":64,"description":"The approval_id a held tool call returned."}},"required":["approval_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"approval_id":{"type":"string"},"tool":{"type":"string"},"status":{"type":"string","enum":["pending","executing","interrupted","approved_done","declined","expired","failed"]},"created_at":{"type":"string"},"expires_at":{"type":"string"},"outcome":{"type":"string"},"outcome_is_error":{"type":"boolean"}},"required":["approval_id","tool","status","created_at","expires_at"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/clients":{"get":{"operationId":"get_clients","summary":"Search clients","description":"List clients in the workspace, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `query` matches name, email or company. `lead_source`, `client_type`, `stage` (a pipeline stage id or name) and `tags` (matches any) are applied after the page is cut, so a filtered page can be short while more matches exist; keep following `nextCursor`. Archived clients are excluded. Scoped members see only their assigned clients.","tags":["clients"],"security":[{"bearerAuth":[]}],"x-tool":"clients_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"clients:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"clients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"},"address":{"type":"string"},"client_type":{"type":"string"},"lead_source":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"lifecycle_stage":{"type":"string"},"stage_id":{"type":"string"},"archived":{"type":"boolean"},"email_opted_out":{"type":"boolean"},"sms_opted_out":{"type":"boolean"},"blacklisted":{"type":"boolean"},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}},"custom_fields_unavailable":{"type":"boolean"}},"required":["id","name"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["clients"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","description":"Matches name, email or company."},"description":"Matches name, email or company."},{"name":"lead_source","in":"query","required":false,"schema":{"type":"string","description":"Only clients with this lead source."},"description":"Only clients with this lead source."},{"name":"client_type","in":"query","required":false,"schema":{"type":"string","enum":["business","individual"],"description":"Only business or individual clients."},"description":"Only business or individual clients."},{"name":"stage","in":"query","required":false,"schema":{"type":"string","description":"Only clients in this pipeline stage (id or name, see workspace_schema clients.stages)."},"description":"Only clients in this pipeline stage (id or name, see workspace_schema clients.stages)."},{"name":"tags","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Only clients having any of these tags."},"description":"Only clients having any of these tags."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"description":"Cursor (`nextCursor`) from the previous page."}]},"post":{"operationId":"post_clients","summary":"Create clients","description":"Create a client, or a prospect when `lifecycle_stage` is \"prospect\". A name is required: `name`, `first_name`/`last_name`, or `company`. `client_type` defaults to business for a company-only client, otherwise individual. Phone numbers are stored as E.164: give the country code; a 10-digit number is read as US/Canada and an unreadable number is refused. Use `addresses` for several addresses (exactly one is primary; the first if none is flagged), or the flat address fields for one. Addresses are checked against Google Places: an agreeing match is stored geocoded, anything else is stored as written and reported as unverified. Scoped members' new clients are assigned to them. `custom_fields` ({key: value}) is validated against the workspace's definitions; an unknown field or a bad value refuses the create. A repeat call with the same `idempotency_key` returns the first client (`deduped: true`).","tags":["clients"],"security":[{"bearerAuth":[]}],"x-tool":"clients_create","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"clients:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["client","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Full name; for a person this alone is enough."},"first_name":{"type":"string","description":"First name."},"last_name":{"type":"string","description":"Last name."},"email":{"type":"string","description":"Primary email address."},"phone":{"type":"string","description":"Primary phone, with country code (e.g. +44 20 7123 4567); a 10-digit number is read as US/Canada."},"company":{"type":"string","description":"Company name."},"address":{"type":"string","description":"Street address line (single-address shorthand)."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"client_type":{"type":"string","enum":["business","individual"],"description":"business or individual; defaults to business for a company-only client."},"lifecycle_stage":{"type":"string","enum":["client","prospect"],"description":"\"prospect\" creates a lead listed under Prospects; \"client\" (default) a client."},"lead_source":{"type":"string","description":"Where the client came from, matched against the workspace's lead sources (lead_sources_list); defaults to the workspace default."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."},"property":{"type":"string","description":"Unit or suite, for the single-address shorthand."},"country":{"type":"string","description":"Country, for the single-address shorthand."},"addresses":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","description":"Street line."},"property":{"type":"string","description":"Unit or suite."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"country":{"type":"string","description":"Country."},"place_id":{"type":"string","description":"Google Places id, if you already hold one."},"label":{"type":"string","description":"Label such as Home or Office."},"is_primary":{"type":"boolean","description":"Mark as the primary address."}},"additionalProperties":false},"maxItems":20,"description":"Several addresses (max 20); wins over the flat address fields. Exactly one ends up primary."},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"enum":["null"]}]},"description":"Custom field values as {key: value}, using the keys (or labels) from workspace_schema clients.custom_field_definitions. Values are checked against each field's type (text, number, boolean, date YYYY-MM-DD, select option); an unknown field or a bad value is refused."}}}}}}}},"/v1/clients/{id}":{"get":{"operationId":"get_clients_by_id","summary":"Get one of clients","description":"Fetch one client by id, with its `custom_fields` values (key to value). Returns `{ client: null }` if it does not exist or is outside a scoped member's assigned clients. Archived clients are returned with `archived: true`. Read-only. Find ids with clients_search; change a client with clients_update.","tags":["clients"],"security":[{"bearerAuth":[]}],"x-tool":"clients_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"clients:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"},"address":{"type":"string"},"client_type":{"type":"string"},"lead_source":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"lifecycle_stage":{"type":"string"},"stage_id":{"type":"string"},"archived":{"type":"boolean"},"email_opted_out":{"type":"boolean"},"sms_opted_out":{"type":"boolean"},"blacklisted":{"type":"boolean"},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}},"custom_fields_unavailable":{"type":"boolean"}},"required":["id","name"],"additionalProperties":false,"nullable":true}},"required":["client"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]},"patch":{"operationId":"patch_clients_by_id","summary":"Update one of clients","description":"Update a client by `id`. Only the fields passed change. `lifecycle_stage` \"client\" promotes a prospect, \"prospect\" demotes. `phone: \"\"` removes the primary phone. Email, phone and single-address updates replace only the primary entry and keep the others; `addresses` replaces the whole address list (the only way to remove or reorder one) and goes through the same Google Places check as on create. `custom_fields` ({key: value}, validated against the workspace's definitions; null clears a value) merges into the client's existing values. Returns the merged client, or an error if the client does not exist or is outside a scoped member's assigned clients.","tags":["clients"],"security":[{"bearerAuth":[]}],"x-tool":"clients_update","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"clients:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"company":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["client"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Full name."},"first_name":{"type":"string","description":"First name."},"last_name":{"type":"string","description":"Last name."},"email":{"type":"string","description":"Replaces the primary email."},"phone":{"type":"string","description":"Replaces the primary phone, with country code; \"\" removes it."},"company":{"type":"string","description":"Company name."},"address":{"type":"string","description":"Street address line (replaces the primary address)."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"client_type":{"type":"string","enum":["business","individual"],"description":"business or individual."},"lifecycle_stage":{"type":"string","enum":["client","prospect"],"description":"\"client\" promotes a prospect; \"prospect\" demotes a client."},"lead_source":{"type":"string","description":"Where the client came from, matched against the workspace's lead sources."},"property":{"type":"string","description":"Unit or suite, for the single-address shorthand."},"country":{"type":"string","description":"Country, for the single-address shorthand."},"addresses":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string","description":"Street line."},"property":{"type":"string","description":"Unit or suite."},"city":{"type":"string","description":"City."},"state":{"type":"string","description":"State or region."},"zip":{"type":"string","description":"Postal code."},"country":{"type":"string","description":"Country."},"place_id":{"type":"string","description":"Google Places id, if you already hold one."},"label":{"type":"string","description":"Label such as Home or Office."},"is_primary":{"type":"boolean","description":"Mark as the primary address."}},"additionalProperties":false},"maxItems":20,"description":"Replaces the client's whole address list (max 20)."},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"enum":["null"]}]},"description":"Custom field values as {key: value}, using the keys (or labels) from workspace_schema clients.custom_field_definitions. Values are checked against each field's type (text, number, boolean, date YYYY-MM-DD, select option); an unknown field or a bad value is refused. null or \"\" clears a value."}}}}}}}},"/v1/proposals":{"get":{"operationId":"get_proposals","summary":"Search proposals","description":"List proposals and estimates, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Invoices are excluded (use invoices_search). `query` matches title, number or client name; archived proposals are excluded unless `include_archived` is true. Each row carries `sent_at`, `viewed_at`, `view_count`, `accepted_at`, `declined_at` and a derived `opened_by_client`; these, not `status`, show whether the client has seen it. `total` is null without the invoices.view_prices permission. Scoped members see only their assigned clients.","tags":["proposals"],"security":[{"bearerAuth":[]}],"x-tool":"proposals_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"total":{"type":"number","nullable":true},"sub_total":{"type":"number","nullable":true},"discount_amount":{"type":"number","nullable":true},"tax_amount":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"sent_at":{"type":"number"},"viewed_at":{"type":"number"},"view_count":{"type":"number"},"accepted_at":{"type":"number"},"declined_at":{"type":"number"},"opened_by_client":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"},"line_items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"optional":{"type":"boolean"},"group":{"type":"string"},"product_id":{"type":"string"}},"required":["name","quantity","unit_price","total"],"additionalProperties":false}},"line_item_count":{"type":"number"},"public_link":{"type":"string"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["proposals"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","description":"Matches title, number or client name."},"description":"Matches title, number or client name."},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"Exact stored proposal status, case-insensitive."},"description":"Exact stored proposal status, case-insensitive."},{"name":"clientId","in":"query","required":false,"schema":{"type":"string","description":"Only this client's proposals."},"description":"Only this client's proposals."},{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","description":"Include archived proposals (excluded by default)."},"description":"Include archived proposals (excluded by default)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"description":"Cursor (`nextCursor`) from the previous page."}]},"post":{"operationId":"post_proposals","summary":"Create proposals","description":"Create a draft proposal for a client. It is saved as a draft and never sent. Needs `client_id` and `title`; numbered from the workspace's proposal sequence (PROP-NNN). `template_id` (see proposal_templates_list) starts from a saved template's sections, design, settings, line items and notes instead of the workspace defaults. Each `line_items` entry is `{product_id, quantity}` (catalogue product; name and price read server-side) or `{description, unit_price, quantity}` (one-off), where `unit_price` is the price of one unit; without line items the proposal quotes zero. `optional: true` marks a client-selectable add-on (only on `product_id` lines). `details` is a line's printed description and `body` seeds one text section; both accept simple markdown. `notes` is internal and not shown to the client. Totals and tax are computed. A discount cannot be set here; use proposals_update_draft. Signature, deposit and validity terms come from the proposal defaults (proposals_get_defaults). The proposal inherits its visibility from the client. A repeat call with the same `idempotency_key` returns the first proposal (`deduped: true`).","tags":["proposals"],"security":[{"bearerAuth":[]}],"x-tool":"proposals_create_draft","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"number":{"type":"string"},"sub_total":{"type":"number"},"total":{"type":"number"},"currency":{"type":"string"},"line_item_count":{"type":"number"},"requires_signature":{"type":"boolean"},"requires_deposit":{"type":"boolean"},"deposit_amount":{"type":"number"},"valid_until":{"type":"number","nullable":true}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["proposal","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"client_id":{"type":"string","minLength":1,"description":"Client the proposal is for; must belong to this workspace."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Proposal title."},"body":{"type":"string","maxLength":20000,"description":"Text seeded into one text section."},"line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."},"optional":{"type":"boolean","description":"true: a client-selectable add-on on the public page; use only on `product_id` lines."},"group":{"type":"string","maxLength":80,"description":"Group label; adjacent lines sharing one render under a header."}},"additionalProperties":false},"maxItems":100,"description":"Priced lines: {product_id, quantity} or {description, unit_price, quantity}; `optional: true` marks a client-selectable add-on."},"currency":{"type":"string","maxLength":8,"description":"Currency code; defaults to the workspace currency."},"notes":{"type":"string","maxLength":5000,"description":"Internal notes; not shown to the client."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."},"template_id":{"type":"string","maxLength":100,"description":"Proposal template to start from (proposal_templates_list)."}},"required":["client_id","title"]}}}}}},"/v1/proposals/{id}":{"get":{"operationId":"get_proposals_by_id","summary":"Get one of proposals","description":"Fetch one proposal or estimate by id. Returns `{ proposal: null }` if it does not exist, is an invoice, or is outside a scoped member's clients. Includes line items (name, quantity, rate, total, whether client-selectable), `design` (theme, colours, cover, title placement) and `sections` (ids, types, titles, text, images, highlights); change them with proposals_update_design and proposals_edit_sections. `content_locked` / `content_lock_reason` show whether it is locked (accepted, or deposit paid) and so changes only through a change order in the app; `change_orders_pending` counts change orders awaiting the client. `total` is null without the invoices.view_prices permission.","tags":["proposals"],"security":[{"bearerAuth":[]}],"x-tool":"proposals_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"proposals:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"total":{"type":"number","nullable":true},"sub_total":{"type":"number","nullable":true},"discount_amount":{"type":"number","nullable":true},"tax_amount":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"currency":{"type":"string"},"sent_at":{"type":"number"},"viewed_at":{"type":"number"},"view_count":{"type":"number"},"accepted_at":{"type":"number"},"declined_at":{"type":"number"},"opened_by_client":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"},"line_items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"optional":{"type":"boolean"},"group":{"type":"string"},"product_id":{"type":"string"}},"required":["name","quantity","unit_price","total"],"additionalProperties":false}},"line_item_count":{"type":"number"},"public_link":{"type":"string"},"design":{"type":"object","properties":{"theme":{"type":"string"},"accent_color":{"type":"string"},"page_background_color":{"type":"string"},"title_placement":{"type":"string"},"cover_image":{"type":"object","properties":{"url":{"type":"string"},"path":{"type":"string"},"source":{"type":"string"},"banner_id":{"type":"string"},"gallery_path":{"type":"string"},"storage_path":{"type":"string"}},"required":["url","path"],"additionalProperties":false,"nullable":true},"cover_image_style":{"type":"string"},"cover_focal_point":{"type":"number"}},"required":["theme","accent_color","page_background_color","title_placement","cover_image","cover_image_style","cover_focal_point"],"additionalProperties":false},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"structural":{"type":"boolean"},"title":{"type":"string","nullable":true},"highlighted":{"type":"boolean"},"body":{"type":"string"},"image_layout":{"type":"string"},"images":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"caption":{"type":"string"},"alt":{"type":"string"},"source":{"type":"string"},"banner_id":{"type":"string"},"gallery_path":{"type":"string"},"storage_path":{"type":"string"}},"required":["url","caption"],"additionalProperties":false}},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"description":{"type":"string"}},"required":["date","description"],"additionalProperties":false}},"terms_id":{"type":"string"}},"required":["id","type","structural","title","highlighted"],"additionalProperties":false}}},"required":["id","design","sections"],"additionalProperties":false,"nullable":true}},"required":["proposal"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]},"patch":{"operationId":"patch_proposals_by_id","summary":"Update one of proposals","description":"Edit an existing draft proposal, identified by `proposal_id`. Changeable: `title`, internal `notes` (replaced), `add_line_items` (same grammar as proposals_create_draft), `remove_line_items` (by line name), discount (`discount_percent` or `discount_amount`; 0 removes it), signature requirement, deposit (`deposit_percent` or `deposit_amount`; `require_deposit: false` removes it) and expiry (`valid_for_days`; 0 removes it). When lines, discount or deposit change, subtotal, tax (at the proposal's rate, or a product's own rate, on the post-discount subtotal), total and deposit are re-derived server-side; other edits leave the money unchanged. Only drafts are editable: a sent, accepted or declined proposal is refused (recall a sent one to draft with proposals_update_status or in the app), and an accepted or deposit-paid proposal is locked and changes only through a change order in the app. It cannot send, accept, decline, convert, delete, change the client or tax rate, or edit layout, theme or sections. Repeating `add_line_items` adds the lines twice.","tags":["proposals"],"security":[{"bearerAuth":[]}],"x-tool":"proposals_update_draft","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"proposal":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"currency":{"type":"string"},"sub_total":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"deposit_amount":{"type":"number","nullable":true},"line_item_count":{"type":"number"},"requires_signature":{"type":"boolean"},"requires_deposit":{"type":"boolean"},"valid_until":{"type":"number","nullable":true}},"required":["id","status","sub_total","total","deposit_amount","line_item_count","requires_signature","requires_deposit","valid_until"],"additionalProperties":false,"nullable":true},"changed":{"type":"boolean"},"changes":{"type":"array","items":{"type":"string"}}},"required":["proposal","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"New title."},"notes":{"type":"string","maxLength":5000,"description":"Replaces the internal notes."},"add_line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."},"optional":{"type":"boolean","description":"true: a client-selectable add-on on the public page; use only on `product_id` lines."},"group":{"type":"string","maxLength":80,"description":"Group label; adjacent lines sharing one render under a header."}},"additionalProperties":false},"maxItems":100,"description":"Lines to add: {product_id, quantity} or {description, unit_price, quantity}."},"remove_line_items":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":50,"description":"Line names to remove."},"discount_percent":{"type":"number","minimum":0,"maximum":100,"description":"Discount as a percentage; 0 removes it. Use this or `discount_amount`."},"discount_amount":{"type":"number","minimum":0,"description":"Discount as a fixed amount; 0 removes it."},"require_signature":{"type":"boolean","description":"Whether accepting requires a signature."},"deposit_percent":{"type":"number","minimum":0,"maximum":100,"description":"Deposit as a percentage of the total. Use this or `deposit_amount`."},"deposit_amount":{"type":"number","minimum":0,"description":"Deposit as a fixed amount."},"require_deposit":{"type":"boolean","description":"false removes the deposit requirement."},"valid_for_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days until the proposal expires; 0 removes the expiry."}}}}}}}},"/v1/proposals/{id}/send":{"post":{"operationId":"post_proposals_by_id_send","summary":"Send one of proposals (held for approval unless the connection auto-approves)","description":"Send a proposal to its client. Enqueues the send; the proposals worker mints the client link, marks the proposal sent and emails the client with the workspace's proposal email template. Requires `proposal_id`. Invoices or estimates, missing ids and proposals outside a scoped member's clients return 'not found' and nothing is sent. If `from_inbox` is omitted, the workspace's AI & MCP inbox is used, else the only inbox the user can send from; with several and no default, nothing is sent and the result lists them. The email goes to the client alone, so there is no Cc/Bcc to set. At most 10 recipients per email from a starter inbox and 50 from the user's own domain or mailbox (To + Cc + Bcc, workspace addresses excluded); over the cap nothing is sent. The result names the inbox and recipient. A repeat call with the same `idempotency_key` collapses onto one send. Sends a real email and bills for it. Held until the user approves it in the Workspace369 app.","tags":["proposals"],"security":[{"bearerAuth":[]}],"x-tool":"proposals_send","x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"proposals:write","x-billing-class":"mcp_tool_send","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"proposal_id":{"type":"string"},"message_id":{"type":"string"},"to":{"type":"string"},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"}},"required":["sent","proposal_id","message_id"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"from_inbox":{"type":"string","description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}}}}}}}},"/v1/invoices":{"get":{"operationId":"get_invoices","summary":"Search invoices","description":"List invoices, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Proposals and estimates are excluded (use proposals_search). `query` matches number, title, client name or PO number; `number` looks up one invoice by its human number (e.g. '26-6') and returns its `id`. Archived invoices are excluded unless `include_archived` is true. There is no 'Overdue' status; use each row's `is_overdue`, `due_date` and `balance_due`. `total` and `balance_due` are null without the invoices.view_prices permission. Scoped members see only their assigned clients.","tags":["invoices"],"security":[{"bearerAuth":[]}],"x-tool":"invoices_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"title":{"type":"string"},"total":{"type":"number","nullable":true},"currency":{"type":"string"},"invoice_date":{"type":"number"},"due_date":{"type":"number"},"balance_due":{"type":"number","nullable":true},"is_paid":{"type":"boolean"},"is_overdue":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["invoices"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","description":"Matches invoice number, title, client name or PO number."},"description":"Matches invoice number, title, client name or PO number."},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"Exact stored invoice status, case-insensitive (e.g. Draft, Pending, Paid). Overdue is not a status."},"description":"Exact stored invoice status, case-insensitive (e.g. Draft, Pending, Paid). Overdue is not a status."},{"name":"clientId","in":"query","required":false,"schema":{"type":"string","description":"Only this client's invoices."},"description":"Only this client's invoices."},{"name":"number","in":"query","required":false,"schema":{"type":"string","description":"Human invoice number (e.g. '26-6'); returns that invoice and its `id`."},"description":"Human invoice number (e.g. '26-6'); returns that invoice and its `id`."},{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","description":"Include archived invoices (excluded by default)."},"description":"Include archived invoices (excluded by default)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"description":"Cursor (`nextCursor`) from the previous page."}]},"post":{"operationId":"post_invoices","summary":"Create invoices","description":"Create a draft invoice for a client. It is saved as a draft and never sent. Needs `client_id` and at least one line item: `{product_id, quantity}` (catalogue product; `unit_price` overrides its price) or `{description, unit_price, quantity}` (one-off). `unit_price` is the price of one unit; line totals are computed. `details` is the line's printed description and accepts simple markdown. A draft without a `title` is named \"Invoice for <client>\". The number comes from the workspace's invoice sequence (`number` sets one explicitly). `due_in_days` (0 = due on receipt) or `due_date` (MM/DD/YYYY) set the due date; `payment_term` is the printed label only. Tax is `tax_percent` or `tax_amount`, discount is `discount_percent` or `discount_amount` (not both of either); tax applies after the discount. `notes` prints on the invoice. The workspace's Invoice Defaults (due terms, tax, discount, deposit, notes) apply unless `apply_workspace_defaults` is false, and explicit values override them (see invoices_get_defaults). The invoice inherits its visibility from the client. A repeat call with the same `idempotency_key` returns the first invoice (`deduped: true`).","tags":["invoices"],"security":[{"bearerAuth":[]}],"x-tool":"invoices_create_draft","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"total":{"type":"number","nullable":true},"invoice_date":{"type":"string"},"due_date":{"type":"string"},"project_id":{"type":"string"}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["invoice","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"client_id":{"type":"string","minLength":1,"description":"Client the invoice is for; must belong to this workspace."},"line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."}},"additionalProperties":false},"minItems":1,"description":"Invoice lines: {product_id, quantity} or {description, unit_price, quantity}."},"currency":{"type":"string","description":"Currency code; defaults to the workspace currency."},"title":{"type":"string","description":"Short title naming the work; without it the draft is called \"Invoice for <client>\"."},"number":{"type":"string","description":"Explicit invoice number; omit to use the workspace sequence."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."},"timezone":{"type":"string","maxLength":64,"description":"IANA time zone that decides which day \"today\" is for the dates."},"invoice_date":{"type":"string","minLength":1,"maxLength":10,"description":"Issue date, MM/DD/YYYY; defaults to today on create."},"due_date":{"type":"string","minLength":1,"maxLength":10,"description":"Due date, MM/DD/YYYY. Use this or `due_in_days`."},"due_in_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days from the issue date until due; 0 = due on receipt."},"payment_term":{"type":"string","maxLength":120,"description":"Printed term label (e.g. \"Net 30\"); does not compute the due date."},"tax_percent":{"type":"number","minimum":0,"maximum":100,"description":"Tax as a percentage of the post-discount subtotal. Use this or `tax_amount`."},"tax_amount":{"type":"number","minimum":0,"description":"Tax as a fixed amount. Use this or `tax_percent`."},"deposit_percent":{"type":"number","minimum":0,"maximum":100,"description":"Request a deposit of this percentage of the total; 0 disables it."},"apply_workspace_defaults":{"type":"boolean","description":"Apply the workspace's Invoice Defaults (default true); explicit values override them."},"notes":{"type":"string","maxLength":5000,"description":"Notes printed on the invoice."},"discount_percent":{"type":"number","minimum":0,"maximum":100,"description":"Discount as a percentage of the subtotal. Use this or `discount_amount`."},"discount_amount":{"type":"number","minimum":0,"description":"Discount as a fixed amount. Use this or `discount_percent`."},"project_id":{"type":"string","minLength":1,"maxLength":200,"description":"Link the invoice to a project for job costing."}},"required":["client_id","line_items"]}}}}}},"/v1/invoices/{id}":{"get":{"operationId":"get_invoices_by_id","summary":"Get one of invoices","description":"Fetch one invoice by `id` or by `invoice_number` (e.g. '26-6'). Returns `{ invoice: null }` if it does not exist, is a proposal/estimate, or is outside a scoped member's clients; if two invoices share a number it refuses and asks for the `id`. Includes `line_items` (up to 100, each with the `line_number` that invoices_update_draft's `update_services` addresses by position) and the true `line_item_count`. `content_locked` / `content_lock_reason` show whether the invoice is locked by a recorded payment or credit (its items and prices then change only through a change order in the app); `change_orders_pending` counts change orders awaiting the client. Monetary fields are null without the invoices.view_prices permission.","tags":["invoices"],"security":[{"bearerAuth":[]}],"x-tool":"invoices_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"invoices:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"title":{"type":"string"},"total":{"type":"number","nullable":true},"currency":{"type":"string"},"invoice_date":{"type":"number"},"due_date":{"type":"number"},"balance_due":{"type":"number","nullable":true},"is_paid":{"type":"boolean"},"is_overdue":{"type":"boolean"},"is_archived":{"type":"boolean"},"content_locked":{"type":"boolean"},"content_lock_reason":{"type":"string","nullable":true},"change_orders_pending":{"type":"number"},"line_items":{"type":"array","items":{"type":"object","properties":{"line_number":{"type":"number"},"name":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number","nullable":true},"total":{"type":"number","nullable":true},"product_id":{"type":"string"}},"required":["line_number","name","quantity","unit_price","total"],"additionalProperties":false}},"line_item_count":{"type":"number"},"public_link":{"type":"string"}},"required":["id"],"additionalProperties":false,"nullable":true}},"required":["invoice"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"invoice_number","in":"query","required":false,"schema":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'. Pass this or `id`."},"description":"Human invoice number, e.g. '26-6'. Pass this or `id`."}]},"patch":{"operationId":"patch_invoices_by_id","summary":"Update one of invoices","description":"Edit an existing invoice by `invoice_id` or `invoice_number`. Changeable: `notes` (replaced), discount (`discount_percent` or `discount_amount`; 0 removes it), tax (`tax_percent` or `tax_amount`), `deposit_percent`, `invoice_date` / `due_date` (MM/DD/YYYY) or `due_in_days`, `payment_term` (printed label only), and `project_id` / `unlink_project`. Lines: `add_services` (same shape as invoices_create_draft), `remove_services` (by line name) and `update_services` (edit a line in place by `line_number`: `description`, `details`, `quantity`, `unit_price`). Line numbers are positions from invoices_get, resolved after `remove_services` and before `add_services`; an out-of-range number is refused and nothing is written. Totals, tax and paid state are re-derived. It sends nothing. Only drafts are editable by default; a sent invoice is refused unless `allow_non_draft: true`, since the edit changes what the customer sees at the public invoice link. A locked invoice (a payment or credit recorded, or any sent invoice when the workspace locks on send) is always refused. Payment state (see payments_record), status, number, client and currency never change.","tags":["invoices"],"security":[{"bearerAuth":[]}],"x-tool":"invoices_update_draft","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"total":{"type":"number","nullable":true}},"required":["id","status","total"],"additionalProperties":false,"nullable":true},"changed":{"type":"boolean"},"changes":{"type":"array","items":{"type":"string"}}},"required":["invoice","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6'. Pass this or `invoice_id`."},"notes":{"type":"string","description":"Replaces the notes printed on the invoice."},"discount_percent":{"type":"number","minimum":0,"maximum":100,"description":"Discount as a percentage; 0 removes it. Use this or `discount_amount`."},"discount_amount":{"type":"number","minimum":0,"description":"Discount as a fixed amount; 0 removes it. Use this or `discount_percent`."},"add_services":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"description":"Short line name (one-off charge); optional when `product_id` is given."},"details":{"type":"string","maxLength":5000,"description":"What the line includes, printed under its name; accepts simple markdown."},"product_id":{"type":"string","minLength":1,"description":"Catalogue product to bill (products_list); its name and set price are read server-side."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."},"unit_price":{"type":"number","minimum":0,"description":"Price of ONE unit; with a `product_id` it overrides the catalogue price."}},"additionalProperties":false},"description":"Lines to add: {product_id, quantity} or {description, unit_price, quantity}."},"remove_services":{"type":"array","items":{"type":"string","minLength":1},"description":"Line names to remove (case-insensitive substring match)."},"update_services":{"type":"array","items":{"type":"object","properties":{"line_number":{"type":"integer","minimum":1,"maximum":200,"description":"1-based position of the line, as returned by invoices_get."},"description":{"type":"string","minLength":1,"maxLength":500,"description":"New line name."},"details":{"type":"string","maxLength":5000,"description":"New printed description; \"\" clears it."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"New number of units."},"unit_price":{"type":"number","minimum":0,"description":"New price of one unit."}},"required":["line_number"],"additionalProperties":false},"maxItems":50,"description":"Edit existing lines in place by `line_number` (from invoices_get)."},"timezone":{"type":"string","maxLength":64,"description":"IANA time zone that decides which day \"today\" is for the dates."},"invoice_date":{"type":"string","minLength":1,"maxLength":10,"description":"Issue date, MM/DD/YYYY; defaults to today on create."},"due_date":{"type":"string","minLength":1,"maxLength":10,"description":"Due date, MM/DD/YYYY. Use this or `due_in_days`."},"due_in_days":{"type":"integer","minimum":0,"maximum":365,"description":"Days from the issue date until due; 0 = due on receipt."},"payment_term":{"type":"string","maxLength":120,"description":"Printed term label (e.g. \"Net 30\"); does not compute the due date."},"tax_percent":{"type":"number","minimum":0,"maximum":100,"description":"Tax as a percentage of the post-discount subtotal. Use this or `tax_amount`."},"tax_amount":{"type":"number","minimum":0,"description":"Tax as a fixed amount. Use this or `tax_percent`."},"deposit_percent":{"type":"number","minimum":0,"maximum":100,"description":"Request a deposit of this percentage of the total; 0 disables it."},"project_id":{"type":"string","minLength":1,"maxLength":200,"description":"Link the invoice to a project."},"unlink_project":{"type":"boolean","description":"true removes the project link."},"allow_non_draft":{"type":"boolean","description":"Allow editing an already-sent (unlocked) invoice; it changes what the customer sees."}}}}}}}},"/v1/invoices/{id}/send":{"post":{"operationId":"post_invoices_by_id_send","summary":"Send one of invoices (held for approval unless the connection auto-approves)","description":"Send an invoice to its client by email or SMS, as the app's Send email sheet does. Identify it by `invoice_id` or `invoice_number` (e.g. '26-6'). `channel` is 'email' (default) or 'sms'; the recipient defaults to the client's email or phone. `to`, `cc` and `bcc` must be saved on the invoice's client or its contacts, or be a team member or the workspace; others are refused. Email uses the workspace's email settings and invoice template, with the invoice button and PDF attached; `template` (see email_send_options) replaces the template, and `subject` and `message` override its subject and body. If `from_inbox` is omitted, the workspace's AI & MCP inbox is used, else the only inbox the user can send from; with several and no default, nothing is sent and the result lists them. `cc`/`bcc` replace the default copies. At most 10 recipients per email from a starter inbox and 50 from the user's own domain or mailbox (To + Cc + Bcc, workspace addresses excluded); over the cap nothing is sent. SMS texts the invoice link, with `message` as a note. Refuses when the invoice has no link yet. Sends a real message and bills for it. Held until the user approves it in the Workspace369 app.","tags":["invoices"],"security":[{"bearerAuth":[]}],"x-tool":"invoices_send","x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"invoices:write","x-billing-class":"mcp_tool_send","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"channel":{"type":"string","enum":["email","sms"]},"to":{"type":"string"},"message_id":{"type":"string"},"from_inbox":{"type":"string"},"from_inbox_id":{"type":"string"},"cc":{"type":"array","items":{"type":"string"}},"bcc":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"conversation_id":{"type":"string"},"body_source":{"type":"string","enum":["message","template","default"]},"template_id":{"type":"string"}},"required":["sent","channel","to","message_id"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"invoice_number":{"type":"string","minLength":1,"description":"Human invoice number, e.g. '26-6' (from invoices_search). Pass this or invoice_id."},"channel":{"type":"string","enum":["email","sms"],"description":"email (default) or sms. Email goes through the sending inbox; SMS texts the invoice link."},"to":{"type":"string","description":"Recipient: an email address (channel email) or phone number (channel sms). Defaults to the client's email or phone."},"message":{"type":"string","description":"Email: the whole body, replacing the template's. SMS: a note in the text. Markdown: `# ` / `## ` / `### ` start a large / medium / small heading; `- ` or `1. ` starts a bullet or numbered item; inline `**bold**`, `*italic*`, `<u>underline</u>`, `~~strikethrough~~`, `[text](https://…)` links and `![alt](https://…)` images. Text without these markers goes out as plain paragraphs. Merge fields like `{{client.first_name}}`, `{{workspace.name}}` and `{{sender.name}}` are filled in."},"subject":{"type":"string","description":"Email only. Replaces the template's or default subject."},"template":{"type":"string","description":"Email only. A library template, by id or name, used instead of the default invoice template."},"from_inbox":{"type":"string","description":"Email only. The inbox to send from, by label (like 'Billing') or address. Omitted, the email goes from the workspace's inbox for AI & MCP emails, else the only inbox the user can send from; when there are several and no such default, nothing is sent and the result lists them."},"cc":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Cc addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"bcc":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Bcc addresses. Email only. The final list: passing it replaces that field's defaults entirely (the Bcc to the workspace's own email, default Cc/Bcc, archive Bcc, a template's copies), so to add someone pass the defaults plus the new address, and to remove someone leave them out; `[]` means none. Omitted, the defaults apply. The sending inbox's compliance archive Bcc is always added. Each address counts toward the per-email cap."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}}}}}}}},"/v1/contracts":{"get":{"operationId":"get_contracts","summary":"Search contracts","description":"List contracts, newest first (up to `limit`, default 25, max 50). Filter by `status_group` (draft; waiting = sent, in progress or sealing; completed; declined; voided; expired), `client_id`, and `archived` ('exclude' by default, or 'only'). `query` matches words in the title. One call scans at most 200 contracts; `scan_truncated: true` means more may match, so pass `next_cursor` to continue. Field values, signatures and signer IP addresses are never returned. Members limited to specific clients see only contracts in their book.","tags":["contracts"],"security":[{"bearerAuth":[]}],"x-tool":"contracts_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"contracts:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contracts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false}},"next_cursor":{"type":"string","nullable":true},"scan_truncated":{"type":"boolean"}},"required":["contracts","next_cursor","scan_truncated"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Words to find in the contract title."},"description":"Words to find in the contract title."},{"name":"status_group","in":"query","required":false,"schema":{"type":"string","enum":["draft","waiting","completed","declined","voided","expired"],"description":"waiting = sent, in progress or sealing."},"description":"waiting = sent, in progress or sealing."},{"name":"client_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128,"description":"Only this client's contracts."},"description":"Only this client's contracts."},{"name":"archived","in":"query","required":false,"schema":{"type":"string","enum":["exclude","only"],"description":"Default exclude."},"description":"Default exclude."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"description":"Results per page (default 25, max 50)."},"description":"Results per page (default 25, max 50)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128,"description":"The `next_cursor` value from the previous response, passed back unchanged; omit for the first page."},"description":"The `next_cursor` value from the previous response, passed back unchanged; omit for the first page."}]},"post":{"operationId":"post_contracts","summary":"Create contracts","description":"Create a DRAFT contract from a template. Pass `template_id` (see contract_templates_list) and `client_id` when the template has a client role; the client's primary email fills that role. Pass `recipients` for roles whose assignment is manual, as { role_key, name, email }; each email must be saved on the client (or its contacts), a team member or the workspace. Optional `title`, `message` (the invitation email subject and body) and `reminders` (the automatic reminder cadence: first after N days, then every N days, at most N). Nothing is sent: the draft can be reviewed in Workspace369 or sent with contracts_send. `unassigned_role_keys` lists roles that still need a person before the contract can be sent. Each call creates a new draft.","tags":["contracts"],"security":[{"bearerAuth":[]}],"x-tool":"contracts_create_draft","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"contracts:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false},"unassigned_role_keys":{"type":"array","items":{"type":"string"}}},"required":["contract","unassigned_role_keys"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"template_id":{"type":"string","minLength":1,"maxLength":128,"description":"Contract template id (from contract_templates_list)."},"client_id":{"type":"string","minLength":1,"maxLength":128,"description":"Required when the template has a client role."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Optional contract title, 1-200 characters."},"message":{"type":"object","properties":{"subject":{"type":"string","maxLength":200},"body":{"type":"string","maxLength":5000}},"required":["subject","body"],"additionalProperties":false,"description":"Invitation email subject and body. Setting it also needs the contracts edit permission."},"recipients":{"type":"array","items":{"type":"object","properties":{"role_key":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":254}},"required":["role_key","name","email"],"additionalProperties":false},"maxItems":20,"description":"One entry per template role whose assignment is manual."},"reminders":{"type":"object","properties":{"first_after_days":{"type":"integer","minimum":1,"maximum":14,"description":"Days after the invitation before the first reminder."},"every_days":{"type":"integer","minimum":1,"maximum":14,"description":"Days between later reminders."},"max":{"type":"integer","minimum":0,"maximum":10,"description":"Most reminders per recipient; 0 turns automatic reminders off."}},"required":["first_after_days","every_days","max"],"additionalProperties":false,"description":"Automatic email reminders for this contract. Omit to use the template's defaults, then Settings → Contracts. Setting it also needs the contracts edit permission."}},"required":["template_id"]}}}}}},"/v1/contracts/{id}":{"get":{"operationId":"get_contracts_by_id","summary":"Get one of contracts","description":"Fetch one contract by `contract_id`: status, dates, verification and expiry settings, invitation subject, the sealed document's SHA-256 once completed, and each recipient's name, email, role, routing order and progress. Returns `{ contract: null }` if the id does not exist or is outside a scoped member's book. `send_request` is the latest send started with contracts_send: `queued` while it runs, `sent`, or `failed` with the `failure_code`; null when there is none. Field values, signature images and signer IP addresses are never returned.","tags":["contracts"],"security":[{"bearerAuth":[]}],"x-tool":"contracts_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"contracts:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"},"source":{"type":"string","nullable":true},"template_id":{"type":"string","nullable":true},"proposal_id":{"type":"string","nullable":true},"invoice_id":{"type":"string","nullable":true},"verification":{"type":"string","nullable":true},"expires_after_days":{"type":"integer","nullable":true},"message_subject":{"type":"string","nullable":true},"voided_reason":{"type":"string","nullable":true},"declined_reason":{"type":"string","nullable":true},"sealed":{"type":"object","properties":{"sha256":{"type":"string"},"seal_level":{"type":"string","nullable":true},"sealed_at":{"type":"string","nullable":true}},"required":["sha256","seal_level","sealed_at"],"additionalProperties":false,"nullable":true},"send_request":{"type":"object","properties":{"status":{"type":"string","enum":["queued","sent","failed"]},"requested_at":{"type":"string","nullable":true},"finished_at":{"type":"string","nullable":true},"failure_code":{"type":"string","nullable":true}},"required":["status","requested_at","finished_at","failure_code"],"additionalProperties":false,"nullable":true},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","nullable":true},"role":{"type":"string"},"routing_order":{"type":"integer"},"status":{"type":"string"},"in_person":{"type":"boolean"},"invited_at":{"type":"string","nullable":true},"opened_at":{"type":"string","nullable":true},"verified_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"declined_at":{"type":"string","nullable":true}},"required":["id","name","email","role","routing_order","status","in_person","invited_at","opened_at","verified_at","completed_at","declined_at"],"additionalProperties":false}}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed","source","template_id","proposal_id","invoice_id","verification","expires_after_days","message_subject","voided_reason","declined_reason","sealed","send_request","recipients"],"additionalProperties":false,"nullable":true}},"required":["contract"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/contracts/{id}/send":{"post":{"operationId":"post_contracts_by_id_send","summary":"Send one of contracts (held for approval unless the connection auto-approves)","description":"Send a draft contract for signature: the document is frozen, the first routing group is emailed and the expiry clock starts. Needs `contract_id`. It uses one of the workspace's included monthly contracts if any remain; otherwise it costs Tokens, and nothing is sent if that charge fails. This emails real recipients and cannot be undone (voiding stops it). The send runs in the background (a contract from a text template is rendered first, which can take minutes), so the result `status: \"sending\"` confirms nothing yet: contracts_get shows whether it went out (status no longer draft; `send_request.failure_code` explains a failure). Calling again while a send is in progress starts nothing new (`deduplicated: true`). Held until the user approves it in the Workspace369 app.","tags":["contracts"],"security":[{"bearerAuth":[]}],"x-tool":"contracts_send","x-readOnly":false,"x-destructive":true,"x-requires-approval":true,"x-required-scope":"contracts:send","x-billing-class":"mcp_tool_send","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"status_group":{"type":"string"},"client_id":{"type":"string","nullable":true},"is_archived":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"sent_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"required_total":{"type":"integer"},"required_completed":{"type":"integer"}},"required":["id","title","status","status_group","client_id","is_archived","created_at","sent_at","expires_at","completed_at","required_total","required_completed"],"additionalProperties":false},"status":{"type":"string","enum":["sending","sent"]},"deduplicated":{"type":"boolean"},"billing":{"type":"string","enum":["unlimited","included","tokens","already_charged"]},"tokens":{"type":"integer"}},"required":["contract","status","deduplicated","billing","tokens"],"additionalProperties":false}}}},"202":{"description":"Held for approval. Nothing ran yet; the user approves in the Workspace369 app, then approvals_get reports the outcome.","content":{"application/json":{"schema":{"type":"object","properties":{"held_for_approval":{"type":"boolean"},"approval_id":{"type":"string"},"approval_url":{"type":"string"},"approval_expires_at":{"type":"string"}},"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}}}},"/v1/projects":{"get":{"operationId":"get_projects","summary":"Search projects","description":"List projects, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `query` matches name or client id; `status` and `clientId` narrow the results. Scoped members see only their assigned clients' projects. To read one in full use projects_get.","tags":["projects"],"security":[{"bearerAuth":[]}],"x-tool":"projects_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"projects:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["projects"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","description":"Matches name or client id."},"description":"Matches name or client id."},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"Only projects with this stored status."},"description":"Only projects with this stored status."},{"name":"clientId","in":"query","required":false,"schema":{"type":"string","description":"Only this client's projects."},"description":"Only this client's projects."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"description":"Cursor (`nextCursor`) from the previous page."}]},"post":{"operationId":"post_projects","summary":"Create projects","description":"Create a project. Needs `project_name`. `status` is planning, in_progress, on_hold, completed or cancelled (display names like \"In Progress\" are accepted). `priority` is low, medium, high or critical. `start_date`/`end_date` are ISO-8601; a date-only value is that day in the workspace time zone. With a `client_id` the project inherits that client's visibility; a client-less project is visible to full members only. A repeat call with the same `idempotency_key` returns the first project (`deduped: true`). To change one use projects_update; to find one, projects_search.","tags":["projects"],"security":[{"bearerAuth":[]}],"x-tool":"projects_create","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"projects:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["project","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"project_name":{"type":"string","minLength":1,"description":"Project name."},"status":{"type":"string","description":"planning, in_progress, on_hold, completed or cancelled (display names like \"In Progress\" are accepted)."},"client_id":{"type":"string","description":"Client the project belongs to; the project inherits its visibility."},"description":{"type":"string","description":"Project description."},"start_date":{"type":"string","description":"ISO-8601 start; a date-only value is that day in the workspace time zone."},"end_date":{"type":"string","description":"ISO-8601 end; a date-only value is that day in the workspace time zone."},"budget":{"type":"number","minimum":0,"description":"Project budget."},"priority":{"type":"string","enum":["low","medium","high","critical"],"description":"low, medium, high or critical."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the project."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["project_name"]}}}}}},"/v1/projects/{id}":{"get":{"operationId":"get_projects_by_id","summary":"Get one of projects","description":"Fetch one project by id. Returns `{ project: null }` if it does not exist or is outside a scoped member's assigned clients. Read-only. Find ids with projects_search; edit with projects_update.","tags":["projects"],"security":[{"bearerAuth":[]}],"x-tool":"projects_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"projects:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false,"nullable":true}},"required":["project"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]},"patch":{"operationId":"patch_projects_by_id","summary":"Update one of projects","description":"Update a project by `id` (from projects_search): `name`, `description`, `status` (planning, in_progress, on_hold, completed, cancelled), `budget`, `priority` (low, medium, high, critical) or `notes`. Only the fields passed change. Progress cannot be set; it is derived from task completion. Moving to in_progress or completed stamps the actual start/end dates. Returns the updated `project`. To add a project use projects_create.","tags":["projects"],"security":[{"bearerAuth":[]}],"x-tool":"projects_update","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"projects:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"client_id":{"type":"string"}},"required":["id"],"additionalProperties":false}},"required":["project"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"New name."},"description":{"type":"string","description":"New description."},"status":{"type":"string","enum":["planning","in_progress","on_hold","completed","cancelled"],"description":"planning, in_progress, on_hold, completed or cancelled."},"budget":{"type":"number","minimum":0,"description":"New budget."},"priority":{"type":"string","enum":["low","medium","high","critical"],"description":"low, medium, high or critical."},"notes":{"type":"string","description":"New notes."}}}}}}}},"/v1/tasks":{"get":{"operationId":"get_tasks","summary":"Search tasks","description":"List tasks across the workspace's boards, paged (up to `limit`, default 25, max 100, plus `nextCursor`). Filters: `query` (title), `boardId` (from task_boards_list), `status` (names normalized, `todo` matches `To-do`), `priority` (1 low, 2 medium, 3 high), `assignee_id` (a member id), `due_before` / `due_after` (ISO-8601 dates), `tags` (matches any) and `is_starred`. Overdue work is `assignee_id` with a `due_before` of now. Filters apply after the page is cut, so a filtered page can be short; keep following `nextCursor`. Rows carry an 80-character description preview; `include_full_descriptions: true` returns complete descriptions. Scoped members see only tasks on boards they can access.","tags":["tasks"],"security":[{"bearerAuth":[]}],"x-tool":"tasks_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"},"client_id":{"type":"string"},"priority":{"type":"number"},"due_date":{"type":"number"},"tags":{"type":"array","items":{"type":"string"}},"description":{"type":"string"},"assignees":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"is_starred":{"type":"boolean"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["tasks"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","description":"Matches task titles."},"description":"Matches task titles."},{"name":"boardId","in":"query","required":false,"schema":{"type":"string","description":"Only tasks on this board (task_boards_list)."},"description":"Only tasks on this board (task_boards_list)."},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"Board status name; names are normalized (`todo` matches `To-do`)."},"description":"Board status name; names are normalized (`todo` matches `To-do`)."},{"name":"priority","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":3,"description":"1 low, 2 medium, 3 high."},"description":"1 low, 2 medium, 3 high."},{"name":"assignee_id","in":"query","required":false,"schema":{"type":"string","description":"Workspace member id of the assignee."},"description":"Workspace member id of the assignee."},{"name":"due_before","in":"query","required":false,"schema":{"type":"string","description":"Only tasks due before this ISO-8601 date."},"description":"Only tasks due before this ISO-8601 date."},{"name":"due_after","in":"query","required":false,"schema":{"type":"string","description":"Only tasks due after this ISO-8601 date."},"description":"Only tasks due after this ISO-8601 date."},{"name":"tags","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Only tasks having any of these tags."},"description":"Only tasks having any of these tags."},{"name":"is_starred","in":"query","required":false,"schema":{"type":"boolean","description":"true: only starred tasks."},"description":"true: only starred tasks."},{"name":"include_full_descriptions","in":"query","required":false,"schema":{"type":"boolean","description":"Return complete descriptions instead of an 80-character preview."},"description":"Return complete descriptions instead of an 80-character preview."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"description":"Cursor (`nextCursor`) from the previous page."}]},"post":{"operationId":"post_tasks","summary":"Create tasks","description":"Create ONE task on a board. Needs `board_id` (from task_boards_list) and `title`. `status` is validated against the board's statuses (names normalized) and defaults to the board default; `priority` is 1 low, 2 medium, 3 high. `assignees` are workspace member ids. `subtasks` are checklist titles created with the task. `custom_fields` is `[{field, value}]` using the field ids, types and dropdown options from task_board_schema (dates ISO 8601, checkboxes true/false, numbers numeric). `start_date` and `due_date` are epoch milliseconds or null; `blocked_by` lists ids of tasks on the same board that must finish first. A task whose exact title (case- and whitespace-insensitive) already exists on the board is skipped and returned with `deduped: true`. `description` is plain text (markdown renders literally). Scoped members can create only on boards they can access. A repeat call with the same `idempotency_key` returns the first task.","tags":["tasks"],"security":[{"bearerAuth":[]}],"x-tool":"tasks_create","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"}},"required":["id","board_id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["task","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board to create the task on (task_boards_list)."},"title":{"type":"string","minLength":1,"description":"Task title."},"status":{"type":"string","description":"Board status name; defaults to the board default."},"description":{"type":"string","description":"Plain-text description (markdown renders literally)."},"priority":{"type":"integer","minimum":1,"maximum":3,"description":"1 low, 2 medium, 3 high."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the task; on update this replaces the list."},"assignees":{"type":"array","items":{"type":"string","minLength":1},"description":"Workspace member ids; on update this replaces the list ([] clears)."},"is_starred":{"type":"boolean","description":"Whether the task is starred."},"custom_fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"description":"Custom field id or unique name (task_board_schema)."},"value":{"type":"string","description":"The value as text; numbers and booleans are accepted and coerced per the field type (dates ISO 8601)."}},"required":["field","value"],"additionalProperties":false},"description":"Custom field values as [{field, value}], using field ids and types from task_board_schema; on update they are merged into the stored values."},"estimated_hours":{"type":"number","minimum":0,"description":"Estimated hours."},"subtasks":{"type":"array","items":{"type":"string","minLength":1},"maxItems":100,"description":"Checklist titles created with the task."},"due_date":{"type":"integer","minimum":0,"nullable":true,"description":"Due date, epoch milliseconds; null means none (on update, clears it)."},"start_date":{"type":"integer","minimum":0,"nullable":true,"description":"Start date, epoch milliseconds; null means none (on update, clears it)."},"is_milestone":{"type":"boolean","description":"Show the task as a milestone on the Gantt chart."},"blocked_by":{"type":"array","items":{"type":"string","minLength":1},"description":"Ids of tasks on the same board that must finish first; on update this replaces the list."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["board_id","title"]}}}}}},"/v1/tasks/{id}":{"get":{"operationId":"get_tasks_by_id","summary":"Get one of tasks","description":"Get the details of one task on a board: description, status, priority, dates, tags, assignees, estimate, star state, custom-field values (resolved against the board schema) and subtasks. Needs `board_id` and the task `id` (or a `title`, accepted only when it identifies one unambiguous task; ambiguous titles are refused with the candidates).","tags":["tasks"],"security":[{"bearerAuth":[]}],"x-tool":"tasks_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"tasks:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"board_id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"status_id":{"type":"string"},"priority":{"type":"number"},"due_date":{"type":"number"},"start_date":{"type":"number"},"is_milestone":{"type":"boolean"},"blocked_by":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}},"assignees":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}},"required":["id","name","email"],"additionalProperties":false}},"estimated_hours":{"type":"number"},"is_starred":{"type":"boolean"},"subtasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"is_completed":{"type":"boolean"}},"required":["id","title","is_completed"],"additionalProperties":false}},"custom_fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"workflow_key":{"type":"string"},"type":{"type":"string"},"value":{}},"required":["id"],"additionalProperties":false}},"created_at":{"type":"number"},"updated_at":{"type":"number"}},"required":["id","board_id","is_milestone","blocked_by","tags","assignees","is_starred","subtasks","custom_fields"],"additionalProperties":false}},"required":["task"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"board_id","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Board the task is on (task_boards_list)."},"description":"Board the task is on (task_boards_list)."},{"name":"title","in":"query","required":false,"schema":{"type":"string","description":"Task title; accepted only if it identifies one task."},"description":"Task title; accepted only if it identifies one task."}]},"patch":{"operationId":"patch_tasks_by_id","summary":"Update one of tasks","description":"Update a task by `id` on its `board_id`. Only the fields passed change. `title`, `status` (validated against the board's statuses), `description` (null clears), `priority` (1-3), `estimated_hours` (null clears) and `is_starred` are replaced as given. `tags`, `assignees` and `blocked_by` REPLACE the stored list ([] clears). `custom_fields` ([{field, value}], using ids from task_board_schema) is merged into the stored values; `clear_custom_fields` lists field ids or unique names to remove (a required field cannot be cleared). `start_date`/`due_date` are epoch milliseconds (null clears). A blocker must be an existing task on the same board, and an edge that would create a dependency cycle is rejected. Subtask changes go through tasks_subtasks_update. Returns the merged task, or an error if the task does not exist or is on a board outside a scoped member's access.","tags":["tasks"],"security":[{"bearerAuth":[]}],"x-tool":"tasks_update","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"tasks:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"board_id":{"type":"string"}},"required":["id","board_id"],"additionalProperties":false}},"required":["task"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"board_id":{"type":"string","minLength":1,"description":"Board the task is on."},"title":{"type":"string","minLength":1,"description":"New title."},"status":{"type":"string","description":"Board status name."},"description":{"type":"string","nullable":true,"description":"New description (null clears it)."},"priority":{"type":"integer","minimum":1,"maximum":3,"description":"1 low, 2 medium, 3 high."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for the task; on update this replaces the list."},"assignees":{"type":"array","items":{"type":"string","minLength":1},"description":"Workspace member ids; on update this replaces the list ([] clears)."},"is_starred":{"type":"boolean","description":"Whether the task is starred."},"custom_fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"description":"Custom field id or unique name (task_board_schema)."},"value":{"type":"string","description":"The value as text; numbers and booleans are accepted and coerced per the field type (dates ISO 8601)."}},"required":["field","value"],"additionalProperties":false},"description":"Custom field values as [{field, value}], using field ids and types from task_board_schema; on update they are merged into the stored values."},"estimated_hours":{"type":"number","minimum":0,"nullable":true,"description":"Estimated hours (null clears)."},"clear_custom_fields":{"type":"array","items":{"type":"string","minLength":1},"description":"Field ids or unique names to remove; a required field cannot be cleared."},"due_date":{"type":"integer","minimum":0,"nullable":true,"description":"Due date, epoch milliseconds; null means none (on update, clears it)."},"start_date":{"type":"integer","minimum":0,"nullable":true,"description":"Start date, epoch milliseconds; null means none (on update, clears it)."},"is_milestone":{"type":"boolean","description":"Show the task as a milestone on the Gantt chart."},"blocked_by":{"type":"array","items":{"type":"string","minLength":1},"description":"Ids of tasks on the same board that must finish first; on update this replaces the list."}},"required":["board_id"]}}}}}},"/v1/requests":{"get":{"operationId":"get_requests","summary":"Search requests","description":"List inbound prospect submissions (leads from contact forms, Pages, Funnels and the inbound lead API), newest first, paged (up to `limit`, default 25, max 100, plus `nextCursor`). `status` is new, reviewed, converted or archived (one at a time). `form_id` accepts an intake-form slug or a funnel id (funnel leads are identified by their `source`, 'funnel:{id}'). `query` matches name, email, phone and message. `form_id` and `query` are applied after paging, so a page can be short; keep following `nextCursor`.","tags":["requests"],"security":[{"bearerAuth":[]}],"x-tool":"requests_search","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"requests:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"number"},"source":{"type":"string"},"form_id":{"type":"string"},"message_preview":{"type":"string"},"converted_client_id":{"type":"string"},"assigned_to":{"type":"string"}},"required":["id","name","status","created_at"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["requests"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["new","reviewed","converted","archived"],"description":"Only requests with this status."},"description":"Only requests with this status."},{"name":"form_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Intake-form slug or funnel id."},"description":"Intake-form slug or funnel id."},{"name":"query","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Matches name, email, phone and message."},"description":"Matches name, email, phone and message."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."},"description":"The `nextCursor` value from the previous response, passed back unchanged; omit for the first page."}]}},"/v1/requests/{id}":{"get":{"operationId":"get_requests_by_id","summary":"Get one of requests","description":"Fetch one inbound request by id, including the full message and the recorded consent (SMS consent, transactional/promotional consent, terms accepted, and the exact consent wording shown). Returns `{ request: null }` if the id does not exist in this workspace. Funnel answer content, internal comments, IP address and user agent are never returned. Read-only. Find ids with requests_search.","tags":["requests"],"security":[{"bearerAuth":[]}],"x-tool":"requests_get","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"requests:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"request":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"number"},"source":{"type":"string"},"form_id":{"type":"string"},"message_preview":{"type":"string"},"converted_client_id":{"type":"string"},"assigned_to":{"type":"string"},"message":{"type":"string"},"source_url":{"type":"string"},"sms_consent":{"type":"boolean"},"sms_transactional_consent":{"type":"boolean"},"sms_promotional_consent":{"type":"boolean"},"terms_accepted":{"type":"boolean"},"consent_language":{"type":"string"},"funnel_id":{"type":"string"},"has_funnel_answers":{"type":"boolean"}},"required":["id","name","status","created_at","sms_consent","sms_transactional_consent","sms_promotional_consent","terms_accepted"],"additionalProperties":false,"nullable":true}},"required":["request"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]},"patch":{"operationId":"patch_requests_by_id","summary":"Update one of requests","description":"Mark an inbound request 'reviewed' or archive it. Archiving is terminal: there is no delete and no way back to 'new'. A converted request can be archived but not moved back to 'reviewed'. Converting is done by requests_convert_to_client. Returns `changed: false` if the request was already in the requested status. Sends nothing to the prospect; to reply use requests_respond.","tags":["requests"],"security":[{"bearerAuth":[]}],"x-tool":"requests_update_status","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"requests:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"request":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"previous_status":{"type":"string"}},"required":["id","status","previous_status"],"additionalProperties":false,"nullable":true},"changed":{"type":"boolean"}},"required":["request","changed"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["reviewed","archived"],"description":"reviewed, or archived (terminal)."}},"required":["status"]}}}}}},"/v1/calendar/events":{"get":{"operationId":"get_calendar_events","summary":"List calendar events","description":"List calendar events (schedules), paged (up to `limit`, default 25, max 100, plus `nextCursor`). `from` / `to` (ISO dates) filter by start time: a date-only value means the whole of that day in the workspace time zone (from = to = one date lists that day); a value with a time is an exact instant. All-day events (`is_all_day`) use UTC-midnight date markers: show the date, not a local clock time. `employee_id` keeps events assigned to that team member; `client_id` keeps one client's events. Cancelled events are excluded unless `include_cancelled` is true. Each row carries `is_cancelled`, `location`, `meeting_url`, `description`, `notes` and `is_recurring`; a Meet link that failed shows `meeting_link_status` / `meeting_link_error_code`. `google` is the caller's Google connection state. Scoped members see only their assigned clients' events plus team-wide ones; members restricted to assigned schedules see only events assigned to them.","tags":["calendar"],"security":[{"bearerAuth":[]}],"x-tool":"calendar_list_events","x-readOnly":true,"x-destructive":false,"x-requires-approval":false,"x-required-scope":"calendar:read","x-billing-class":"mcp_tool_read","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"client_id":{"type":"string"},"client_name":{"type":"string"},"status":{"type":"string"},"is_cancelled":{"type":"boolean"},"location":{"type":"string"},"meeting_url":{"type":"string"},"meeting_link_status":{"type":"string"},"meeting_link_error_code":{"type":"string"},"description":{"type":"string"},"notes":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"is_all_day":{"type":"boolean"},"is_recurring":{"type":"boolean"}},"required":["id"],"additionalProperties":false}},"nextCursor":{"type":"string"},"google":{"type":"string","enum":["connected","needs_reconnect","not_connected"]}},"required":["events"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","description":"Start of the range, ISO date; a date-only value means the whole day in the workspace time zone."},"description":"Start of the range, ISO date; a date-only value means the whole day in the workspace time zone."},{"name":"to","in":"query","required":false,"schema":{"type":"string","description":"End of the range, ISO date; a date-only value includes that whole day."},"description":"End of the range, ISO date; a date-only value includes that whole day."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (default 25, max 100)."},"description":"Results per page (default 25, max 100)."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"Cursor (`nextCursor`) from the previous page."},"description":"Cursor (`nextCursor`) from the previous page."},{"name":"employee_id","in":"query","required":false,"schema":{"type":"string","description":"Only events assigned to this team member (team_members_list)."},"description":"Only events assigned to this team member (team_members_list)."},{"name":"client_id","in":"query","required":false,"schema":{"type":"string","description":"Only this client's events."},"description":"Only this client's events."},{"name":"include_cancelled","in":"query","required":false,"schema":{"type":"boolean","description":"Include cancelled events (excluded by default)."},"description":"Include cancelled events (excluded by default)."}]},"post":{"operationId":"post_calendar_events","summary":"Create a calendar event","description":"Create a calendar event (schedule). Needs `title` and `starts_at` (ISO date). `ends_at` defaults to one hour after `starts_at` and must be after it. For all-day events set `is_all_day: true`, pass YYYY-MM-DD dates (no timezone conversion) and `time_zone`; the default all-day end is the following date and explicit ends are exclusive (September 11 alone ends September 12). With a `client_id` the event inherits that client's visibility; a client-less event is visible to the whole team. `category` must be an existing name from calendar_categories_list. `reminders` are alarm metadata on the event (5_minutes_before, 15_minutes_before, 30_minutes_before, 1_hour_before, 2_hours_before, 1_day_before); they do not prove a notification was scheduled. `recurrence` is daily, weekly, biweekly or monthly, with `recurrence_count` or `recurrence_end_date`. `assigned_user_ids` are ids from team_members_list (omitted: assigned to the caller; `[]`: unassigned). `services` (name + quantity) returns a catalog-priced estimate in the response (`services_preview`, `estimate_total`); nothing is stored on the event. A repeat call with the same `idempotency_key` returns the first event (`deduped: true`).","tags":["calendar"],"security":[{"bearerAuth":[]}],"x-tool":"calendar_create_event","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"calendar:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"client_id":{"type":"string"},"is_all_day":{"type":"boolean"},"time_zone":{"type":"string"}},"required":["id"],"additionalProperties":false},"deduped":{"type":"boolean"}},"required":["event","deduped"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"Event title."},"is_all_day":{"type":"boolean","description":"true for an all-day event; use YYYY-MM-DD dates."},"time_zone":{"type":"string","description":"IANA time zone for the event."},"starts_at":{"type":"string","minLength":1,"description":"Start, ISO date."},"ends_at":{"type":"string","description":"End, ISO date; defaults to one hour after the start. All-day ends are exclusive."},"client_id":{"type":"string","description":"Client the event is for; it inherits that client's visibility."},"description":{"type":"string","description":"Event description."},"category":{"type":"string","description":"An existing category name (calendar_categories_list)."},"reminders":{"type":"array","items":{"type":"string","enum":["5_minutes_before","15_minutes_before","30_minutes_before","1_hour_before","2_hours_before","1_day_before"]},"description":"Alarm metadata on the event; does not prove a notification was scheduled."},"recurrence":{"type":"string","enum":["none","daily","weekly","biweekly","monthly"],"description":"Repeat pattern; use with `recurrence_count` or `recurrence_end_date`."},"recurrence_count":{"type":"integer","minimum":1,"maximum":52,"description":"Number of occurrences."},"recurrence_end_date":{"type":"string","description":"Last date of the series, ISO date."},"assigned_user_ids":{"type":"array","items":{"type":"string"},"description":"Team member ids (team_members_list); omitted assigns the caller, [] leaves it unassigned."},"services":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Service name, looked up in the catalog."},"quantity":{"type":"number","exclusiveMinimum":true,"minimum":0,"description":"Number of units; default 1."}},"required":["name"],"additionalProperties":false},"description":"Services (name + quantity) priced from the catalog; returned as a preview in the response and not stored on the event."},"idempotency_key":{"type":"string","minLength":0,"maxLength":200,"description":"Optional. Repeat a call with the same key to avoid doing it twice."}},"required":["title","starts_at"]}}}}}},"/v1/calendar/events/{id}":{"patch":{"operationId":"patch_calendar_events_by_id","summary":"Update a calendar event","description":"Edit or reschedule an existing calendar event by `event_id` (new events: calendar_create_event; bulk client moves: calendar_events_reschedule_batch). Only the fields passed change. `starts_at` / `ends_at` are ISO dates; `starts_at` alone moves the event and keeps its duration. All-day moves use date strings with exclusive ends; set `is_all_day` to convert. `notes` replaces the Notes block and `description` the description (\"\" clears either). `add_reminders` appends, skipping any reminder already set; `clear_reminders: true` removes them all. `status: \"cancelled\"` soft-cancels (record kept). A recurring event (`is_recurring`) needs `occurrence_scope: \"all_events\"`, which changes the whole series; other scopes are done in the Calendar screen. `recurrence` (none, daily, weekly, biweekly, monthly, with `recurrence_count` or `recurrence_end_date`) makes a one-off event repeat, re-patterns a series, or with `none` makes it one event; a pattern shorter than the event is refused, and a series on specific weekdays can only have its count changed. An event someone has open in the app is refused as being edited. Linked reminders fire for the first occurrence only on biweekly series.","tags":["calendar"],"security":[{"bearerAuth":[]}],"x-tool":"calendar_update_event","x-readOnly":false,"x-destructive":true,"x-requires-approval":false,"x-required-scope":"calendar:write","x-billing-class":"mcp_tool_write","responses":{"200":{"description":"The tool's structured output.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"}},"required":["id"],"additionalProperties":false},"changes":{"type":"array","items":{"type":"string"}}},"required":["changes"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"usage_exhausted: the workspace is out of Tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Scope or permission missing (details names the scope), the app is not approved, or plan_required: the API is on the Specialist plan and up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The record is not in a state this call can act on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The input does not match the tool's schema (details.issues lists each problem).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited. Retry-After says how many seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"is_all_day":{"type":"boolean","description":"Convert between a timed and an all-day event; supply starts_at with it."},"time_zone":{"type":"string","description":"IANA zone used for linked relative reminders."},"title":{"type":"string","minLength":1,"description":"New title."},"starts_at":{"type":"string","description":"New start, ISO date. Alone, it moves the event and keeps its duration."},"ends_at":{"type":"string","description":"New end, ISO date."},"notes":{"type":"string","description":"Replaces the event's Notes block; \"\" clears it."},"description":{"type":"string","description":"Replaces the description; \"\" clears it."},"add_reminders":{"type":"array","items":{"type":"string","enum":["5_minutes_before","15_minutes_before","30_minutes_before","1_hour_before","2_hours_before","1_day_before"]},"description":"Reminders to append to the existing ones."},"clear_reminders":{"type":"boolean","description":"true removes all reminders."},"occurrence_scope":{"type":"string","enum":["all_events"],"description":"Required when the event repeats. Only \"all_events\" (the whole series) is supported; single occurrences and series splits are done on the Calendar screen."},"status":{"type":"string","enum":["confirmed","tentative","cancelled"],"description":"cancelled is a soft cancel that keeps the record."},"recurrence":{"type":"string","enum":["none","daily","weekly","biweekly","monthly"],"description":"Repeat pattern; none turns a series into a single event. Use with `recurrence_count` or `recurrence_end_date`."},"recurrence_count":{"type":"integer","minimum":1,"maximum":52,"description":"Number of occurrences."},"recurrence_end_date":{"type":"string","description":"Last date of the series, ISO date."}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}}}}