{"openapi":"3.1.0","info":{"title":"API Reference","version":"1.0.0"},"paths":{"/projects":{"get":{"operationId":"projects_listProjects","summary":"List Projects","description":"Retrieve a paginated list of projects.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`, optionally widened to project-level line item edits via `include_line_item_updates`)\n- Phase entry/exit date filtering (`entered_phase_id`+`entered_after`/`entered_before`, `exited_phase_id`+`exited_after`/`exited_before`)\n- Sorting (`order_by`)\n- Field search (`title`, `address`, `primaryName`, `primaryPhone`, `primaryEmail`)\n- Full text search (`q`)\n- Phase detail (`include_phases=true`: `phaseInstances` plus the current phase's `startedAt`/`completedAt`, as returned by `GET /projects/{project_id}`; use a `page_size` of 25 or less)\n\nEach project includes `ownerId`, `salesRepId`, `projectManagerId` and a `projectManager` object (`null` when unset). `updatedBy` is only returned by `GET /projects/{project_id}`.\n\n**Note:** `updated_after`/`updated_before` also match projects whose custom property values changed within the window.\n\n**Note:** If a project has no `title` (empty or whitespace-only), the response returns the parent account's `title` instead. The stored value is not modified — this is a read-time fallback only. Title-based search (`title` query param, full-text `q`, or the `/projects/search` endpoint with `prop=title&op=contains`) also matches projects whose own title is null/empty when the parent account's title matches the search term.\n\n**Note:** `entered_phase_id`/`exited_phase_id` identify a phase *template* (shared across all projects on a workflow), not a specific phase instance. Use the `phaseTemplateId` from a `GET /projects/{project_id}` response to find the id for a given phase. When either filter is used, each row also includes a compact `phaseTimeline` (`phaseTemplateId`, `startedAt`, `completedAt`); use `GET /projects/{project_id}` for the full `phaseInstances` with names/positions/SLA.\n","tags":["projects"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsGetParametersUpdatedBefore"}},{"name":"include_line_item_updates","in":"query","description":"Requires `updated_after` and/or `updated_before` to also be passed — has no effect\non its own. When true, widens that window to also match projects whose\nproject-level line items (estimate/scope items) were added or edited in\nthe window, and adds a `lineItemsUpdatedAt` field to each returned project (the most\nrecent `updatedAt` among its own scope line items, `null` if none). Line items on\nquotes/invoices are excluded. Deletions and reorders are not detected. Ordering\nremains on the project's own updatedAt, so this flag is not a replacement for a\nfull change-feed. Default: false. Only applies to project list/search endpoints.\n","required":false,"schema":{"type":"boolean","default":false}},{"name":"entered_phase_id","in":"query","description":"Phase template ID to filter by phase-entry date. Required when `entered_after` or `entered_before` is provided. Given alone (no date bounds), matches records that ever entered this phase.\n","required":false,"schema":{"type":"integer"}},{"name":"entered_after","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"entered_before","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_phase_id","in":"query","description":"Phase template ID to filter by phase-exit date. Required when `exited_after` or `exited_before` is provided. Given alone (no date bounds), matches records that have exited this phase at any point.\n","required":false,"schema":{"type":"integer"}},{"name":"exited_after","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `exited_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_before","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `exited_phase_id`. On opportunities, combine with `exited_phase_id` set to a \"Closed - Won\"-style phase template to find deals that closed within a date range.\n","required":false,"schema":{"type":"string"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ProjectsGetParametersOrderBy","default":"asc"}},{"name":"include_virtual_properties","in":"query","description":"Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_phases","in":"query","description":"Also return `phaseInstances` (every phase with its `status`, `startedAt` and `completedAt`) and `phase.startedAt` / `phase.completedAt` for the current phase, in the same shape as the single-record GET. Defaults to false. Adds two relation reads per row, so use a `page_size` of 25 or less when it is on.","required":false,"schema":{"type":"boolean","default":false}},{"name":"q","in":"query","description":"Full text search query","required":false,"schema":{"type":"string"}},{"name":"title","in":"query","description":"Title search query","required":false,"schema":{"type":"string"}},{"name":"address","in":"query","description":"Address search query","required":false,"schema":{"type":"string"}},{"name":"primaryName","in":"query","description":"Contact name search query","required":false,"schema":{"type":"string"}},{"name":"primaryPhone","in":"query","description":"Contact phone search query","required":false,"schema":{"type":"string"}},{"name":"primaryEmail","in":"query","description":"Contact email search query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of projects","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProjectWithPhaseInstances"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"projects_createProject","summary":"Create Project","description":"Create a new project with required and optional fields.\n\nRequired fields:\n- `title`: Project title/name\n- `address`: An array containing a single string, which represents the full project location/address.\n\nOptional fields:\n- `trades`: Array of trade types\n- `accountId`: Link to existing account\n- `workflowId`: Link to workflow\n- `phaseId`: Link to phase\n- `primaryEmail`/`primaryPhone`: Contact information\n- `contacts`: Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts.\n- `custom`: Custom fields object\n\nNote: If primaryEmail or primaryPhone is provided, a contact will be automatically created or matched.\n","tags":["projects"],"parameters":[{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}},{"name":"match_by","in":"query","description":"Field to use for matching existing records","required":false,"schema":{"$ref":"#/components/schemas/ProjectsPostParametersMatchBy","default":"title"}},{"name":"match_found_strategy","in":"query","description":"Strategy to use when a match is found","required":false,"schema":{"$ref":"#/components/schemas/ProjectsPostParametersMatchFoundStrategy","default":"skip"}}],"responses":{"200":{"description":"Matching project found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/search":{"get":{"operationId":"projects_searchProjects","summary":"Search Projects","description":"Search projects using up to two filters (prop1/op1/value1 and optionally prop2/op2/value2), combined with `logic` (AND/OR).\n\nProperties:\n- `propX` can be a standard field (e.g., `status`, `title`, `city`, `type`, `accountId`, etc.) or a custom property key name.\n- Use the `property key` from your company settings.\n- Filter by parent account with `accountId`. `clientId` is accepted as a deprecated alias for backwards compatibility.\n\nOperators (`opX`):\n- Equality: `eq`, `neq`\n- Numeric/datetime comparisons: `gt`, `gte`, `lt`, `lte`\n- Text/string matching: `contains` (case-insensitive)\n- Lists: `in`, `nin` (CSV list in `valueX`)\n- Ranges: `between` (use `valueX` as `from,to`)\n- Existence: `exists` is not supported for custom properties due to performance limitations. Use `eq` or `neq` instead.\n- `status` has a fixed set of values, so it supports only `eq`, `neq`, `in`, and `nin`.\n\nValue formats:\n- `in`/`nin`: lists can be provided as:\n  - Plain CSV: `value1=OPEN,ACTIVE`\n  - Quoted CSV (to include commas inside a value): `value1=\"Last, First\",Other`\n  - JSON array: `value1=[\"Last, First\",\"Other\"]`\n- `between`: `from,to` (e.g., `value1=2025-01-01,2025-12-31` or `value1=10,20`)\n- Dates should be ISO 8601 strings; numeric-like values on custom properties are matched against both numeric and text representations.\n\nExamples:\n- status equals ACTIVE: `?prop1=status&op1=eq&value1=ACTIVE`\n- custom id equals 1234: `?prop1=legacy_tool_project_id&op1=eq&value1=1234`\n- title contains \"Solar\": `?prop1=name&op1=contains&value1=Solar`\n- status IN (ACTIVE, ON_HOLD) AND city = Austin: `?prop1=status&op1=in&value1=ACTIVE,ON_HOLD&logic=and&prop2=city&op2=eq&value2=Austin`\n\n**Note:** If a project has no `title` (empty or whitespace-only), the response returns the parent account's `title` instead. The stored value is not modified — this is a read-time fallback only. Title-based search (`title` query param, full-text `q`, or the `/projects/search` endpoint with `prop=title&op=contains`) also matches projects whose own title is null/empty when the parent account's title matches the search term.\n\nSupports date filtering (`updated_after`, `updated_before`), optionally widened to project-level line item edits via `include_line_item_updates`. `updated_after`/`updated_before` also match projects whose custom property values changed within the window.\n\nPass `include_phases=true` to also return `phaseInstances` and the current phase's `startedAt`/`completedAt` (use a `page_size` of 25 or less).\n","tags":["projects"],"parameters":[{"name":"prop1","in":"query","description":"First field to filter (standard or custom keyName)","required":true,"schema":{"type":"string"}},{"name":"op1","in":"query","description":"Operator for prop1","required":true,"schema":{"$ref":"#/components/schemas/ProjectsSearchGetParametersOp1"}},{"name":"value1","in":"query","description":"Value for prop1 (comma-separated values for in/nin or between)","required":true,"schema":{"type":"string"}},{"name":"logic","in":"query","description":"Logical combination when both prop1 and prop2 are provided","required":false,"schema":{"$ref":"#/components/schemas/ProjectsSearchGetParametersLogic","default":"and"}},{"name":"prop2","in":"query","description":"Optional second field to filter","required":false,"schema":{"type":"string"}},{"name":"op2","in":"query","description":"Operator for prop2","required":false,"schema":{"$ref":"#/components/schemas/ProjectsSearchGetParametersOp2"}},{"name":"value2","in":"query","description":"Value for prop2 (comma-separated values for in/nin or between)","required":false,"schema":{"type":"string"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsSearchGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsSearchGetParametersUpdatedBefore"}},{"name":"include_line_item_updates","in":"query","description":"Requires `updated_after` and/or `updated_before` to also be passed — has no effect\non its own. When true, widens that window to also match projects whose\nproject-level line items (estimate/scope items) were added or edited in\nthe window, and adds a `lineItemsUpdatedAt` field to each returned project (the most\nrecent `updatedAt` among its own scope line items, `null` if none). Line items on\nquotes/invoices are excluded. Deletions and reorders are not detected. Ordering\nremains on the project's own updatedAt, so this flag is not a replacement for a\nfull change-feed. Default: false. Only applies to project list/search endpoints.\n","required":false,"schema":{"type":"boolean","default":false}},{"name":"entered_phase_id","in":"query","description":"Phase template ID to filter by phase-entry date. Required when `entered_after` or `entered_before` is provided. Given alone (no date bounds), matches records that ever entered this phase.\n","required":false,"schema":{"type":"integer"}},{"name":"entered_after","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"entered_before","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_phase_id","in":"query","description":"Phase template ID to filter by phase-exit date. Required when `exited_after` or `exited_before` is provided. Given alone (no date bounds), matches records that have exited this phase at any point.\n","required":false,"schema":{"type":"integer"}},{"name":"exited_after","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `exited_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_before","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `exited_phase_id`. On opportunities, combine with `exited_phase_id` set to a \"Closed - Won\"-style phase template to find deals that closed within a date range.\n","required":false,"schema":{"type":"string"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ProjectsSearchGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_phases","in":"query","description":"Also return `phaseInstances` (every phase with its `status`, `startedAt` and `completedAt`) and `phase.startedAt` / `phase.completedAt` for the current phase, in the same shape as the single-record GET. Defaults to false. Adds two relation reads per row, so use a `page_size` of 25 or less when it is on.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of projects matching filters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProjectWithPhaseInstances"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchProjectsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchProjectsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}":{"get":{"operationId":"projects_getProject","summary":"Get Project","description":"Retrieve a specific project by ID.\n\n**Note:** If the project has no `title` (empty or whitespace-only), the response returns the parent account's `title` instead. The stored value is not modified — this is a read-time fallback only.\n","tags":["projects"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"include_virtual_properties","in":"query","description":"Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Project details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectWithPhaseInstances"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"projects_updateProject","summary":"Update Project","description":"Update an existing project. Supports partial updates.\n\nUpdatable fields:\n- Standard fields (value, size, status, etc.)\n- Workflow fields (workflowId, phaseId)\n- Contact information (primaryEmail, primaryPhone)\n- Contacts (contact IDs only, no name, email, phone, etc.)\n- Custom fields (through custom object)\n\nNote: Updates are atomic - either all fields update or none do.\n\n> **Changing account association is not supported via update.** To move a project to a different account, delete and re-create it under the new account.\n","tags":["projects"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Project updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"projects_deleteProject","summary":"Delete Project","description":"Delete a specific project by ID","tags":["projects"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Project deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProjectRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProjectRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities":{"get":{"operationId":"opportunities_listOpportunities","summary":"List Opportunities","description":"Retrieve a paginated list of opportunities.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Phase entry/exit date filtering (`entered_phase_id`+`entered_after`/`entered_before`, `exited_phase_id`+`exited_after`/`exited_before`)\n- Sorting (`order_by`, default: desc)\n- Field search (`title`, `address`, `primaryName`, `primaryPhone`, `primaryEmail`)\n- Full text search (`q`)\n- Phase detail (`include_phases=true`: `phaseInstances` plus the current phase's `startedAt`/`completedAt`; use a `page_size` of 25 or less)\n\nEach opportunity includes `ownerId`, `salesRepId`, `projectManagerId` and a `projectManager` object (`null` when unset). `updatedBy` is only returned by `GET /opportunities/{opportunity_id}`.\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n\n**Note:** If an opportunity has no `title` (empty or whitespace-only), the response returns the parent account's `title` instead. The stored value is not modified — this is a read-time fallback only.\n\n**Note:** `entered_phase_id`/`exited_phase_id` identify a phase *template* (shared across all deals on a workflow), not a specific phase instance. Use the `phaseTemplateId` from a `GET /opportunities/{opportunity_id}` response or the `GET /workflows` response to find the id for a given phase (e.g. \"Closed - Won\"). When either filter is used, each row also includes a compact `phaseTimeline` (`phaseTemplateId`, `startedAt`, `completedAt`); use `GET /opportunities/{opportunity_id}` for the full `phaseInstances` with names/positions/SLA.\n","tags":["opportunities"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesGetParametersUpdatedBefore"}},{"name":"entered_phase_id","in":"query","description":"Phase template ID to filter by phase-entry date. Required when `entered_after` or `entered_before` is provided. Given alone (no date bounds), matches records that ever entered this phase.\n","required":false,"schema":{"type":"integer"}},{"name":"entered_after","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"entered_before","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_phase_id","in":"query","description":"Phase template ID to filter by phase-exit date. Required when `exited_after` or `exited_before` is provided. Given alone (no date bounds), matches records that have exited this phase at any point.\n","required":false,"schema":{"type":"integer"}},{"name":"exited_after","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `exited_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_before","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `exited_phase_id`. On opportunities, combine with `exited_phase_id` set to a \"Closed - Won\"-style phase template to find deals that closed within a date range.\n","required":false,"schema":{"type":"string"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesGetParametersOrderBy","default":"asc"}},{"name":"include_virtual_properties","in":"query","description":"Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_phases","in":"query","description":"Also return `phaseInstances` (every phase with its `status`, `startedAt` and `completedAt`) and `phase.startedAt` / `phase.completedAt` for the current phase, in the same shape as the single-record GET. Defaults to false. Adds two relation reads per row, so use a `page_size` of 25 or less when it is on.","required":false,"schema":{"type":"boolean","default":false}},{"name":"q","in":"query","description":"Full text search query","required":false,"schema":{"type":"string"}},{"name":"title","in":"query","description":"Title search query","required":false,"schema":{"type":"string"}},{"name":"address","in":"query","description":"Address search query","required":false,"schema":{"type":"string"}},{"name":"primaryName","in":"query","description":"Contact name search query","required":false,"schema":{"type":"string"}},{"name":"primaryPhone","in":"query","description":"Contact phone search query","required":false,"schema":{"type":"string"}},{"name":"primaryEmail","in":"query","description":"Contact email search query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of opportunities","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityWithPhaseInstances"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOpportunitiesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOpportunitiesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"opportunities_createOpportunity","summary":"Create Opportunity","description":"Create a new opportunity with required and optional fields.\n\nRequired fields:\n- `title`: Opportunity title/name\n- `address`: Opportunity location\n- `trades`: Array of trade types\n\nOptional fields:\n- `accountId`: Link to existing account\n- `workflowId`: Link to workflow\n- `phaseId`: Link to phase\n- `value`: Opportunity value\n- `size`: Opportunity size\n- `confidence`: Confidence score (0-100)\n- `primaryEmail`/`primaryPhone`: Contact information\n- `contacts`: Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts.\n- `custom`: Custom fields object\n\nNote: If primaryEmail or primaryPhone is provided, a contact will be automatically created or matched.\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["opportunities"],"parameters":[{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}},{"name":"match_by","in":"query","description":"Field to use for matching existing records","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesPostParametersMatchBy","default":"title"}},{"name":"match_found_strategy","in":"query","description":"Strategy to use when a match is found","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesPostParametersMatchFoundStrategy","default":"skip"}}],"responses":{"200":{"description":"Matching opportunity found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Opportunity"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityUpsert"}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/search":{"get":{"operationId":"opportunities_searchOpportunities","summary":"Search Opportunities","description":"Search opportunities using up to two filters (prop1/op1/value1 and optionally prop2/op2/value2), combined with `logic` (AND/OR).\n\nProperties:\n- `propX` can be a standard field (e.g., `status`, `title`, `city`, `type`, `accountId`, etc.) or a custom property key name.\n- Use the `property key` from your company settings.\n- Filter by parent account with `accountId`. `clientId` is accepted as a deprecated alias for backwards compatibility.\n\nOperators (`opX`):\n- Equality: `eq`, `neq`\n- Numeric/datetime comparisons: `gt`, `gte`, `lt`, `lte`\n- Text/string matching: `contains` (case-insensitive)\n- Lists: `in`, `nin` (CSV list in `valueX`)\n- Ranges: `between` (use `valueX` as `from,to`)\n- Existence: `exists` is not supported for custom properties due to performance limitations. Use `eq` or `neq` instead.\n- `status` has a fixed set of values, so it supports only `eq`, `neq`, `in`, and `nin`.\n\nValue formats:\n- `in`/`nin`: lists can be provided as:\n  - Plain CSV: `value1=OPEN,ACTIVE`\n  - Quoted CSV (to include commas inside a value): `value1=\"Last, First\",Other`\n  - JSON array: `value1=[\"Last, First\",\"Other\"]`\n- `between`: `from,to` (e.g., `value1=2025-01-01,2025-12-31` or `value1=10,20`)\n- Dates should be ISO 8601 strings; numeric-like values on custom properties are matched against both numeric and text representations.\n\nExamples:\n- status equals ACTIVE: `?prop1=status&op1=eq&value1=ACTIVE`\n- won or lost: `?prop1=status&op1=in&value1=WON,LOST` (opportunity status is `ACTIVE`, `ON_HOLD`, `WON`, or `LOST`)\n- custom id equals 1234: `?prop1=legacy_tool_project_id&op1=eq&value1=1234`\n- title contains \"Solar\": `?prop1=name&op1=contains&value1=Solar`\n- status IN (ACTIVE, ON_HOLD) AND city = Austin: `?prop1=status&op1=in&value1=ACTIVE,ON_HOLD&logic=and&prop2=city&op2=eq&value2=Austin`\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n\n**Note:** If an opportunity has no `title` (empty or whitespace-only), the response returns the parent account's `title` instead. The stored value is not modified — this is a read-time fallback only.\n","tags":["opportunities"],"parameters":[{"name":"prop1","in":"query","description":"First field to filter (standard or custom keyName)","required":true,"schema":{"type":"string"}},{"name":"op1","in":"query","description":"Operator for prop1","required":true,"schema":{"$ref":"#/components/schemas/OpportunitiesSearchGetParametersOp1"}},{"name":"value1","in":"query","description":"Value for prop1 (comma-separated values for in/nin or between)","required":true,"schema":{"type":"string"}},{"name":"logic","in":"query","description":"Logical combination when both prop1 and prop2 are provided","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesSearchGetParametersLogic","default":"and"}},{"name":"prop2","in":"query","description":"Optional second field to filter","required":false,"schema":{"type":"string"}},{"name":"op2","in":"query","description":"Operator for prop2","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesSearchGetParametersOp2"}},{"name":"value2","in":"query","description":"Value for prop2 (comma-separated values for in/nin or between)","required":false,"schema":{"type":"string"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"entered_phase_id","in":"query","description":"Phase template ID to filter by phase-entry date. Required when `entered_after` or `entered_before` is provided. Given alone (no date bounds), matches records that ever entered this phase.\n","required":false,"schema":{"type":"integer"}},{"name":"entered_after","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"entered_before","in":"query","description":"Only include records that entered the phase given by `entered_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `entered_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_phase_id","in":"query","description":"Phase template ID to filter by phase-exit date. Required when `exited_after` or `exited_before` is provided. Given alone (no date bounds), matches records that have exited this phase at any point.\n","required":false,"schema":{"type":"integer"}},{"name":"exited_after","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` on or after this date/timestamp. Accepts a date (`2026-07-01`) or a full ISO 8601 timestamp (`2026-07-01T00:00:00Z`). Requires `exited_phase_id`.\n","required":false,"schema":{"type":"string"}},{"name":"exited_before","in":"query","description":"Only include records that exited the phase given by `exited_phase_id` before this date/timestamp (exclusive). Accepts a date (`2026-08-01`) or a full ISO 8601 timestamp (`2026-08-01T00:00:00Z`). Requires `exited_phase_id`. On opportunities, combine with `exited_phase_id` set to a \"Closed - Won\"-style phase template to find deals that closed within a date range.\n","required":false,"schema":{"type":"string"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesSearchGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_phases","in":"query","description":"Also return `phaseInstances` (every phase with its `status`, `startedAt` and `completedAt`) and `phase.startedAt` / `phase.completedAt` for the current phase, in the same shape as the single-record GET. Defaults to false. Adds two relation reads per row, so use a `page_size` of 25 or less when it is on.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of opportunities matching filters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityWithPhaseInstances"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchOpportunitiesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchOpportunitiesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}":{"get":{"operationId":"opportunities_getOpportunity","summary":"Get Opportunity","description":"Retrieve a specific opportunity by ID\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n\n**Note:** If the opportunity has no `title` (empty or whitespace-only), the response returns the parent account's `title` instead. The stored value is not modified — this is a read-time fallback only.\n","tags":["opportunities"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"include_virtual_properties","in":"query","description":"Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Opportunity details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityWithPhaseInstances"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"opportunities_updateOpportunity","summary":"Update Opportunity","description":"Update an existing opportunity. Supports partial updates.\n\nUpdatable fields:\n- Standard fields (value, size, status, confidence, etc.)\n- Workflow fields (workflowId, phaseId)\n- Contact information (primaryEmail, primaryPhone)\n- Contacts (contact IDs only, no name, email, phone, etc.)\n- Custom fields (through custom object)\n\nNote: Updates are atomic - either all fields update or none do.\n\n> **Changing account association is not supported via update.** To move an opportunity to a different account, delete and re-create it under the new account.\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["opportunities"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Opportunity updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Opportunity"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpportunityRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpportunityRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpportunityRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityUpsert"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"opportunities_deleteOpportunity","summary":"Delete Opportunity","description":"Delete a specific opportunity by ID\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["opportunities"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Opportunity deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteOpportunityRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteOpportunityRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts":{"get":{"operationId":"accounts_listAccounts","summary":"List Accounts","description":"Retrieve a paginated list of accounts.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`, default: desc)\n- Field search (`title`, `address`, `primaryName`, `primaryPhone`, `primaryEmail`)\n- Full text search (`q`)\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["accounts"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/AccountsGetParametersOrderBy","default":"asc"}},{"name":"include_virtual_properties","in":"query","description":"Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"q","in":"query","description":"Full text search query","required":false,"schema":{"type":"string"}},{"name":"title","in":"query","description":"Title search query","required":false,"schema":{"type":"string"}},{"name":"address","in":"query","description":"Address search query","required":false,"schema":{"type":"string"}},{"name":"primaryName","in":"query","description":"Contact name search query","required":false,"schema":{"type":"string"}},{"name":"primaryPhone","in":"query","description":"Contact phone search query","required":false,"schema":{"type":"string"}},{"name":"primaryEmail","in":"query","description":"Contact email search query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of accounts","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Account"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAccountsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"accounts_createAccount","summary":"Create Account","description":"Create a new account with required and optional fields.\n\nRequired fields:\n- `title`: Account name\n- `address`: Account location\n\nOptional fields:\n- `accountType`: Account type (RESIDENTIAL/COMMERCIAL)\n- `value`: Account value\n- `size`: Account size\n- `primaryEmail`/`primaryPhone`: Contact information\n- `contacts`: Contact IDs only (no name, email, phone, etc.). **The contacts must be created first via POST /contacts.**\n- `custom`: Custom fields object\n\nNote: If primaryEmail or primaryPhone is provided and no contacts are provided, a contact will be automatically created or matched.\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["accounts"],"parameters":[{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}},{"name":"match_by","in":"query","description":"Field to use for matching existing records","required":false,"schema":{"$ref":"#/components/schemas/AccountsPostParametersMatchBy","default":"title"}},{"name":"match_found_strategy","in":"query","description":"Strategy to use when a match is found","required":false,"schema":{"$ref":"#/components/schemas/AccountsPostParametersMatchFoundStrategy","default":"skip"}}],"responses":{"200":{"description":"Matching account found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUpsert"}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/search":{"get":{"operationId":"accounts_searchAccounts","summary":"Search Accounts","description":"Search accounts using up to two filters (prop1/op1/value1 and optionally prop2/op2/value2), combined with `logic` (AND/OR).\n\nProperties:\n- `propX` can be a standard field (e.g., `status`, `title`, `city`, `type`, `accountId`, etc.) or a custom property key name.\n- Use the `property key` from your company settings.\n- Filter by parent account with `accountId`. `clientId` is accepted as a deprecated alias for backwards compatibility.\n\nOperators (`opX`):\n- Equality: `eq`, `neq`\n- Numeric/datetime comparisons: `gt`, `gte`, `lt`, `lte`\n- Text/string matching: `contains` (case-insensitive)\n- Lists: `in`, `nin` (CSV list in `valueX`)\n- Ranges: `between` (use `valueX` as `from,to`)\n- Existence: `exists` is not supported for custom properties due to performance limitations. Use `eq` or `neq` instead.\n\nValue formats:\n- `in`/`nin`: lists can be provided as:\n  - Plain CSV: `value1=OPEN,ACTIVE`\n  - Quoted CSV (to include commas inside a value): `value1=\"Last, First\",Other`\n  - JSON array: `value1=[\"Last, First\",\"Other\"]`\n- `between`: `from,to` (e.g., `value1=2025-01-01,2025-12-31` or `value1=10,20`)\n- Dates should be ISO 8601 strings; numeric-like values on custom properties are matched against both numeric and text representations.\n\nExamples:\n- status equals ACTIVE: `?prop1=status&op1=eq&value1=ACTIVE`\n- custom id equals 1234: `?prop1=legacy_tool_project_id&op1=eq&value1=1234`\n- title contains \"Solar\": `?prop1=name&op1=contains&value1=Solar`\n- status IN (ACTIVE, ON_HOLD) AND city = Austin: `?prop1=status&op1=in&value1=ACTIVE,ON_HOLD&logic=and&prop2=city&op2=eq&value2=Austin`\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["accounts"],"parameters":[{"name":"prop1","in":"query","description":"First field to filter (standard or custom keyName)","required":true,"schema":{"type":"string"}},{"name":"op1","in":"query","description":"Operator for prop1","required":true,"schema":{"$ref":"#/components/schemas/AccountsSearchGetParametersOp1"}},{"name":"value1","in":"query","description":"Value for prop1 (comma-separated values for in/nin or between)","required":true,"schema":{"type":"string"}},{"name":"logic","in":"query","description":"Logical combination when both prop1 and prop2 are provided","required":false,"schema":{"$ref":"#/components/schemas/AccountsSearchGetParametersLogic","default":"and"}},{"name":"prop2","in":"query","description":"Optional second field to filter","required":false,"schema":{"type":"string"}},{"name":"op2","in":"query","description":"Operator for prop2","required":false,"schema":{"$ref":"#/components/schemas/AccountsSearchGetParametersOp2"}},{"name":"value2","in":"query","description":"Value for prop2 (comma-separated values for in/nin or between)","required":false,"schema":{"type":"string"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/AccountsSearchGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of accounts matching filters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Account"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAccountsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAccountsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}":{"get":{"operationId":"accounts_getAccount","summary":"Get Account","description":"Retrieve a specific account by ID\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["accounts"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"include_virtual_properties","in":"query","description":"Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Account details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"accounts_updateAccount","summary":"Update Account","description":"Update an existing account. Supports partial updates.\n\nUpdatable fields:\n- Standard fields (title, description, address, accountType, isActive)\n- Contact information (primaryEmail, primaryPhone)\n- `contacts`: Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts.\n- Custom fields (through custom object)\n\nNote: Updates are atomic - either all fields update or none do.\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["accounts"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Account updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"accounts_deleteAccount","summary":"Delete Account","description":"Delete a specific account by ID\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["accounts"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Account deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/sites":{"get":{"operationId":"sites_listSites","summary":"List Sites","description":"Retrieve a paginated list of sites. Results can be filtered by account, state, city, or zipcode.\n","tags":["sites"],"parameters":[{"name":"accountId","in":"query","description":"Filter by account ID.","required":false,"schema":{"type":"integer"}},{"name":"state","in":"query","description":"Filter by state, case-insensitive (e.g. `ca` or `CA`).","required":false,"schema":{"type":"string"}},{"name":"city","in":"query","description":"Filter by city, case-insensitive substring match (e.g. `francisco` matches `San Francisco`).","required":false,"schema":{"type":"string"}},{"name":"zipcode","in":"query","description":"Filter by zip code, case-insensitive.","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"List of sites","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Site"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSitesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSitesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"sites_createSite","summary":"Create Site","description":"Create a new site record belonging to an account.\n\nRequired fields:\n- `accountId`: The account this site belongs to.\n- `fullAddress` or `geoLocation`: At least one must be provided. The backend geocodes `fullAddress` to derive coordinates.\n\nIf a site with the same address already exists for the same account, the existing site is returned instead of creating a duplicate (`200` instead of `201`).\n","tags":["sites"],"responses":{"200":{"description":"Duplicate site found — existing site returned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSiteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSiteRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/sites/{site_id}":{"get":{"operationId":"sites_getSite","summary":"Get Site","description":"Retrieve a specific site by ID. Returns 404 if not found or if the site belongs to a different company.","tags":["sites"],"parameters":[{"name":"site_id","in":"path","description":"Site identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Site details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSiteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSiteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSiteRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"sites_updateSite","summary":"Update Site","description":"Update an existing site. All fields are optional — only provided fields are changed.\n\n> **Moving a site to a different account:** Use `POST /sites/{site_id}/move` instead. `accountId` cannot be changed on a site update.\n\n> **Note on `geoLocation` and `fullAddress`:** Sending either field on update triggers geocoding — the backend may overwrite the stored coordinates with what Google Maps snaps to for the nearest address, so the values you send may not be stored as-is. There is currently no way to update coordinates without allowing the geocoder to potentially adjust them.\n","tags":["sites"],"parameters":[{"name":"site_id","in":"path","description":"Site identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Site updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSiteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSiteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSiteRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"sites_deleteSite","summary":"Delete Site","description":"Delete a specific site by ID. Returns 404 if not found.","tags":["sites"],"parameters":[{"name":"site_id","in":"path","description":"Site identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Site deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteSiteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteSiteRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/sites/{site_id}/move":{"post":{"operationId":"sites_moveSite","summary":"Move Site to Another Account","description":"Move a site and all its associated records to a different account.\n\n**A new site is created with a new ID.** The original site (`siteId` in the path) is permanently\ndeleted. The response contains the new site object — update any stored site IDs accordingly.\n\nThe `fullAddress` and `title` are copied from the original site to the new one. The backend geocodes the address on the new site, so all address components (street, city, state, zipcode) are derived from geocoding.\n\n**Migrated records:** opportunities, projects, work orders, forms, services, systems, assets, and financial documents.\n\n> ⚠️ **This operation is irreversible.** The original site and its ID are permanently deleted.\n> Any references to the old `siteId` will no longer resolve.\n> Service plan instance links are removed — plans are account-scoped and cannot be transferred.\n","tags":["sites"],"parameters":[{"name":"site_id","in":"path","description":"Site identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"The newly created site on the target account. This site has a new `id` — the original site has been deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveSiteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveSiteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveSiteRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"integer","description":"The target account ID to move the site to."}},"required":["accountId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/assets":{"get":{"operationId":"assets_listAssets","summary":"List Assets","description":"List assets for the authenticated company. Supports pagination and filters (`account_id`, `site_id`, `status`, `type`, `manufacturer`, `is_archived`, date range on `updated_at`).\n","tags":["assets"],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"order_by","in":"query","required":false,"schema":{"$ref":"#/components/schemas/AssetsGetParametersOrderBy","default":"desc"}},{"name":"account_id","in":"query","description":"Filter to assets belonging to a specific account.","required":false,"schema":{"type":"integer"}},{"name":"site_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/AssetStatus"}},{"name":"type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/AssetType"}},{"name":"manufacturer","in":"query","description":"Case-insensitive substring match on `manufacturer`.","required":false,"schema":{"type":"string"}},{"name":"is_archived","in":"query","description":"Filter by archive state. Accepts `true` / `false` / `1` / `0`.","required":false,"schema":{"$ref":"#/components/schemas/AssetsGetParametersIsArchived","default":"false"}},{"name":"updated_after","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updated_before","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"List of assets","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAssetsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAssetsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"assets_createAsset","summary":"Create Asset","description":"Create a new asset. Requires `accountId`, `siteId`, `type`, `manufacturer`, `model`, and `serialNumber`.","tags":["assets"],"responses":{"201":{"description":"Asset created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssetRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssetRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/assets/{asset_id}":{"get":{"operationId":"assets_getAsset","summary":"Get Asset","description":"Retrieve a specific asset by ID.","tags":["assets"],"parameters":[{"name":"asset_id","in":"path","description":"Asset identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Asset details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAssetRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAssetRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"assets_updateAsset","summary":"Update Asset","description":"Update an existing asset. All fields are optional — only include what you want to change.\n\n`siteId` and `accountId` cannot be changed after creation. Including either field in the request body is rejected with a `400 Bad Request` validation error.\n\nTo archive an asset, set `isArchived: true`. To unarchive, set `isArchived: false`.\n","tags":["assets"],"parameters":[{"name":"asset_id","in":"path","description":"Asset identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Asset updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAssetRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAssetRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAssetRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetUpdate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/vendors":{"get":{"operationId":"vendors_listVendors","summary":"List Vendors","description":"Retrieve a paginated list of vendors.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`, default: desc)\n- Vendor type filter (`vendor_type`)\n","tags":["vendors"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/VendorsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/VendorsGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/VendorsGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}},{"name":"vendor_type","in":"query","description":"Filter by vendor type","required":false,"schema":{"$ref":"#/components/schemas/VendorsGetParametersVendorType"}}],"responses":{"200":{"description":"List of vendors","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Vendor"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListVendorsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"vendors_createVendor","summary":"Create Vendor","description":"Create a new vendor.\n\nRequired fields:\n- `name`: Vendor name\n- `vendorType`: One of `CONSULTANT`, `FINANCING`, `LOGISTICS`, `MANUFACTURER`, `SUBCONTRACTOR`, `SUPPLIER`\n\nOptional fields:\n- `address`: Array containing a single string for the full vendor location/address\n- `website`: Vendor website URL (max 2048 chars)\n- `description`: Vendor description\n- `isActive`: Whether the vendor is active (default: true)\n- `contacts`: Array of contact IDs to associate\n- `projectIds`: Array of project IDs to link this vendor to\n- `custom`: Custom fields object\n","tags":["vendors"],"parameters":[{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Matching vendor found (upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vendor"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/vendors/search":{"get":{"operationId":"vendors_searchVendors","summary":"Search Vendors","description":"Search vendors using up to two filters (prop1/op1/value1 and optionally prop2/op2/value2), combined with `logic` (AND/OR).\n\nProperties:\n- `propX` can be a standard field (e.g., `name`, `website`, `vendorType`) or a custom property key name.\n\nOperators (`opX`):\n- Equality: `eq`, `neq`\n- Text/string matching: `contains` (case-insensitive)\n- Lists: `in`, `nin` (CSV list in `valueX`)\n","tags":["vendors"],"parameters":[{"name":"prop1","in":"query","description":"First field to filter (e.g. `name`, `vendorType`, `website` or custom keyName)","required":true,"schema":{"type":"string"}},{"name":"op1","in":"query","description":"Operator for prop1","required":true,"schema":{"$ref":"#/components/schemas/VendorsSearchGetParametersOp1"}},{"name":"value1","in":"query","description":"Value for prop1 (comma-separated values for in/nin or between)","required":true,"schema":{"type":"string"}},{"name":"logic","in":"query","description":"Logical combination when both prop1 and prop2 are provided","required":false,"schema":{"$ref":"#/components/schemas/VendorsSearchGetParametersLogic","default":"and"}},{"name":"prop2","in":"query","description":"Optional second field to filter","required":false,"schema":{"type":"string"}},{"name":"op2","in":"query","description":"Operator for prop2","required":false,"schema":{"$ref":"#/components/schemas/VendorsSearchGetParametersOp2"}},{"name":"value2","in":"query","description":"Value for prop2 (comma-separated values for in/nin or between)","required":false,"schema":{"type":"string"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Matching vendors","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Vendor"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchVendorsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchVendorsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/vendors/{vendor_id}":{"get":{"operationId":"vendors_getVendor","summary":"Get Vendor","description":"Retrieve a specific vendor by ID.","tags":["vendors"],"parameters":[{"name":"vendor_id","in":"path","description":"The vendor ID","required":true,"schema":{"type":"integer"}},{"name":"include_contacts","in":"query","description":"Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Vendor details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vendor"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVendorRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVendorRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"vendors_updateVendor","summary":"Update Vendor","description":"Update an existing vendor. All fields are optional — only include what you want to change.\n\nPass `null` to clear a nullable field (e.g. `website`, `description`).\n","tags":["vendors"],"parameters":[{"name":"vendor_id","in":"path","description":"The vendor ID","required":true,"schema":{"type":"integer"}},{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Vendor updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vendor"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVendorRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVendorRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVendorRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"vendors_deleteVendor","summary":"Delete Vendor","description":"Permanently delete a vendor by ID.","tags":["vendors"],"parameters":[{"name":"vendor_id","in":"path","description":"The vendor ID","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Vendor deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteVendorRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteVendorRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/vendors/{vendor_id}":{"post":{"operationId":"vendors_createVendorProjectLink","summary":"Create Vendor-Project Link","description":"Associate a vendor with a project (many-to-many relationship).\n\nA vendor can be linked to multiple projects and a project can have multiple vendors.\n","tags":["vendors"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"vendor_id","in":"path","description":"The vendor ID","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Vendor linked successfully to project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vendors_createVendorProjectLink_Response_200"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorProjectLinkRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorProjectLinkRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"vendors_deleteVendorProjectLink","summary":"Delete Vendor-Project Link","description":"Remove the association between a vendor and a project.","tags":["vendors"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"vendor_id","in":"path","description":"The vendor ID","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Vendor-Project link deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vendors_deleteVendorProjectLink_Response_200"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteVendorProjectLinkRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteVendorProjectLinkRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/ahjs":{"get":{"operationId":"ahJs_list-ahjs","summary":"List AHJs","description":"Retrieve a paginated list of Authorities Having Jurisdiction (AHJs).\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Sorting by name (`order_by`, default: asc)\n- Search by name or state code (`q`) — when `q` is exactly two characters it also matches the two-letter state code\n- Filter by `state` (two-letter code), `type`, and `country` (default: `US`)\n- Geo mode: pass `lat`+`lng` (together) to return every AHJ whose boundary covers the point — e.g. city, county, and state — ordered most-specific-first. Name/state/type filters are ignored, and an empty array is returned if none cover the point.\n\nOnly active jurisdictions are returned. AHJs are seeded globally from the US Census TIGER catalog plus per-company private records. Most fields are read-only; only custom fields can be updated (see PATCH /ahjs/{ahj_id}).\n","tags":["AHJs"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"q","in":"query","description":"Search by AHJ name (case-insensitive). If exactly two characters, also matches the state code.","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","description":"Filter by two-letter state code (e.g. \"CA\").","required":false,"schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"type","in":"query","description":"Filter by jurisdiction type.","required":false,"schema":{"$ref":"#/components/schemas/AhjsGetParametersType"}},{"name":"country","in":"query","description":"Filter by country code.","required":false,"schema":{"type":"string","default":"US"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/AhjsGetParametersOrderBy","default":"asc"}},{"name":"lat","in":"query","description":"Latitude in decimal degrees. Must be used together with `lng`.","required":false,"schema":{"type":"number","format":"double","minimum":-90,"maximum":90}},{"name":"lng","in":"query","description":"Longitude in decimal degrees. Must be used together with `lat`.","required":false,"schema":{"type":"number","format":"double","minimum":-180,"maximum":180}}],"responses":{"200":{"description":"List of AHJs","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AHJ"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-ahjsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-ahjsRequestUnauthorizedError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-ahjsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/ahjs/{ahj_id}":{"get":{"operationId":"ahJs_getAhj","summary":"Get AHJ","description":"Retrieve a specific AHJ by ID, including catalog metadata and custom field values.","tags":["AHJs"],"parameters":[{"name":"ahj_id","in":"path","description":"The AHJ ID.","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"AHJ details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AHJ"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAhjRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAhjRequestNotFoundError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAhjRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"ahJs_updateAhj","summary":"Update AHJ","description":"Update custom property values on an AHJ. The body `custom` map is keyed by property `keyName` — fetch the available keys via `GET /properties?record_type=ahj`.\n\nBuilt-in AHJ fields (under `Community Data` in the UI) are read-only and cannot be updated through this endpoint.\n\nPass `null` to clear a value.\n","tags":["AHJs"],"parameters":[{"name":"ahj_id","in":"path","description":"The AHJ ID.","required":true,"schema":{"type":"integer"}},{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"AHJ updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AHJ"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAhjRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAhjRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAhjRequestNotFoundError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAhjRequestBadGatewayError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AHJUpdate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/utilities":{"get":{"operationId":"utilities_list-utilities","summary":"List Utilities","description":"Retrieve a paginated list of utilities.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Sorting by name (`order_by`, default: asc)\n- Search by name, holding company, or state code (`q`)\n- Filter by `state` (two-letter code) and `ownership_type`\n- Geo mode: pass `lat`+`lng` (together) to return every utility whose service territory covers the point, ordered most-specific-first. Name/state/ownership_type filters are ignored, and an empty array is returned if none cover the point.\n\nOnly active utilities are returned. Utilities are seeded globally from the HIFLD catalog. Most fields are read-only; only custom fields can be updated (see PATCH /utilities/{utility_id}).\n","tags":["Utilities"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"q","in":"query","description":"Search by utility name, holding company, or state code (case-insensitive).","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","description":"Filter by two-letter state code (e.g. \"CA\").","required":false,"schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"ownership_type","in":"query","description":"Filter by ownership type.","required":false,"schema":{"$ref":"#/components/schemas/UtilitiesGetParametersOwnershipType"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/UtilitiesGetParametersOrderBy","default":"asc"}},{"name":"lat","in":"query","description":"Latitude in decimal degrees. Must be used together with `lng`.","required":false,"schema":{"type":"number","format":"double","minimum":-90,"maximum":90}},{"name":"lng","in":"query","description":"Longitude in decimal degrees. Must be used together with `lat`.","required":false,"schema":{"type":"number","format":"double","minimum":-180,"maximum":180}}],"responses":{"200":{"description":"List of utilities","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Utility"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-utilitiesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-utilitiesRequestUnauthorizedError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-utilitiesRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/utilities/{utility_id}":{"get":{"operationId":"utilities_getUtility","summary":"Get Utility","description":"Retrieve a specific utility by ID, including catalog metadata and custom field values.","tags":["Utilities"],"parameters":[{"name":"utility_id","in":"path","description":"The utility ID.","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Utility details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Utility"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUtilityRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUtilityRequestNotFoundError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUtilityRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"utilities_updateUtility","summary":"Update Utility","description":"Update custom property values on a utility. The body `custom` map is keyed by property `keyName` — fetch the available keys via `GET /properties?record_type=utility`.\n\nBuilt-in utility fields (name, state, ownershipType, holdingCompany, etc.) are read-only and cannot be updated through this endpoint.\n\nPass `null` to clear a value.\n","tags":["Utilities"],"parameters":[{"name":"utility_id","in":"path","description":"The utility ID.","required":true,"schema":{"type":"integer"}},{"name":"allow_new_options","in":"query","description":"Whether to allow creation of new dropdown options during record creation","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Utility updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Utility"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUtilityRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUtilityRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUtilityRequestNotFoundError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUtilityRequestBadGatewayError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UtilityUpdate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/contacts":{"get":{"operationId":"contacts_listContacts","summary":"List Contacts","description":"Retrieve a paginated list of contacts.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Search (`q`)\n","tags":["contacts"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ContactsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ContactsGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ContactsGetParametersOrderBy","default":"asc"}},{"name":"q","in":"query","description":"Full text search across contact name, emails, and phones.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of contacts","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"contacts_createContact","summary":"Create Contact","description":"Create a new contact.\n\nRequired fields:\n- `name`: Contact's full name\n\nOptional fields:\n- `phones`: Array of contact phone numbers\n- `emails`: Array of contact email addresses\n- `title`: Contact title\n- `accountIds`: Array of account IDs to associate\n- `projectIds`: Array of project IDs to associate\n","tags":["contacts"],"responses":{"201":{"description":"Contact created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/contacts/{contact_id}":{"get":{"operationId":"contacts_getContact","summary":"Get Contact","description":"Retrieve a specific contact by ID","tags":["contacts"],"parameters":[{"name":"contact_id","in":"path","description":"Contact identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Contact details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"contacts_updateContact","summary":"Update Contact","description":"Update an existing contact. Supports partial updates.\n\nUpdatable fields:\n- `name`: Contact's full name\n- `phones`: Array of contact phone numbers\n- `emails`: Array of contact email addresses\n- `title`: Contact title\n- `accountIds`: Array of account IDs to associate\n- `projectIds`: Array of project IDs to associate\n","tags":["contacts"],"parameters":[{"name":"contact_id","in":"path","description":"Contact identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Contact updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"contacts_deleteContact","summary":"Delete Contact","description":"Delete a specific contact by ID","tags":["contacts"],"parameters":[{"name":"contact_id","in":"path","description":"Contact identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Contact deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteContactRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteContactRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/notes":{"get":{"operationId":"notes_listProjectNotes","summary":"List Project Notes","description":"Retrieve notes for a specific project\n\n**Note:** The `/projects/{project_id}/comments` path will continue to work until users are individually notified and migrated to the new naming.\n","tags":["notes"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of notes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListNotesResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectNotesRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectNotesRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"notes_createProjectNote","summary":"Create Project Note","description":"Create a new note on a project\n\n**Note:** The `/projects/{project_id}/comments` path will continue to work until users are notified and migrated to the new naming.\n","tags":["notes"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Note created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectNoteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectNoteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectNoteRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/notes":{"get":{"operationId":"notes_listOpportunityNotes","summary":"List Opportunity Notes","description":"Retrieve notes for a specific opportunity\n\n**Note:** The `/requests/{request_id}/comments` path will continue to work until users are notified and migrated to the new naming.\n","tags":["notes"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of notes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListNotesResponse"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"notes_createOpportunityNote","summary":"Create Opportunity Note","description":"Add a new note on an opportunity\n\n**Note:** The `/requests/{request_id}/comments` path will continue to work until users are notified and migrated to the new naming.\n","tags":["notes"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Note created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreateResponse"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/notes":{"get":{"operationId":"notes_listAccountNotes","summary":"List Account Notes","description":"Retrieve notes for a specific account\n\n**Note:** The `/clients/{client_id}/comments` path will continue to work until users are notified and migrated to the new naming.\n","tags":["notes"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of notes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListNotesResponse"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"notes_createAccountNote","summary":"Create Account Note","description":"Add a new note on an account\n\n**Note:** The `/clients/{client_id}/comments` path will continue to work until users are notified and migrated to the new naming.\n","tags":["notes"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Note created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreateResponse"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/work-orders/{work_order_id}/notes":{"get":{"operationId":"notes_listWorkOrderNotes","summary":"List Work Order Notes","description":"Returns paginated notes (comments) for a specific work order, sorted by creation date descending (newest first).\n","tags":["notes"],"parameters":[{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Paginated list of notes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Notes_listWorkOrderNotes_Response_200"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkOrderNotesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkOrderNotesRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkOrderNotesRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"notes_createWorkOrderNote","summary":"Create Work Order Note","description":"Add a note (comment) to a specific work order.\n\nNotes are stored as internal comments linked to the work order. They trigger\nthe same notification and feed pipeline as comments created in the Coperniq UI.\n","tags":["notes"],"parameters":[{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Note created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteCreateOnWorkOrderResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderNoteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderNoteRequestUnauthorizedError"}}}},"403":{"description":"API key valid but does not have access to this resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderNoteRequestForbiddenError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderNoteRequestNotFoundError"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderNoteRequestTooManyRequestsError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":5000,"description":"Note text content (1–5000 characters).\n\nMention (@) tokens are supported in the body string using the format `[Display Name|~id:USER_ID]` (users), `[Team Name|~team:TEAM_ID]` (teams, notifies all members), or `[Name|~agent:slug]` (AI agents). The display-name portion is cosmetic; the trailing token drives the mention. A valid mention creates a feed notification for the mentioned recipient(s). The author is excluded from their own mention notifications, so mention a different user than the one the API key authenticates as to test.\n"},"fileIds":{"type":"array","items":{"type":"integer"},"description":"Optional array of file IDs (previously uploaded) to attach to the note."},"replyToId":{"type":"integer","description":"ID of the note to reply to. Creates a threaded reply on the parent note."}},"required":["body"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/notes/{note_id}":{"patch":{"operationId":"notes_updateNote","summary":"Update Note","description":"Update an existing note. The note being updated must be authored by the connected user.\n\n**Note:** The following legacy paths will continue to work until users are notified and migrated to the new naming:\n- `/projects/{projectId}/comments/{commentId}`\n- `/requests/{requestId}/comments/{commentId}`\n- `/clients/{clientId}/comments/{commentId}`\n","tags":["notes"],"parameters":[{"name":"note_id","in":"path","description":"Note identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Note updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Note"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNoteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNoteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNoteRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"notes_deleteNote","summary":"Delete Note","description":"Delete a note by its ID.\n\nIf the note has replies, it is soft-deleted — the text is replaced with \"This communication was deleted.\" and the thread is preserved. If the note has no replies, both the Communication and Comment records are hard-deleted.\n\nReturns `204 No Content` on success.\n","tags":["notes"],"parameters":[{"name":"note_id","in":"path","description":"Note identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Note deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteNoteRequestUnauthorizedError"}}}},"403":{"description":"API key valid but does not have access to this resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteNoteRequestForbiddenError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteNoteRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/work-orders":{"get":{"operationId":"workOrders_listWorkOrders","summary":"List Work Orders","description":"Retrieve a paginated list of work orders across all projects.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Archived work orders (`include_archived=true`, case-insensitive; any other value is treated as `false`, so archived work orders are excluded by default)\n\nWork orders whose parent project, opportunity, or account is archived are never returned, even with `include_archived=true`.\n","tags":["workOrders"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/WorkOrdersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/WorkOrdersGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/WorkOrdersGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of work orders","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrder"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkOrdersRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/work-orders":{"get":{"operationId":"workOrders_listProjectWorkOrders","summary":"List Project Work Orders","description":"Retrieve work orders for a specific project.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Archived work orders (`include_archived=true`, case-insensitive; any other value is treated as `false`, so archived work orders are excluded by default)\n\nWork orders whose parent project, opportunity, or account is archived are never returned, even with `include_archived=true`.\n","tags":["workOrders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of work orders","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrder"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectWorkOrdersRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectWorkOrdersRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"workOrders_createProjectWorkOrder","summary":"Create Project Work Order","description":"Create a new work order in a project.\n\nNotes:\n- `templateId` is required.\n- `phaseInstanceId` is optional; if provided the referenced phase must be started (active) for creation to succeed.\n","tags":["workOrders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Work order created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectWorkOrderRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"integer","description":"Template to use for the work order"},"phaseInstanceId":{"type":"integer","description":"Optional. Phase instance id where the work order will be created (phase must be started). You can gather phase instance ids from the get project endpoint."}},"required":["templateId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/work-orders":{"get":{"operationId":"workOrders_listOpportunityWorkOrders","summary":"List Opportunity Work Orders","description":"Retrieve work orders for a specific opportunity.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Archived work orders (`include_archived=true`, case-insensitive; any other value is treated as `false`, so archived work orders are excluded by default)\n\nWork orders whose parent project, opportunity, or account is archived are never returned, even with `include_archived=true`.\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["workOrders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of work orders","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrder"}}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"workOrders_createOpportunityWorkOrder","summary":"Create Opportunity Work Order","description":"Create a new work order for an opportunity.\n\nNotes:\n- `templateId` is required.\n- `phaseInstanceId` is optional. The phase does not need to be started to create an opportunity work order.\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["workOrders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Work order created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityWorkOrderRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"integer","description":"The ID of the work order template to use"},"phaseInstanceId":{"type":"integer","description":"Optional. The ID of the phase instance to use. If provided, the phase does not need to be started to create an opportunity work order. You can gather phase instance ids from the get opportunity endpoint."}},"required":["templateId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/work-orders":{"get":{"operationId":"workOrders_listAccountWorkOrders","summary":"List Account Work Orders","description":"Retrieve work orders for a specific account.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Archived work orders (`include_archived=true`, case-insensitive; any other value is treated as `false`, so archived work orders are excluded by default)\n\nWork orders whose parent project, opportunity, or account is archived are never returned, even with `include_archived=true`.\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["workOrders"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersGetParametersOrderBy","default":"asc"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of work orders","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrder"}}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"workOrders_createAccountWorkOrder","summary":"Create Account Work Order","description":"Create a new work order for an account (no phases)\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["workOrders"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Work order created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountWorkOrderRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"integer"}},"required":["templateId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/work-orders/{work_order_id}":{"get":{"operationId":"workOrders_getWorkOrder","summary":"Get Work Order","description":"Retrieve a specific work order by ID.\n\nArchived work orders are returned too. Check `isActive`: it is `false` for an archived work order (the deprecated `isArchived` field is `true`).\n\nThe `lineItems` property is returned **only** for service work orders on an **account** (parent project type `ACCOUNT`), and **only** when at least one line item exists. Otherwise the field is omitted from the JSON object.\n","tags":["workOrders"],"parameters":[{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Work order details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrder"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWorkOrderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/work-orders/templates":{"get":{"operationId":"workOrders_listWorkOrderTemplates","summary":"List Work Order Templates","description":"Retrieve available work order templates. Returns all templates (not paginated).","tags":["workOrders"],"responses":{"200":{"description":"List of work order templates","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderTemplate"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkOrderTemplatesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/work-orders/{work_order_id}":{"patch":{"operationId":"workOrders_updateProjectWorkOrder","summary":"Update Project Work Order","description":"Update a project's work order. Supports partial updates.\n\nUpdatable fields:\n- title, description, priority\n- startDate, endDate, startDateAllDay, endDateAllDay\n- status (label string)\n- assigneeId\n- visits: Only applicable on field work orders. When provided, the `visits` array REPLACES the full set of visits for the work order. Include all existing visits you wish to keep or update (with their `id`), and include new visits without an `id`. Any existing visit not included in the request will be removed. Visit booleans default to false when omitted.\n- checklist: Update the checklist for the work order.\n    When this field is provided, the `checklist` array REPLACES the full set of checklist items on the work order.\n    - Include every existing item you want to keep or modify (identified by `id`). \n    - Any existing item NOT included in this array will be removed.\n    - Each item MUST include an `id`. Items without an `id` are ignored (checklist item creation is not supported).\n- isActive: Set to `false` to archive the work order, or `true` to unarchive it. Applied independently of any other fields present in the same request.\n","tags":["workOrders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Work order updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectWorkOrderRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"workOrders_deleteProjectWorkOrder","summary":"Delete Project Work Order","description":"Delete a specific work order from a project","tags":["workOrders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Work order deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid request (missing or invalid parameters)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProjectWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProjectWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProjectWorkOrderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/work-orders/{work_order_id}":{"patch":{"operationId":"workOrders_updateOpportunityWorkOrder","summary":"Update Opportunity Work Order","description":"Update an opportunity's work order. Supports partial updates.\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n\nUpdatable fields:\n- title, description, priority\n- startDate, endDate, startDateAllDay, endDateAllDay\n- status (label string)\n- assigneeId\n- visits: Only applicable on field work orders. When provided, the `visits` array REPLACES the full set of visits for the work order. Include all existing visits you wish to keep or update (with their `id`), and include new visits without an `id`. Any existing visit not included in the request will be removed. Visit booleans default to false when omitted.\n- checklist: Update the checklist for the work order.\n    When this field is provided, the `checklist` array REPLACES the full set of checklist items on the work order.\n    - Include every existing item you want to keep or modify (identified by `id`). \n    - Any existing item NOT included in this array will be removed.\n    - Each item MUST include an `id`. Items without an `id` are ignored (checklist item creation is not supported).\n- isActive: Set to `false` to archive the work order, or `true` to unarchive it. Applied independently of any other fields present in the same request.\n","tags":["workOrders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Work order updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpportunityWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpportunityWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpportunityWorkOrderRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"workOrders_deleteOpportunityWorkOrder","summary":"Delete Opportunity Work Order","description":"Delete an opportunity's work order by ID\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["workOrders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Work order deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteOpportunityWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteOpportunityWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteOpportunityWorkOrderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/work-orders/{work_order_id}":{"patch":{"operationId":"workOrders_updateAccountWorkOrder","summary":"Update Account Work Order","description":"Update an account's work order. Supports partial updates.\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n\nUpdatable fields:\n- title, description, priority\n- startDate, endDate, startDateAllDay, endDateAllDay\n- status (label string)\n- assigneeId\n- visits: Only applicable on field work orders. When provided, the `visits` array REPLACES the full set of visits for the work order. Include all existing visits you wish to keep or update (with their `id`), and include new visits without an `id`. Any existing visit not included in the request will be removed. Visit booleans default to false when omitted.\n- checklist: Update the checklist for the work order.\n    When this field is provided, the `checklist` array REPLACES the full set of checklist items on the work order.\n    - Include every existing item you want to keep or modify (identified by `id`). \n    - Any existing item NOT included in this array will be removed.\n    - Each item MUST include an `id`. Items without an `id` are ignored (checklist item creation is not supported).\n- isActive: Set to `false` to archive the work order, or `true` to unarchive it. Applied independently of any other fields present in the same request.\n\n**Line items** are not updated here. For account (service) work orders, replace quote line items with **`PUT /work-orders/{work_order_id}/line-items`** (see **Line Items** in this reference).\n","tags":["workOrders"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Work order updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountWorkOrderRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"workOrders_deleteAccountWorkOrder","summary":"Delete Account Work Order","description":"Delete a specific work order for an account\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["workOrders"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Work order deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountWorkOrderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountWorkOrderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountWorkOrderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/files":{"get":{"operationId":"files_getProjectFiles","summary":"Get Project Files","description":"Retrieve all files associated with a project","tags":["files"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/File"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectFilesRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectFilesRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectFilesRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"files_uploadProjectFileFromUrl","summary":"Create Project File (from URL)","description":"Upload a file to a project by providing its URL","tags":["files"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadProjectFileFromUrlRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadProjectFileFromUrlRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadProjectFileFromUrlRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL of the file to upload"},"name":{"type":"string","description":"Name of the file"},"isArchived":{"type":"boolean","default":false,"description":"Whether the file is archived"},"phaseInstanceId":{"type":"integer","description":"Optional. The ID of the phase instance to use. If provided, the phase does not need to be started to upload a file. You can gather phase instance ids from the get project endpoint."}},"required":["url"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/files":{"get":{"operationId":"files_getRequestFiles","summary":"Get Opportunity Files","description":"Retrieve all files associated with an opportunity\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["files"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/File"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetRequestFilesRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetRequestFilesRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetRequestFilesRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"files_uploadRequestFileFromUrl","summary":"Create Opportunity File (from URL)","description":"Upload a file to an opportunity by providing its URL\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["files"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequestFileFromUrlRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequestFileFromUrlRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequestFileFromUrlRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL of the file to upload"},"name":{"type":"string","description":"Name of the file"},"isArchived":{"type":"boolean","default":false,"description":"Whether the file is archived"},"phaseInstanceId":{"type":"integer","description":"Optional. The ID of the phase instance to use. If provided, the phase does not need to be started to upload a file. You can gather phase instance ids from the get opportunity endpoint."}},"required":["url"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/files":{"get":{"operationId":"files_getAccountFiles","summary":"Get Account Files","description":"Retrieve all files associated with an account\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["files"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/File"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountFilesRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountFilesRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountFilesRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"files_uploadAccountFileFromUrl","summary":"Create Account File (from URL)","description":"Upload a file to an account by providing its URL\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["files"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAccountFileFromUrlRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAccountFileFromUrlRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAccountFileFromUrlRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL of the file to upload"},"name":{"type":"string","description":"Name of the file"},"isArchived":{"type":"boolean","default":false,"description":"Whether the file is archived"}},"required":["url"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/files/{file_id}":{"get":{"operationId":"files_getFile","summary":"Get File","description":"Retrieve a specific file by id.\n","tags":["files"],"parameters":[{"name":"file_id","in":"path","description":"File identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFileRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFileRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFileRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"files_updateFile","summary":"Update File","description":"Rename, archive/unarchive, and/or move a file. Moving isn't a separate operation — set `folderId` and/or `phaseInstanceId` in the same request.\n\nNotes:\n- All fields are optional; only fields present in the request body are applied.\n- `folderId` accepts `null` to un-file (remove from its current folder).\n- The target folder must belong to the same project as the file.\n- A file sits in either a folder or the root of a phase, never both. Setting `phaseInstanceId` clears `folderId` (and vice versa) unless you explicitly set both in the same request, which is rejected with `400`.\n","tags":["files"],"parameters":[{"name":"file_id","in":"path","description":"File identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUpdateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFileRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFileRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFileRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"New file name"},"isActive":{"type":"boolean","description":"Set to false to archive the file, or true to unarchive it"},"folderId":{"type":["integer","null"],"description":"Folder to move the file into. Pass `null` to un-file it."},"phaseInstanceId":{"type":"integer","description":"Phase instance to move the file to the root of."}}}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"files_deleteFile","summary":"Delete File","description":"Delete a file by id.\n","tags":["files"],"parameters":[{"name":"file_id","in":"path","description":"File identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Files_deleteFile_Response_200"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteFileRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteFileRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/files/upload":{"post":{"operationId":"files_uploadProjectFile","summary":"Create Project File (stream)","description":"Upload a file to a project using multipart/form-data\n\n**File size limit:** Files uploaded through this endpoint are currently capped at **6 MB**. For larger files, upload the file to your own storage using a pre-signed URL and create the file record with **`POST /projects/{project_id}/files`**, passing the file's URL instead of streaming the bytes.\n","tags":["files"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"name","in":"query","description":"Optional file name to store","required":false,"schema":{"type":"string"}},{"name":"content_type","in":"query","description":"Optional MIME type to associate with the file","required":false,"schema":{"type":"string"}},{"name":"phase_instance_id","in":"query","description":"Optional phase instance id to associate with the file","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadProjectFileRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadProjectFileRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadProjectFileRequestInternalServerError"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/files/upload":{"post":{"operationId":"files_uploadRequestFile","summary":"Create Opportunity File (stream)","description":"Upload a file to an opportunity using multipart/form-data\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n\n**File size limit:** Files uploaded through this endpoint are currently capped at **6 MB**. For larger files, upload the file to your own storage using a pre-signed URL and create the file record with **`POST /opportunities/{opportunity_id}/files`**, passing the file's URL instead of streaming the bytes.\n","tags":["files"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"name","in":"query","description":"Optional file name to store","required":false,"schema":{"type":"string"}},{"name":"content_type","in":"query","description":"Optional MIME type to associate with the file","required":false,"schema":{"type":"string"}},{"name":"phase_instance_id","in":"query","description":"Optional phase instance id to associate with the file","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequestFileRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequestFileRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequestFileRequestInternalServerError"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/files/upload":{"post":{"operationId":"files_uploadAccountFile","summary":"Create Account File (stream)","description":"Upload a file to an account using multipart/form-data\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n\n**File size limit:** Files uploaded through this endpoint are currently capped at **6 MB**. For larger files, upload the file to your own storage using a pre-signed URL and create the file record with **`POST /accounts/{account_id}/files`**, passing the file's URL instead of streaming the bytes.\n","tags":["files"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"name","in":"query","description":"Optional file name to store","required":false,"schema":{"type":"string"}},{"name":"content_type","in":"query","description":"Optional MIME type to associate with the file","required":false,"schema":{"type":"string"}},{"name":"phase_instance_id","in":"query","description":"Optional phase instance id to associate with the file","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAccountFileRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAccountFileRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAccountFileRequestInternalServerError"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/folders":{"get":{"operationId":"folders_getProjectFolders","summary":"List Project Folders","description":"Retrieve the top level of a project's Docs tab: workflow phases, plus any real doc folders that sit at the project root (not nested in another folder or scoped to a phase).\n\nEach item carries a `type` field (`phase` or `folder`) telling you what it is and, for folders, matches the shape of `GET /folders/{folder_id}`.\n\n**Behavior change:** this endpoint used to return every real folder flat, including ones nested under another folder or scoped to a phase. It now returns root-level folders only, alongside phase rows, matching what the UI shows at the top of the Docs tab. To see what's inside a phase or folder, use `GET /phases/{phase_instance_id}/contents` or `GET /folders/{folder_id}/contents`.\n\nPagination (`page`/`page_size`) applies only to the folder half of the results — phase rows are returned unpaginated (bounded by the project's workflow, not user-created volume). Pass `include_archived=true` to include archived root folders (default `false`); this doesn't affect phase rows.\n","tags":["folders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FoldersListItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectFoldersRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectFoldersRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectFoldersRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"folders_createProjectFolder","summary":"Create Project Folder","description":"Create a new doc folder in a project.\n\nNotes:\n- `name` is required.\n- `parentId` and `phaseInstanceId` are mutually exclusive — a folder sits either at the root of a phase, or nested under another folder, not both.\n- Folders nest at most 2 levels deep.\n","tags":["folders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectFolderRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectFolderRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectFolderRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Folder name"},"parentId":{"type":"integer","description":"Optional. Parent folder id to nest this folder under."},"phaseInstanceId":{"type":"integer","description":"Optional. Phase instance id this folder should sit at the root of. You can gather phase instance ids from the Get Project endpoint."}},"required":["name"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/folders":{"get":{"operationId":"folders_getOpportunityFolders","summary":"List Opportunity Folders","description":"Retrieve the top level of an opportunity's Docs tab: workflow phases, plus any real doc folders that sit at the opportunity root (not nested in another folder or scoped to a phase). Same shape as the project version of this endpoint — opportunities have their own workflow phases too.\n\nTo see what's inside a phase or folder, use `GET /phases/{phase_instance_id}/contents` or `GET /folders/{folder_id}/contents` — both are addressed by id alone, no opportunity needed in the path.\n","tags":["folders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FoldersListItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityFoldersRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityFoldersRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityFoldersRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"folders_createOpportunityFolder","summary":"Create Opportunity Folder","description":"Create a new doc folder in an opportunity.\n\nNotes:\n- `name` is required.\n- `parentId` and `phaseInstanceId` are mutually exclusive — a folder sits either at the root of a phase, or nested under another folder, not both.\n- Folders nest at most 2 levels deep.\n- Update and delete a folder via `PATCH`/`DELETE /folders/{folder_id}`, same as project folders.\n","tags":["folders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderCreateResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityFolderRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityFolderRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityFolderRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Folder name"},"parentId":{"type":"integer","description":"Optional. Parent folder id to nest this folder under."},"phaseInstanceId":{"type":"integer","description":"Optional. Phase instance id this folder should sit at the root of."}},"required":["name"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/folders/{folder_id}":{"get":{"operationId":"folders_getFolderById","summary":"Get Folder","description":"Retrieve a specific doc folder by id.\n","tags":["folders"],"parameters":[{"name":"folder_id","in":"path","description":"Folder identifier","required":true,"schema":{"type":"integer"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFolderByIdRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFolderByIdRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFolderByIdRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"folders_updateFolder","summary":"Update Folder","description":"Rename, move, or archive a doc folder.\n\nNotes:\n- All fields are optional; only fields present in the request body are applied.\n- `parentId` and `phaseInstanceId` are mutually exclusive.\n- Moving a folder that has subfolders is rejected.\n- Archiving a folder cascades the archived state to its subfolders and their files.\n","tags":["folders"],"parameters":[{"name":"folder_id","in":"path","description":"Folder identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFolderRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFolderRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFolderRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"New folder name"},"parentId":{"type":["integer","null"],"description":"New parent folder id. Pass `null` to move the folder to the root of its phase/project."},"phaseInstanceId":{"type":["integer","null"],"description":"New phase instance id. Pass `null` to detach from a phase."},"isActive":{"type":"boolean","description":"Set to false to archive the folder, or true to unarchive it"}}}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"folders_deleteFolder","summary":"Delete Folder","description":"Delete a doc folder. Deleting a folder also deletes its subfolders and any files inside them.\n","tags":["folders"],"parameters":[{"name":"folder_id","in":"path","description":"Folder identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folders_deleteFolder_Response_200"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteFolderRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteFolderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/folders/{folder_id}/contents":{"get":{"operationId":"folders_getFolderContents","summary":"Get Folder Contents","description":"List a folder's direct children: subfolders, files, and forms filed directly in it (not further nested).\n\nEach item carries a `type` field (`folder`, `file`, or `form`) telling you what it is. For `type: \"folder\"` items, call this same endpoint again with that folder's id to walk further in. Forms are ordinary files under the hood (`isForm: true` on the underlying file) that inherit their folder/phase placement, so they appear here rather than in a separate forms listing.\n\nNote: on this endpoint (and the phase-contents endpoint), the file's MIME/category label is named `fileType` instead of `type`, to avoid colliding with the folder/file/form discriminator. This does not affect `GET /projects/{project_id}/files`, where `type` keeps its original meaning.\n","tags":["folders"],"parameters":[{"name":"folder_id","in":"path","description":"Folder identifier","required":true,"schema":{"type":"integer"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FolderContentsItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFolderContentsRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFolderContentsRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFolderContentsRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/phases/{phase_instance_id}/contents":{"get":{"operationId":"folders_getPhaseContents","summary":"Get Phase Contents","description":"List a workflow phase's direct children: doc folders, files, and forms filed directly at the phase root (not nested inside a folder). Works the same whether the phase belongs to a project or an opportunity.\n\nEach item carries a `type` field (`folder`, `file`, or `form`) telling you what it is. For `type: \"folder\"` items, call `GET /folders/{folder_id}/contents` with that folder's id to walk further in. Forms are ordinary files under the hood (`isForm: true` on the underlying file) that inherit their folder/phase placement, so they appear here rather than in a separate forms listing.\n\nNote: on this endpoint (and the folder-contents endpoint), the file's MIME/category label is named `fileType` instead of `type`, to avoid colliding with the folder/file/form discriminator.\n\nPhase instance ids come from the `type: \"phase\"` rows returned by `GET /projects/{project_id}/folders` or `GET /opportunities/{opportunity_id}/folders`.\n","tags":["folders"],"parameters":[{"name":"phase_instance_id","in":"path","description":"Phase instance identifier. Gathered from the `type: \"phase\"` rows returned by GET /projects/{project_id}/folders or GET /opportunities/{opportunity_id}/folders.","required":true,"schema":{"type":"integer"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FolderContentsItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetPhaseContentsRequestBadRequestError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetPhaseContentsRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetPhaseContentsRequestInternalServerError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/line-items":{"get":{"operationId":"lineItems_listProjectLineItems","summary":"List Project Line Items","description":"Retrieve all line items for a project","tags":["lineItems"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of line items","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LineItem"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectLineItemsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectLineItemsRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"put":{"operationId":"lineItems_replaceProjectLineItems","summary":"Replace Project Line Items","description":"Replace all line items for a project. Send an object with `lineItems`, `sections`, or both:\n\n- **`lineItems`** `{ lineItems: [...] }` — ungrouped line items.\n- **`sections`** `{ sections: [{ name?, lineItems: [...] }] }` — line items grouped into named sections.\n- The two may be combined (ungrouped items + named sections).\n\nA `catalogItemId` may appear at most once across the flattened set.\n\n> **Deprecated:** the previous request shape is still accepted for backwards compatibility but is deprecated and will not be supported in a future version.\n","tags":["lineItems"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Updated list of line items","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LineItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceProjectLineItemsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceProjectLineItemsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceProjectLineItemsRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectLineItemsPutRequest"}}}},"security":[{"ApiKeyAuth":[]}]}},"/work-orders/{work_order_id}/line-items":{"put":{"operationId":"lineItems_replaceWorkOrderLineItems","summary":"Replace Work Order Line Items","description":"Replaces all line items on a work order. Internally updates or creates the underlying quote linked to the task.\n\nSupported **only** for service work orders on an **account** (parent project type `ACCOUNT`). Requests for other work orders receive `400`.\n\nProvide **either** `sections` **or** `lineItems` (not both), using the same shapes as quote line items.\n","tags":["lineItems"],"parameters":[{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Updated line items (dollar amounts)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderLineItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceWorkOrderLineItemsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceWorkOrderLineItemsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceWorkOrderLineItemsRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceWorkOrderLineItemsRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkOrderLineItemsPutRequest"}}}},"security":[{"ApiKeyAuth":[]}]}},"/form-templates":{"get":{"operationId":"formTemplates_listFormTemplates","summary":"List Form Templates","description":"Retrieve all form templates for the company. Form templates are reusable form definitions\nthat define the layout, fields, assignees, and labels for forms created on projects/workflows.\n","tags":["formTemplates"],"parameters":[{"name":"includeArchived","in":"query","description":"Include archived form templates in results","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of form templates","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateSummary"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFormTemplatesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/form-templates/{form_template_id}":{"get":{"operationId":"formTemplates_getFormTemplateById","summary":"Get Form Template","description":"Retrieve a specific form template by ID, including its full field layout.\n","tags":["formTemplates"],"parameters":[{"name":"form_template_id","in":"path","description":"Form template identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Form template details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormTemplateDetail"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormTemplateByIdRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormTemplateByIdRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormTemplateByIdRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"formTemplates_updateFormTemplate","summary":"Update Form Template","description":"Update an existing form template. All fields are optional — only provided fields are updated. `formLayouts` is optional — omit it to leave the existing layout untouched.\n\n**formLayouts replacement:** When provided, the `formLayouts` array **fully replaces** all layout groups and their fields on the template. Position is determined by array order.\n\n**IDs are not stable across updates.** Every update internally deletes all existing layout rows and inserts new ones, so every group and field receives a new auto-generated ID after each PATCH. The IDs returned in a GET response are only valid until the next PATCH. Do not store or rely on layout IDs across updates.\n\n**Using `id` in the request:** You can pass `{ \"id\": <id from a recent GET> }` for a group or field to reference its current data without repeating all attributes — the API will look up the existing name, type, isRequired, etc. and carry them forward. This is a convenience shortcut for the current request only; the ID will be different in the response.\n\n**Assignee (mutually exclusive — use at most one):**\n- `assigneeId` — assign a specific user by ID.\n- `assigneeProperty` — assign by project property key: `OWNER`, `SALES_REP`, `PROJECT_MANAGER`, `CREATED_BY`, or a custom PERSON property `keyName`.\n- `assigneeTeamId` — assign a team: the team lead becomes the assignee and all other team members are added as collaborators.\n\n**Collaborators:**\n- `collaborators` — replaces the list of direct user collaborator IDs.\n- `collaboratorProperties` — replaces the list of property-based collaborators. Each value is a standard key (`OWNER`, `SALES_REP`, `PROJECT_MANAGER`, `CREATED_BY`) or a custom PERSON property `keyName`.\n- `collaboratorTeamIds` — team IDs whose members are resolved to user IDs and merged (deduplicated) into collaborators alongside any direct `collaborators` and members from `assigneeTeamId`.\n","tags":["formTemplates"],"parameters":[{"name":"form_template_id","in":"path","description":"Form template identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Form template updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormTemplateDetail"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormTemplateRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormTemplateRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormTemplateRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormTemplateUpdate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/forms":{"get":{"operationId":"forms_listProjectForms","summary":"List Project Forms","description":"Retrieve all forms associated with a project.\n\nSupports:\n- Status filtering (`status` query parameter)\n","tags":["forms"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"status","in":"query","description":"Filter forms by status","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdFormsGetParametersStatus"}}],"responses":{"200":{"description":"List of forms","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Form"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectFormsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"forms_createProjectForm","summary":"Create Project Form","description":"Create a new form instance in a project.\n\nNotes:\n- `templateId` is required.\n- The form is created using its template's name. `name` is not accepted here — use `PATCH /forms/{form_id}` to rename it afterward.\n- `phaseInstanceId` is optional, but if provided the referenced phase must be started (active) for creation to succeed.\n","tags":["forms"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Form created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forms_createProjectForm_Response_201"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectFormRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectFormRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectFormRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"integer","description":"Template to use for the form"},"phaseInstanceId":{"type":"integer","description":"Optional. Phase instance id where the form will be created (phase must be started). You can gather phase instance ids from the Get Project endpoint."}},"required":["templateId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/forms":{"get":{"operationId":"forms_listOpportunityForms","summary":"List Opportunity Forms","description":"Retrieve all forms associated with an opportunity.\n\nSupports:\n- Status filtering (`status` query parameter)\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["forms"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"status","in":"query","description":"Filter forms by status","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFormsGetParametersStatus"}}],"responses":{"200":{"description":"List of forms","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityForm"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOpportunityFormsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"forms_createOpportunityForm","summary":"Create Opportunity Form","description":"Create a new form instance in an opportunity.\n\nNotes:\n- `templateId` is required.\n- `name` is optional; defaults to the template's name.\n- Opportunities cannot be assigned to a phase, so there is no `phaseInstanceId` field on this endpoint.\n","tags":["forms"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Form created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forms_createOpportunityForm_Response_201"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityFormRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityFormRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityFormRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"integer","description":"Template to use for the form"},"name":{"type":"string","description":"Optional. Name for the created form. Defaults to the template's name."}},"required":["templateId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/forms/{form_id}":{"get":{"operationId":"forms_getForm","summary":"Get Form","description":"Retrieve a specific form by ID with detailed layout information","tags":["forms"],"parameters":[{"name":"form_id","in":"path","description":"Form identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Form details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormDetail"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"forms_updateForm","summary":"Update Form","description":"Update an existing form, including core fields (status, due dates, assignee, collaborators)\nand individual field responses.\n","tags":["forms"],"parameters":[{"name":"form_id","in":"path","description":"Form identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Updated form details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormDetail"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormUpdate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/work-orders/{work_order_id}/forms":{"post":{"operationId":"forms_createWorkOrderForm","summary":"Create Work Order Form","description":"Create a new form instance on a work order.\n\nNotes:\n- `templateId` is required.\n- The form is created using its template's name. `name` is not accepted here — use `PATCH /forms/{form_id}` to rename it afterward.\n- A work order already sits in a phase, so `phaseInstanceId` is not accepted on this endpoint — the form inherits placement via its parent element instance.\n","tags":["forms"],"parameters":[{"name":"work_order_id","in":"path","description":"Work order identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Form created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forms_createWorkOrderForm_Response_201"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderFormRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderFormRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderFormRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkOrderFormRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"integer","description":"Template to use for the form"}},"required":["templateId"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/forms/{form_id}/fields/file-from-url":{"post":{"operationId":"forms_attachFileToFormFieldFromUrl","summary":"Attach file to form field from URL","description":"Uploads a file from a public URL into Coperniq and attaches it to a specific FILE-type field on the form.\n","tags":["forms"],"parameters":[{"name":"form_id","in":"path","description":"Form identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"File uploaded and attached successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forms_attachFileToFormFieldFromUrl_Response_200"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachFileToFormFieldFromUrlRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachFileToFormFieldFromUrlRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachFileToFormFieldFromUrlRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"columnId":{"type":"integer","description":"ID of the FILE-type field to attach the uploaded file to."},"url":{"type":"string","format":"uri","description":"Public URL of the file to upload."},"name":{"type":"string","description":"Optional display name for the uploaded file."},"projectId":{"type":"integer","description":"Optional project ID to associate with the file. This will add the file to the project's 'Docs' section at the root level."},"action":{"$ref":"#/components/schemas/FormsFormIdFieldsFileFromUrlPostRequestBodyContentApplicationJsonSchemaAction","description":"Whether to append to existing files (add) or replace them entirely (replace). Defaults to add."}},"required":["columnId","url"]}}}},"security":[{"ApiKeyAuth":[]}]}},"/forms/{form_id}/pdf":{"post":{"operationId":"forms_getFormPdf","summary":"Export Form as PDF","description":"Export a form to PDF. All body fields are optional.\n","tags":["forms"],"parameters":[{"name":"form_id","in":"path","description":"Form identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"PDF generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forms_getFormPdf_Response_200"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormPdfRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormPdfRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormPdfRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFormPdfRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"imagesOnly":{"type":"boolean","description":"Export only the form's image fields, omitting other field types. Defaults to false."},"imagesInRow":{"$ref":"#/components/schemas/FormsFormIdPdfPostRequestBodyContentApplicationJsonSchemaImagesInRow","description":"Number of images to lay out per row. Defaults to 2."},"includeImageMetadata":{"type":"boolean","description":"Include image metadata (e.g. GPS, timestamp) below each image. Defaults to true."}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/quotes":{"get":{"operationId":"quotes_listQuotes","summary":"List Quotes","description":"Retrieve a paginated list of quotes.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Status filtering (`status`)\n- Sorting (`order_by`)\n","tags":["quotes"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/QuotesGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/QuotesGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/QuotesGetParametersUpdatedBefore"}},{"name":"status","in":"query","description":"Filter quotes by status","required":false,"schema":{"$ref":"#/components/schemas/QuotesGetParametersStatus"}}],"responses":{"200":{"description":"List of quotes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListQuotesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListQuotesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"quotes_createQuote","summary":"Create Quote","description":"Create a new quote on an opportunity (project/deal/account record).\n\n- `opportunityId`: Required — record ID used by the payment service.\n- `sections` or `lineItems`: At least one item required\n- `discountType` / `discountValue`: Optional discount\n- `taxId`: Optional tax\n- `issueDate` / `status`: `issueDate` only allowed with `status` of `SENT` or `APPROVED`\n\nTo add or replace line items on a **work order**, use `PUT /work-orders/{work_order_id}/line-items` instead.\n","tags":["quotes"],"responses":{"201":{"description":"Quote created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuoteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuoteRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/quotes":{"get":{"operationId":"quotes_getOpportunityQuotes","summary":"Get Opportunity Quotes","description":"Retrieve quotes for a specific opportunity.","tags":["quotes"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity ID","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdQuotesGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdQuotesGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdQuotesGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of quotes for the opportunity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteListResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityQuotesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/quotes/{quote_id}":{"get":{"operationId":"quotes_getQuote","summary":"Get Quote","description":"Retrieve a specific quote by ID","tags":["quotes"],"parameters":[{"name":"quote_id","in":"path","description":"Quote identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Quote details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetQuoteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetQuoteRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"quotes_updateQuote","summary":"Update Quote","description":"Update an existing quote. Supports partial updates.\n\n**`isArchived`**: pass `true` to archive or `false` to unarchive.\n\nWhen setting **`status`** to anything other than **`DRAFT`**, you must supply **`issueDate`** unless the quote already has one.\n\n**`sharedWithPortal`**: pass `true` or `false` to show or hide the quote on the client portal.\n","tags":["quotes"],"parameters":[{"name":"quote_id","in":"path","description":"Quote identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Quote updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQuoteRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQuoteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQuoteRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"quotes_deleteQuote","summary":"Delete Quote","description":"Delete a quote. The quote is archived first (required by the payment service),\nthen permanently deleted.\n","tags":["quotes"],"parameters":[{"name":"quote_id","in":"path","description":"Quote identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Quote deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteQuoteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteQuoteRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/quotes/{quote_id}/pdf":{"get":{"operationId":"quotes_getQuotePdf","summary":"Get Quote PDF","description":"Returns the quote PDF. Response is JSON with base64-encoded PDF (`pdfBase64`) and `contentType`.\n","tags":["quotes"],"parameters":[{"name":"quote_id","in":"path","description":"Quote identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"PDF payload (base64 JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quotes_getQuotePdf_Response_200"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetQuotePdfRequestUnauthorizedError"}}}},"403":{"description":"API key valid but does not have access to this resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetQuotePdfRequestForbiddenError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetQuotePdfRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/quotes/{quote_id}/send":{"post":{"operationId":"quotes_sendQuote","summary":"Send Quote","description":"Email the quote to the customer and transition **DRAFT** to **SENT** when applicable.\n","tags":["quotes"],"parameters":[{"name":"quote_id","in":"path","description":"Quote identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Quote sent; returns the updated quote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendQuoteRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendQuoteRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/invoices":{"get":{"operationId":"invoices_listInvoices","summary":"List Invoices","description":"Retrieve a paginated list of invoices.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n","tags":["invoices"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/InvoicesGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/InvoicesGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/InvoicesGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of invoices","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvoicesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvoicesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"invoices_createInvoice","summary":"Create Invoice","description":"Create a new invoice.\n\nRequired fields:\n- `recordId`: Project or account ID (the record must exist first)\n- `calculationMethod`: Must be \"LINE_ITEMS\" or \"PERCENTAGE\"\n\nConditionally required:\n- `lineItems`: Required when `calculationMethod` is \"LINE_ITEMS\" (at least one item)\n- `percentage`: Required when `calculationMethod` is \"PERCENTAGE\"\n\nOptional fields:\n- `issueDate`: ISO 8601 datetime string\n- `dueDate`: ISO 8601 datetime string\n- `status`: Initial invoice status (defaults to DRAFT)\n- `description`: Invoice description\n","tags":["invoices"],"responses":{"201":{"description":"Invoice created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoiceRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoiceRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/invoices/{invoice_id}":{"get":{"operationId":"invoices_getInvoice","summary":"Get Invoice","description":"Retrieve a specific invoice by ID","tags":["invoices"],"parameters":[{"name":"invoice_id","in":"path","description":"Invoice identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Invoice details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInvoiceRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInvoiceRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"invoices_updateInvoice","summary":"Update Invoice","description":"Update an existing invoice. Supports partial updates.\n\nUpdatable fields:\n- `lineItems`: Array of line items if calculationMethod is \"LINE_ITEMS\"\n- `sections`: Grouped line items if calculationMethod is \"LINE_ITEMS\"\n- `percentage`: Percentage if calculationMethod is \"PERCENTAGE\"\n- `issueDate`: ISO 8601 datetime string\n- `dueDate`: ISO 8601 datetime string\n- `description`: Invoice description\n- `status`: Invoice status — one of `DRAFT`, `SENT`, `DECLINED`, `PAID`, `PARTIALLY_PAID`, `OVERDUE`. Only valid transitions from the invoice's current status are accepted (e.g. `DECLINED` is reachable from `DRAFT`, `SENT`, `OVERDUE`, or `PARTIALLY_PAID`); an invalid transition is rejected with a 400.\n- `isActive`: Set to `false` to archive the invoice, or `true` to unarchive it. Applied independently of any other fields present in the same request.\n\n`calculationMethod` cannot be changed after creation and is rejected if included.\n","tags":["invoices"],"parameters":[{"name":"invoice_id","in":"path","description":"Invoice identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Invoice updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvoiceRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvoiceRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvoiceRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"invoices_deleteInvoice","summary":"Delete Invoice","description":"Delete a specific invoice by ID","tags":["invoices"],"parameters":[{"name":"invoice_id","in":"path","description":"Invoice identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Invoice deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteInvoiceRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteInvoiceRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/invoices":{"get":{"operationId":"invoices_getProjectInvoices","summary":"Get Project Invoices","description":"Retrieve invoices for a specific project.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n","tags":["invoices"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdInvoicesGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdInvoicesGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdInvoicesGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of invoices for the project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectInvoicesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectInvoicesRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectInvoicesRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/invoices":{"get":{"operationId":"invoices_getAccountInvoices","summary":"Get Account Invoices","description":"Retrieve invoices for a specific account.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["invoices"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdInvoicesGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdInvoicesGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdInvoicesGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of invoices for the account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountInvoicesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountInvoicesRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountInvoicesRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/invoices/{invoice_id}/payments":{"get":{"operationId":"payments_listInvoicePayments","summary":"List Invoice Payments","description":"Retrieve all payment records for an invoice.\n\nAmounts are returned in **dollars** (internal storage uses cents).\n","tags":["payments"],"parameters":[{"name":"invoice_id","in":"path","description":"Invoice identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of payments for the invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvoicePaymentsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvoicePaymentsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvoicePaymentsRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"payments_createInvoicePayment","summary":"Create Invoice Payment","description":"Record a manual payment against an invoice.\n\n**Request body**\n- `amount`: Positive number in **dollars**\n- `paymentDate`: ISO 8601 datetime string\n- `paymentMethod`: One of `CASH`, `ACH`, `CREDIT_CARD`, `KLARNA`, `AFFIRM`, `CHECK`\n- `notes` (optional)\n- `paymentReference` (optional)\n","tags":["payments"],"parameters":[{"name":"invoice_id","in":"path","description":"Invoice identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Payment created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoicePaymentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoicePaymentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoicePaymentRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/invoices/{invoice_id}/payments/{payment_id}":{"get":{"operationId":"payments_getInvoicePayment","summary":"Get Invoice Payment","description":"Retrieve a single payment record on an invoice by payment id.\n\nCore does not expose a standalone payment-record GET; this resolves the payment from the invoice's nested payment records.\n","tags":["payments"],"parameters":[{"name":"invoice_id","in":"path","description":"Invoice identifier","required":true,"schema":{"type":"integer"}},{"name":"payment_id","in":"path","description":"Payment record identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Payment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInvoicePaymentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInvoicePaymentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInvoicePaymentRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/bills/{bill_id}/payments":{"get":{"operationId":"payments_listBillPayments","summary":"List Bill Payments","description":"Retrieve all payment records for a bill.\n\nAmounts are returned in **dollars** (internal storage uses cents).\n","tags":["payments"],"parameters":[{"name":"bill_id","in":"path","description":"Bill identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of payments for the bill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillPaymentListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBillPaymentsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBillPaymentsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBillPaymentsRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"payments_createBillPayment","summary":"Create Bill Payment","description":"Record a manual payment against a bill.\n\n**Request body**\n- `amount`: Positive number in **dollars**\n- `paymentDate`: ISO 8601 datetime string\n- `paymentMethod`: One of `CASH`, `ACH`, `CREDIT_CARD`, `KLARNA`, `AFFIRM`, `CHECK`\n- `notes` (optional)\n- `paymentReference` (optional)\n","tags":["payments"],"parameters":[{"name":"bill_id","in":"path","description":"Bill identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Payment created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillPayment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillPaymentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillPaymentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillPaymentRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/bills/{bill_id}/payments/{payment_id}":{"get":{"operationId":"payments_getBillPayment","summary":"Get Bill Payment","description":"Retrieve a single payment record on a bill by payment id.\n\nCore does not expose a standalone payment-record GET; this resolves the payment from the bill's nested payment records.\n","tags":["payments"],"parameters":[{"name":"bill_id","in":"path","description":"Bill identifier","required":true,"schema":{"type":"integer"}},{"name":"payment_id","in":"path","description":"Payment record identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Payment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillPayment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBillPaymentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBillPaymentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBillPaymentRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/payments/{payment_id}":{"patch":{"operationId":"payments_updatePayment","summary":"Update Payment","description":"Update an existing payment record by its own id — no invoice or bill id is required in the path.\n\nSupports partial updates of `amount`, `paymentMethod`, `paymentDate`, `notes`, and `paymentReference` — the same fields the Coperniq UI exposes when editing a logged payment.\n\nIf the payment is external (processed by Stripe), only `notes` may be updated; any other field returns a `400`.\n\nUpdating `amount` may fail with a `400` if the new total would exceed the parent invoice/bill's outstanding balance. The parent document's `amountPaid`/`status` are recalculated automatically.\n","tags":["payments"],"parameters":[{"name":"payment_id","in":"path","description":"Payment record identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Payment updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payments_updatePayment_Response_200"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePaymentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePaymentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePaymentRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"payments_deletePayment","summary":"Delete Payment","description":"Delete a payment record by its own id — no invoice or bill id is required in the path.\n\nExternal payments (processed by Stripe) cannot be deleted — use a refund instead. Deleting a payment recalculates the parent invoice/bill's `amountPaid`/`status` automatically.\n","tags":["payments"],"parameters":[{"name":"payment_id","in":"path","description":"Payment record identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Payment deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePaymentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePaymentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePaymentRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/bills":{"get":{"operationId":"bills_listBills","summary":"List Bills","description":"Retrieve a paginated list of bills.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n","tags":["bills"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/BillsGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/BillsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/BillsGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of bills","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBillsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBillsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"bills_createBill","summary":"Create Bill","description":"Create a new bill.\n\nRequired fields:\n- `recordId`: Project ID (the project must exist first)\n- `calculationMethod`: Must be \"LINE_ITEMS\" or \"PERCENTAGE\"\n- `lineItems`: Array of at least one line item if calculationMethod is \"LINE_ITEMS\"\n- `percentage`: Percentage if calculationMethod is \"PERCENTAGE\"\n\n**Line item rules for bills:**\n- `unitCost` must be greater than 0 (strictly positive — bills represent vendor costs)\n- `unitPrice` may be negative (negative values represent discounts)\n\nOptional fields:\n- `dueDate`: ISO 8601 datetime string\n- `description`: Bill description\n- `issueDate`: ISO 8601 datetime string\n","tags":["bills"],"responses":{"201":{"description":"Bill created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bill"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/bills/{bill_id}":{"get":{"operationId":"bills_getBill","summary":"Get Bill","description":"Retrieve a specific bill by ID","tags":["bills"],"parameters":[{"name":"bill_id","in":"path","description":"Bill identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Bill details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bill"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBillRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBillRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"bills_updateBill","summary":"Update Bill","description":"Update an existing bill. Supports partial updates.\n\nUpdatable fields:\n- `calculationMethod`: Must be \"LINE_ITEMS\" or \"PERCENTAGE\"\n- `lineItems`: Array of line items if calculationMethod is \"LINE_ITEMS\"\n- `percentage`: Percentage if calculationMethod is \"PERCENTAGE\"\n- `dueDate`: ISO 8601 datetime string\n- `issueDate`: ISO 8601 datetime string\n- `description`: Bill description\n- `status`: Bill status\n","tags":["bills"],"parameters":[{"name":"bill_id","in":"path","description":"Bill identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Bill updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bill"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"bills_deleteBill","summary":"Delete Bill","description":"Delete a specific bill by ID.\n\nThe bill is automatically archived before deletion — no separate archive step is required.\n","tags":["bills"],"parameters":[{"name":"bill_id","in":"path","description":"Bill identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Bill deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteBillRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteBillRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/bills":{"get":{"operationId":"bills_getProjectBills","summary":"Get Project Bills","description":"Retrieve bills for a specific project.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n","tags":["bills"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdBillsGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdBillsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdBillsGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of bills for the project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectBillsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectBillsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectBillsRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/timesheets":{"get":{"operationId":"timesheets_list-timesheets","summary":"List Timesheets","description":"Retrieve a paginated list of timesheets (time entries).\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Sorting by last updated (`order_by`, default: desc)\n- Filter by `project_id` / `account_id` / `opportunity_id` (aliases — projects, accounts, and opportunities share the same underlying record), `work_order_id`, `user_id`, and `type`\n- Filter by the entry's own date range (`start_date`, `end_date`) or by last-updated time (`updated_after`, `updated_before`)\n\nArchived timesheets are excluded unless `include_archived=true` is passed.\n","tags":["Timesheets"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/TimesheetsGetParametersOrderBy","default":"asc"}},{"name":"project_id","in":"query","description":"Filter by project ID. Alias of account_id/opportunity_id.","required":false,"schema":{"type":"integer"}},{"name":"account_id","in":"query","description":"Filter by account ID. Alias of project_id/opportunity_id.","required":false,"schema":{"type":"integer"}},{"name":"opportunity_id","in":"query","description":"Filter by opportunity ID. Alias of project_id/account_id.","required":false,"schema":{"type":"integer"}},{"name":"work_order_id","in":"query","description":"Filter by work order ID.","required":false,"schema":{"type":"integer"}},{"name":"user_id","in":"query","description":"Filter by the worker the time entry is logged for.","required":false,"schema":{"type":"integer"}},{"name":"type","in":"query","description":"Filter by time entry type.","required":false,"schema":{"$ref":"#/components/schemas/TimesheetsGetParametersType"}},{"name":"status","in":"query","description":"Filter by processing status.","required":false,"schema":{"$ref":"#/components/schemas/TimesheetsGetParametersStatus"}},{"name":"include_archived","in":"query","description":"Include archived timesheets in the results.","required":false,"schema":{"type":"boolean","default":false}},{"name":"start_date","in":"query","description":"Only return timesheets whose start time is at or after this timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"end_date","in":"query","description":"Only return timesheets whose end time is at or before this timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/TimesheetsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/TimesheetsGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of timesheets","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Timesheet"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-timesheetsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-timesheetsRequestUnauthorizedError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/List-timesheetsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"timesheets_createTimesheet","summary":"Create Timesheet","description":"Create a new timesheet (time entry) for a worker on a project, account, or opportunity (and optionally a work order).","tags":["Timesheets"],"responses":{"201":{"description":"Timesheet created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timesheet"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTimesheetRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTimesheetRequestUnauthorizedError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTimesheetRequestBadGatewayError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimesheetCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/timesheets/{timesheet_id}":{"get":{"operationId":"timesheets_getTimesheet","summary":"Get Timesheet","description":"Retrieve a specific timesheet by ID. Returns 404 if archived unless `include_archived=true` is passed.","tags":["Timesheets"],"parameters":[{"name":"timesheet_id","in":"path","description":"The timesheet ID.","required":true,"schema":{"type":"integer"}},{"name":"include_archived","in":"query","description":"Return the timesheet even if it has been archived.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Timesheet details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timesheet"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTimesheetRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTimesheetRequestNotFoundError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTimesheetRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"timesheets_updateTimesheet","summary":"Update Timesheet","description":"Update a timesheet's fields, and/or archive or unarchive it.\n\nSet `isArchived` to `true`/`false` to archive/unarchive the timesheet; this is applied independently of any other fields present in the same request.\n","tags":["Timesheets"],"parameters":[{"name":"timesheet_id","in":"path","description":"The timesheet ID.","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Timesheet updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timesheet"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTimesheetRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTimesheetRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTimesheetRequestNotFoundError"}}}},"502":{"description":"Bad gateway — an upstream service request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTimesheetRequestBadGatewayError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimesheetUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"timesheets_deleteTimesheet","summary":"Delete Timesheet","description":"Delete a timesheet (time entry) by ID.","tags":["Timesheets"],"parameters":[{"name":"timesheet_id","in":"path","description":"The timesheet ID.","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Timesheet deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteTimesheetRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteTimesheetRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/reminders":{"get":{"operationId":"reminders_getProjectReminders","summary":"Get Project Reminders","description":"Retrieve reminders for a specific project.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Completion filter (`is_completed`)\n","tags":["reminders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersGetParametersUpdatedBefore"}},{"name":"is_completed","in":"query","description":"Filter by completion status","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of reminders for the project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectRemindersRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProjectRemindersRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"reminders_createProjectReminder","summary":"Create Project Reminder","description":"Create a new reminder associated with a project.","tags":["reminders"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Reminder created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reminder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectReminderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectReminderRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/reminders":{"get":{"operationId":"reminders_getOpportunityReminders","summary":"Get Opportunity Reminders","description":"Retrieve reminders for a specific opportunity.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Completion filter (`is_completed`)\n","tags":["reminders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersGetParametersUpdatedBefore"}},{"name":"is_completed","in":"query","description":"Filter by completion status","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of reminders for the opportunity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityRemindersRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityRemindersRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"reminders_createOpportunityReminder","summary":"Create Opportunity Reminder","description":"Create a new reminder associated with an opportunity.","tags":["reminders"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Reminder created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reminder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityReminderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityReminderRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/reminders":{"get":{"operationId":"reminders_getAccountReminders","summary":"Get Account Reminders","description":"Retrieve reminders for a specific account.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n- Completion filter (`is_completed`)\n","tags":["reminders"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdRemindersGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdRemindersGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/AccountsAccountIdRemindersGetParametersUpdatedBefore"}},{"name":"is_completed","in":"query","description":"Filter by completion status","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of reminders for the account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountRemindersRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccountRemindersRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"reminders_createAccountReminder","summary":"Create Account Reminder","description":"Create a new reminder associated with an account.","tags":["reminders"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Reminder created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reminder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountReminderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountReminderRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/reminders/{reminder_id}":{"get":{"operationId":"reminders_getReminder","summary":"Get Reminder","description":"Retrieve a specific reminder by ID.","tags":["reminders"],"parameters":[{"name":"reminder_id","in":"path","description":"Reminder identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Reminder details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reminder"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetReminderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetReminderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"reminders_updateReminder","summary":"Update Reminder","description":"Update an existing reminder.","tags":["reminders"],"parameters":[{"name":"reminder_id","in":"path","description":"Reminder identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Reminder updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reminder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReminderRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReminderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReminderRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReminderUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"reminders_deleteReminder","summary":"Delete Reminder","description":"Delete a specific reminder by ID.","tags":["reminders"],"parameters":[{"name":"reminder_id","in":"path","description":"Reminder identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Reminder deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteReminderRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteReminderRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/appointments":{"get":{"operationId":"appointments_getOpportunityAppointments","summary":"Get Opportunity Appointments","description":"Retrieve appointments for a specific opportunity.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Sorting (`order_by`)\n","tags":["appointments"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"order_by","in":"query","description":"Sort order for results","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsGetParametersOrderBy","default":"asc"}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsGetParametersUpdatedBefore"}}],"responses":{"200":{"description":"List of appointments for the opportunity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppointmentListResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityAppointmentsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOpportunityAppointmentsRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"appointments_createOpportunityAppointment","summary":"Create Opportunity Appointment","description":"Create a new appointment associated with an opportunity.","tags":["appointments"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Appointment created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityAppointmentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityAppointmentRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppointmentCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/appointments/{appointment_id}":{"get":{"operationId":"appointments_getAppointment","summary":"Get Appointment","description":"Retrieve a specific appointment by ID.","tags":["appointments"],"parameters":[{"name":"appointment_id","in":"path","description":"Appointment identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Appointment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAppointmentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAppointmentRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"appointments_updateAppointment","summary":"Update Appointment","description":"Update an existing appointment.","tags":["appointments"],"parameters":[{"name":"appointment_id","in":"path","description":"Appointment identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Appointment updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAppointmentRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAppointmentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAppointmentRequestNotFoundError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppointmentUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"appointments_deleteAppointment","summary":"Delete Appointment","description":"Delete a specific appointment by ID.","tags":["appointments"],"parameters":[{"name":"appointment_id","in":"path","description":"Appointment identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Appointment deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAppointmentRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAppointmentRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/calls":{"get":{"operationId":"calls_listCalls","summary":"List Calls","description":"Retrieve a paginated list of calls across your whole company, including calls logged on\nprojects, opportunities and accounts. Each call has `projectId`, `opportunityId` or\n`accountId` set to the record it's logged on (all three are `null` for calls not yet\nlinked to a record).\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Date filtering (`updated_after`, `updated_before`)\n- Filtering by `outcome`, `reason` and `disposition`\n- Sorting by creation time (`order_by`, newest first by default)\n","tags":["calls"],"parameters":[{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"updated_after","in":"query","description":"Filter items updated after this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/CallsGetParametersUpdatedAfter"}},{"name":"updated_before","in":"query","description":"Filter items updated before this timestamp (ISO 8601). Also matches records whose custom property values changed within the window.","required":false,"schema":{"$ref":"#/components/schemas/CallsGetParametersUpdatedBefore"}},{"name":"order_by","in":"query","description":"Sort by creation time. Defaults to newest first.","required":false,"schema":{"$ref":"#/components/schemas/CallsGetParametersOrderBy","default":"desc"}},{"name":"outcome","in":"query","description":"Only return calls with this outcome","required":false,"schema":{"$ref":"#/components/schemas/CallsGetParametersOutcome"}},{"name":"reason","in":"query","description":"Only return calls with exactly this reason (see `GET /calls/classification-options`)","required":false,"schema":{"type":"string","maxLength":255}},{"name":"disposition","in":"query","description":"Only return calls with exactly this disposition (see `GET /calls/classification-options`)","required":false,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"List of calls","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CallListItem"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallsRequestUnauthorizedError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallsRequestInternalServerError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/calls/classification-options":{"get":{"operationId":"calls_listCallClassificationOptions","summary":"List Call Classification Options","description":"Lists your company's call reasons and dispositions, ordered by type and then position.\nA call's `reason` and `disposition` hold an option's `name`. Options are company-defined,\nand renaming or deleting one does not change calls already logged with it.\n","tags":["calls"],"parameters":[{"name":"type","in":"query","description":"Only return options of this type. Omit to return both.","required":false,"schema":{"$ref":"#/components/schemas/CallsClassificationOptionsGetParametersType"}}],"responses":{"200":{"description":"List of call classification options","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CallClassificationOption"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallClassificationOptionsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallClassificationOptionsRequestUnauthorizedError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallClassificationOptionsRequestInternalServerError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCallClassificationOptionsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/projects/{project_id}/calls":{"get":{"operationId":"calls_listProjectCalls","summary":"List Project Calls","description":"Retrieve all phone call records associated with a project","tags":["calls"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of call records","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Call"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectCallsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectCallsRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectCallsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"calls_createProjectCall","summary":"Create Project Call","description":"Create a new phone call record associated with a project","tags":["calls"],"parameters":[{"name":"project_id","in":"path","description":"Project identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Call record created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectCallRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectCallRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/opportunities/{opportunity_id}/calls":{"get":{"operationId":"calls_listOpportunityCalls","summary":"List Opportunity Calls","description":"Retrieve all phone call records associated with an opportunity\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["calls"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of call records","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Call"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOpportunityCallsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOpportunityCallsRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOpportunityCallsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"calls_createOpportunityCall","summary":"Create Opportunity Call","description":"Create a new phone call record associated with an opportunity\n\n**Note:** The `/requests` path is an alias for `/opportunities` and will continue to work until users are individually notified and migrated.\n","tags":["calls"],"parameters":[{"name":"opportunity_id","in":"path","description":"Opportunity identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Call record created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityCallRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpportunityCallRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/accounts/{account_id}/calls":{"get":{"operationId":"calls_listAccountCalls","summary":"List Account Calls","description":"Retrieve all phone call records associated with an account\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["calls"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of call records","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Call"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAccountCallsRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAccountCallsRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAccountCallsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"calls_createAccountCall","summary":"Create Account Call","description":"Create a new phone call record associated with an account\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n","tags":["calls"],"parameters":[{"name":"account_id","in":"path","description":"Account identifier","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Call record created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountCallRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountCallRequestUnauthorizedError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/catalog-items":{"get":{"operationId":"catalogItems_listCatalogItems","summary":"List Catalog Items","description":"Lists catalog items (products and services).\n","tags":["catalogItems"],"responses":{"200":{"description":"List of catalog items","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogItem"}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCatalogItemsRequestUnauthorizedError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCatalogItemsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"catalogItems_createCatalogItem","summary":"Create Catalog Item","description":"Create a new catalog item.","tags":["catalogItems"],"responses":{"201":{"description":"Catalog item created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogItem"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCatalogItemRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCatalogItemRequestUnauthorizedError"}}}},"502":{"description":"The catalog item was created, but could not be read back afterwards, so the full response (including any `unit` and `measurements` links) is unavailable. Use the returned `id` to fetch it with `GET /catalog-items/{catalog_item_id}` — do not retry this POST, which would create a duplicate. `id` is omitted only when the upstream write response itself contained no usable id.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCatalogItemRequestBadGatewayError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogItemCreate"}}}},"security":[{"ApiKeyAuth":[]}]}},"/catalog-categories":{"get":{"operationId":"catalogItems_listCatalogCategories","summary":"List Catalog Categories","description":"Lists the valid category codes for catalog items, grouped by PRODUCT/SERVICE, along with the\navailable trade groups. Use these values to populate `category` and `tradeGroup` on\nPOST/PATCH /catalog-items.\n","tags":["catalogItems"],"responses":{"200":{"description":"Available catalog categories and trade groups","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogCategoriesResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCatalogCategoriesRequestUnauthorizedError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/catalog-units":{"get":{"operationId":"catalogItems_listCatalogUnits","summary":"List Catalog Units","description":"Lists the units of measure available to your company (e.g. Each, Square Feet, Linear Feet).\nUse these IDs when setting `unitId` on a catalog item, or when linking measurements.\n","tags":["catalogItems"],"parameters":[{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"List of catalog units","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogUnit"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCatalogUnitsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCatalogUnitsRequestUnauthorizedError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCatalogUnitsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/catalog-items/{catalog_item_id}":{"get":{"operationId":"catalogItems_getCatalogItem","summary":"Get Catalog Item","description":"Retrieve a specific catalog item by ID.","tags":["catalogItems"],"parameters":[{"name":"catalog_item_id","in":"path","description":"Catalog item identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Catalog item details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogItem"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogItemRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogItemRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogItemRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogItemRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"patch":{"operationId":"catalogItems_updateCatalogItem","summary":"Update Catalog Item","description":"Update an existing catalog item.\n","tags":["catalogItems"],"parameters":[{"name":"catalog_item_id","in":"path","description":"Catalog item identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Catalog item updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogItem"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCatalogItemRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCatalogItemRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCatalogItemRequestNotFoundError"}}}},"502":{"description":"The catalog item was updated, but could not be read back afterwards, so the full response (including any `unit` and `measurements` links) is unavailable. The update itself did apply. If this request did not archive the item, fetch the current state with `GET /catalog-items/{catalog_item_id}`. If it set `isArchived: true`, that endpoint (and the list endpoint) excludes archived catalog items by design, so it will return 404 even though the archive succeeded — treat that 404 as confirmation, not a failure, and do not retry the PATCH.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCatalogItemRequestBadGatewayError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogItemUpdate"}}}},"security":[{"ApiKeyAuth":[]}]},"delete":{"operationId":"catalogItems_deleteCatalogItem","summary":"Delete Catalog Item","description":"Archives the catalog item (soft delete). The item is marked as archived and will no longer appear in list or lookup responses, but is not permanently removed.\n","tags":["catalogItems"],"parameters":[{"name":"catalog_item_id","in":"path","description":"Catalog item identifier","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Catalog item archived (No Content)","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCatalogItemRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCatalogItemRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCatalogItemRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCatalogItemRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/catalog-units/{catalog_unit_id}":{"get":{"operationId":"catalogItems_getCatalogUnit","summary":"Get Catalog Unit","description":"Retrieve a specific catalog unit by ID.","tags":["catalogItems"],"parameters":[{"name":"catalog_unit_id","in":"path","description":"Catalog unit identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Catalog unit details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogUnit"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogUnitRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogUnitRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogUnitRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogUnitRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/measurements":{"get":{"operationId":"measurements_listMeasurements","summary":"List Measurements","description":"Lists the measurements (and sub-measurements) available to your company. Use these IDs when\nsetting `measurementIds` on a catalog item. A \"sub-measurement\" is a measurement with\n`type: SUB_CALCULATION`.\n","tags":["measurements"],"parameters":[{"name":"type","in":"query","description":"Filter by measurement type","required":false,"schema":{"$ref":"#/components/schemas/MeasurementsGetParametersType"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"List of measurements","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Measurement"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMeasurementsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMeasurementsRequestUnauthorizedError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMeasurementsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/measurements/{measurement_id}":{"get":{"operationId":"measurements_getMeasurement","summary":"Get Measurement","description":"Retrieve a specific measurement (or sub-measurement) by ID.","tags":["measurements"],"parameters":[{"name":"measurement_id","in":"path","description":"Measurement identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Measurement details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Measurement"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMeasurementRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMeasurementRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMeasurementRequestNotFoundError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMeasurementRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/labels":{"get":{"operationId":"labels_listLabels","summary":"List Labels","description":"Lists active labels for your company. Labels can be applied to work orders (`WORK` type) or assets (`ASSET` type).\nThe company is implied by the API key.\n","tags":["labels"],"parameters":[{"name":"type","in":"query","description":"Filter by label type","required":false,"schema":{"$ref":"#/components/schemas/LabelsGetParametersType"}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"List of labels","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Label"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLabelsRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLabelsRequestUnauthorizedError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLabelsRequestInternalServerError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLabelsRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"labels_createLabel","summary":"Create Label","description":"Creates a new label for the company. Use `WORK` for work-order labels or `ASSET` for asset labels.\n","tags":["labels"],"responses":{"201":{"description":"Label created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Label"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLabelRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLabelRequestUnauthorizedError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLabelRequestInternalServerError"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLabelRequest"}}}},"security":[{"ApiKeyAuth":[]}]}},"/labels/{label_id}":{"get":{"operationId":"labels_getLabel","summary":"Get Label","description":"Retrieve a single label by ID.","tags":["labels"],"parameters":[{"name":"label_id","in":"path","description":"Label identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Label retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Label"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetLabelRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetLabelRequestNotFoundError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetLabelRequestInternalServerError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetLabelRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/taxes":{"get":{"operationId":"taxes_listTaxes","summary":"List Taxes","description":"Lists tax rates configured for your company. Use these IDs when assigning taxes to quotes, invoices, and other financial documents.\nThe company is implied by the API key; `companyId` is not returned on each item.\n","tags":["taxes"],"parameters":[{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","description":"Number of items per page (max 100)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"List of company taxes (paginated)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompanyTax"}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTaxesRequestBadRequestError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTaxesRequestUnauthorizedError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTaxesRequestInternalServerError"}}}},"502":{"description":"Bad Gateway — downstream GraphQL service returned errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTaxesRequestBadGatewayError"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/users":{"get":{"operationId":"users_listUsers","summary":"List Users","description":"Retrieve a list of users","tags":["users"],"parameters":[{"name":"email","in":"query","description":"Email of the user to search for","required":false,"schema":{"type":"string"}},{"name":"id","in":"query","description":"ID of the user to search for","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"List of users","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/User"}}}}}},"security":[{"ApiKeyAuth":[]}]},"post":{"operationId":"users_inviteUser","summary":"Invite User","description":"Invite a new user to the organization","tags":["users"],"responses":{"201":{"description":"User invited successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Users_inviteUser_Response_201"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserInvite"}}}},"security":[{"ApiKeyAuth":[]}]}},"/roles":{"get":{"operationId":"users_listRoles","summary":"List Roles","description":"Retrieve available user roles","tags":["users"],"responses":{"200":{"description":"List of roles","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Role"}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/teams":{"get":{"operationId":"users_listTeams","summary":"List Teams","description":"Retrieve available teams","tags":["users"],"responses":{"200":{"description":"List of teams","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Team"}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/properties":{"get":{"operationId":"properties_listProperties","summary":"List Properties","description":"Retrieve list of properties organized by record type.\n\nWhen `record_type` is **omitted**, the response includes all keys: `account`, `opportunity`,\n`project`, `vendor`, `ahj`, and `utility` — plus the deprecated alias keys `client` and `request`.\n\nWhen `record_type` is **provided**, the response contains only the requested key(s). Filtering\nby `account` or `client` returns both `account` and `client` (identical data); filtering by\n`opportunity` or `request` returns both `opportunity` and `request` (identical data).\n\n> **Note:** `client` and `request` are deprecated aliases for `account` and `opportunity` respectively. They will continue to be returned until all users have migrated.\n\n> **AHJ:** The `ahj` key returns only customer-defined custom properties (`isCustom: true`). Standard built-in AHJ fields are not included here — they are exposed directly on the AHJ object instead, and are not updatable via the public API.\n\n> **Utility:** The `utility` key returns only customer-defined custom properties (`isCustom: true`). Standard built-in utility fields are not included here — they are exposed directly on the utility object instead, and are not updatable via the public API.\n\n> **keyName semantics:** For built-in properties (`isCustom: false`), `keyName` is the public\n> field name used on the record's create/update/read endpoints (e.g. `address`, `isActive`,\n> `createdAt`) — not the internal storage key. Use the `readOnly` flag to tell which built-in\n> fields can be sent on create/update (`readOnly: false`) versus which are system/derived\n> fields you can only read (`readOnly: true`). For custom properties, `keyName` is the key\n> used under the `custom` object, and `readOnly` is always `false`.\n","tags":["properties"],"parameters":[{"name":"record_type","in":"query","description":"Filter by record type. Can also be supplied as a comma-separated list\n(`?record_type=project,vendor`) or repeated (`?record_type=project&record_type=vendor`)\nto request multiple types in one call.\n\nWhen omitted, the response includes every record-type key. When supplied, the response\nincludes only the requested key(s) — plus the matching deprecated alias key where\napplicable (`account` ↔ `client`, `opportunity` ↔ `request`).\n\n> **Note:** `client` and `request` are deprecated aliases for `account` and `opportunity` respectively. They are still accepted as input.\n","required":false,"schema":{"$ref":"#/components/schemas/PropertiesGetParametersRecordType"}}],"responses":{"200":{"description":"List of properties","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Properties_listProperties_Response_200"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/workflows":{"get":{"operationId":"workflows_listWorkflows","summary":"List Workflows","description":"Retrieve a paginated list of workflows.\n\nSupports:\n- Pagination (`page_size`, `page`)\n- Sorting (`order_by`, default: asc)\n","tags":["workflows"],"parameters":[{"name":"page","in":"query","description":"Page number","required":false,"schema":{"type":"integer"}},{"name":"page_size","in":"query","description":"Number of items per page","required":false,"schema":{"type":"integer"}},{"name":"order_by","in":"query","description":"Field to sort by","required":false,"schema":{"type":"string"}},{"name":"include_archived","in":"query","description":"Whether to include archived (inactive) records in the response. By default only active records are returned.","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of workflows","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Workflow"}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/workflows/{workflow_id}":{"get":{"operationId":"workflows_getWorkflow","summary":"Get Workflow","description":"Retrieve details of a specific workflow","tags":["workflows"],"parameters":[{"name":"workflow_id","in":"path","description":"Workflow identifier","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Workflow details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workflow"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWorkflowRequestUnauthorizedError"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWorkflowRequestNotFoundError"}}}}},"security":[{"ApiKeyAuth":[]}]}}},"tags":[{"name":"projects"},{"name":"opportunities"},{"name":"accounts"},{"name":"sites"},{"name":"assets"},{"name":"vendors"},{"name":"AHJs","description":"Authorities Having Jurisdiction (AHJs). Read access to the global jurisdiction catalog (sourced from US Census TIGER). List by name/state/type, or pass `lat`+`lng` to the list endpoint to find the AHJ covering a point. Most fields are read-only catalog data; only custom property values can be updated.\n"},{"name":"Utilities","description":"Utilities. Read access to the global utility catalog (sourced from HIFLD). List by name/holding company/state/ownership type, or pass `lat`+`lng` to the list endpoint to find the utility covering a point. Most fields are read-only catalog data; only custom property values can be updated.\n"},{"name":"contacts"},{"name":"notes"},{"name":"workOrders"},{"name":"files"},{"name":"folders"},{"name":"lineItems"},{"name":"formTemplates"},{"name":"forms"},{"name":"quotes"},{"name":"invoices"},{"name":"payments"},{"name":"bills"},{"name":"Timesheets","description":"Timesheets (time entries) logged by workers against a project and, optionally, a task. Create and update time entries, and archive/unarchive them via `PATCH` with `isArchived`.\n"},{"name":"reminders"},{"name":"appointments"},{"name":"calls"},{"name":"catalogItems"},{"name":"measurements"},{"name":"labels"},{"name":"taxes"},{"name":"users"},{"name":"properties"},{"name":"workflows"}],"servers":[{"url":"https://api.coperniq.io/v1","description":"Production server"}],"components":{"schemas":{"ProjectsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsGetParametersUpdatedAfter"},"ProjectsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsGetParametersUpdatedBefore"},"ProjectsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ProjectsGetParametersOrderBy"},"UserSummary":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"email":{"type":["string","null"],"format":"email"},"avatarUrl":{"type":["string","null"]}},"description":"Minimal user representation used in responses","title":"UserSummary"},"TradeType":{"type":"string","enum":["EV Charger","Solar","Storage","Boiler","Chiller","Ductwork","HVAC","Refrigeration","Electrical","Generator","Lighting","Gas Line","Plumbing","Water Filtration","Water Heater","Communications","Electronic Safety & Security","Integrated Automation","Insulation","Gutters","Roofing","Siding","Windows","Drywall","General Contracting","Home Improvement","Landscaping","R&R (Remove & Reinstall)","Tenant Improvement","Tree Cutting"],"description":"Trade type. Matching is case-insensitive on input. `D&R` and `R&R (Repair and Renovation)` are accepted as legacy aliases and normalized to `R&R (Remove & Reinstall)`.","title":"TradeType"},"ProjectWithPhaseInstancesProjectManager":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"description":"Assigned project manager, `null` when unset. Same shape as `owner` and `salesRep`.","title":"ProjectWithPhaseInstancesProjectManager"},"ProjectStatus":{"type":"string","enum":["ACTIVE","ON_HOLD","CANCELLED","COMPLETED"],"description":"Status of the project:\n* `ACTIVE` - Project is active and in progress\n* `ON_HOLD` - Project is temporarily paused\n* `CANCELLED` - Project has been cancelled\n* `COMPLETED` - Project has been completed\n","title":"ProjectStatus"},"ProjectWithPhaseInstancesStageSlaStatus":{"type":"string","enum":["VIOLATED","NON_VIOLATED"],"description":"Current SLA violation status","title":"ProjectWithPhaseInstancesStageSlaStatus"},"ProjectWithPhaseInstancesStage":{"type":"object","properties":{"id":{"type":"integer","description":"Stage identifier"},"name":{"type":"string","description":"Stage name"},"type":{"type":"string","description":"Stage type"},"scope":{"type":"string","description":"Stage scope"},"redSla":{"type":"integer","description":"Red SLA threshold in days"},"yellowSla":{"type":"integer","description":"Yellow SLA threshold in days"},"timeInStageDays":{"type":"integer","description":"Number of days in current stage"},"slaStatus":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesStageSlaStatus","description":"Current SLA violation status"}},"description":"Current stage information (Workflows 1.0).\n\nThis object is present only for records still using the original Stage-based workflow engine.\nWhen the project is managed by Workflows 2.0 (Phase engine) the `stage` object and\nrelated fields (`stageId`, `timeInStageDays`, `slaStatus`) are omitted.\n","title":"ProjectWithPhaseInstancesStage"},"ProjectWithPhaseInstancesPhaseSlaStatus":{"type":"string","enum":["VIOLATED","NON_VIOLATED"],"description":"Current SLA violation status for the phase","title":"ProjectWithPhaseInstancesPhaseSlaStatus"},"ProjectWithPhaseInstancesPhase":{"type":"object","properties":{"instanceId":{"type":"integer","description":"Phase instance identifier"},"templateId":{"type":"integer","description":"Phase template identifier"},"name":{"type":"string","description":"Phase name"},"status":{"type":"string","description":"Current phase status"},"type":{"type":"string","description":"Phase type"},"redSla":{"type":"integer","description":"Red SLA threshold in days (from template)"},"yellowSla":{"type":"integer","description":"Yellow SLA threshold in days (from template)"},"timeInStageDays":{"type":"integer","description":"Number of days in current phase (mirrors `timeInStageDays` metric)"},"slaStatus":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesPhaseSlaStatus","description":"Current SLA violation status for the phase"},"startedAt":{"type":["string","null"],"format":"date-time","description":"When the current phase started. Present on `GET /projects/{project_id}` and on lists with `include_phases=true`."},"completedAt":{"type":["string","null"],"format":"date-time","description":"When the current phase completed. Present on `GET /projects/{project_id}` and on lists with `include_phases=true`."}},"description":"Current phase information (Workflows 2.0).\n\nThis object replaces `stage` when a project is attached to the Phase-based workflow engine.\nIf the project is still on Workflows 1.0 this object will be omitted.\nOnly populated on GET (list, search, get by id) — omitted on create/update responses.\n","title":"ProjectWithPhaseInstancesPhase"},"ProjectWithPhaseInstancesPhaseTimelineItems":{"type":"object","properties":{"phaseTemplateId":{"type":"integer"},"startedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the project entered this phase template"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the project exited this phase template"}},"title":"ProjectWithPhaseInstancesPhaseTimelineItems"},"ContactRef":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"title":{"type":["string","null"],"description":"Contact title (e.g. job title)"},"description":{"type":["string","null"]},"emails":{"type":"array","items":{"type":"string"}},"phones":{"type":"array","items":{"type":"string"}},"isPrimary":{"type":"boolean","description":"True for the primary contact (the first contact in the list). At most one contact is primary."}},"title":"ContactRef"},"ProjectWithPhaseInstancesPhaseInstancesItemsStatus":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"],"title":"ProjectWithPhaseInstancesPhaseInstancesItemsStatus"},"PhaseTemplateSummary":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string"},"redSla":{"type":["integer","null"]},"yellowSla":{"type":["integer","null"]}},"title":"PhaseTemplateSummary"},"ProjectWithPhaseInstancesPhaseInstancesItems":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesPhaseInstancesItemsStatus"},"position":{"type":"integer"},"type":{"type":"string"},"phaseTemplateId":{"type":"integer"},"phaseTemplate":{"$ref":"#/components/schemas/PhaseTemplateSummary"},"startedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the phase instance started"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the phase instance completed"}},"title":"ProjectWithPhaseInstancesPhaseInstancesItems"},"ProjectWithPhaseInstances":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent update to the record, including changes to its custom property values."},"title":{"type":"string","description":"Record title/name"},"description":{"type":["string","null"],"description":"Record description"},"address":{"type":"array","items":{"type":"string"},"description":"Record location/address"},"isActive":{"type":"boolean","description":"Whether the record is active"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"number":{"type":"integer","description":"Record number (e.g., 1234)"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who created the record. Null when the record was created by a non-user actor (e.g. automation or a contact)."},"updatedBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who last edited a field on the record, derived from the changelog. Null when the record has never been edited or the last edit was made by a non-user actor. Returned by single-record GET only; list and search responses omit it."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types"},"value":{"type":["string","null"],"title":"float","description":"Project value"},"size":{"type":["string","null"],"title":"float","description":"Project size"},"workflowId":{"type":["integer","null"],"description":"Associated workflow ID"},"accountId":{"type":["integer","null"],"description":"Associated account ID"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"salesRepId":{"type":["integer","null"],"description":"ID of the assigned sales rep"},"projectManagerId":{"type":["integer","null"],"description":"ID of the assigned project manager"},"projectManager":{"oneOf":[{"$ref":"#/components/schemas/ProjectWithPhaseInstancesProjectManager"},{"type":"null"}],"description":"Assigned project manager, `null` when unset. Same shape as `owner` and `salesRep`."},"status":{"$ref":"#/components/schemas/ProjectStatus"},"stage":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesStage","description":"Current stage information (Workflows 1.0).\n\nThis object is present only for records still using the original Stage-based workflow engine.\nWhen the project is managed by Workflows 2.0 (Phase engine) the `stage` object and\nrelated fields (`stageId`, `timeInStageDays`, `slaStatus`) are omitted.\n"},"phase":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesPhase","description":"Current phase information (Workflows 2.0).\n\nThis object replaces `stage` when a project is attached to the Phase-based workflow engine.\nIf the project is still on Workflows 1.0 this object will be omitted.\nOnly populated on GET (list, search, get by id) — omitted on create/update responses.\n"},"phaseTimeline":{"type":"array","items":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesPhaseTimelineItems"},"description":"Only present on `GET /projects` and `/projects/search` when `entered_phase_id`/`exited_phase_id` is used to filter the results. Contains the project's full phase-transition history (not just the matched phase) in compact form — use `GET /projects/{project_id}` for the complete `phaseInstances` with names, positions, and SLA info.\n"},"lineItemsUpdatedAt":{"type":["string","null"],"format":"date-time","description":"Only present on `GET /projects` and `/projects/search` when `include_line_item_updates=true` is passed together with `updated_after` and/or `updated_before`. The most recent `updatedAt` among the project's own scope line items (estimate/scope items; line items on quotes/invoices are excluded). `null` if the project has no scope line items. Useful for telling whether a row matched the date window via its own `updatedAt` or via a line item edit.\n"},"workflowName":{"type":"string","description":"Name of the associated workflow.\n"},"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactRef"},"description":"Contacts associated with this project (independent of, and not inherited from, the parent account's contacts). Set on create or update via the `contacts` request field. On GET requests, only populated when include_contacts=true is passed. Always populated on POST (create) and PATCH (update) responses. Ordered with the primary contact first, capped at 20 contacts."},"phaseInstances":{"type":"array","items":{"$ref":"#/components/schemas/ProjectWithPhaseInstancesPhaseInstancesItems"},"description":"Ordered list of phase instances for the project. Returned by `GET /projects/{project_id}`, and on lists and search with `include_phases=true`."}},"title":"ProjectWithPhaseInstances"},"ProjectsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsGetResponsesContentApplicationJsonSchemaCode"},"ListProjectsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListProjectsRequestBadRequestError"},"ListProjectsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectsRequestUnauthorizedError"},"ProjectsSearchGetParametersOp1":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"ProjectsSearchGetParametersOp1"},"ProjectsSearchGetParametersLogic":{"type":"string","enum":["and","or"],"default":"and","title":"ProjectsSearchGetParametersLogic"},"ProjectsSearchGetParametersOp2":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"ProjectsSearchGetParametersOp2"},"ProjectsSearchGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsSearchGetParametersUpdatedAfter"},"ProjectsSearchGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsSearchGetParametersUpdatedBefore"},"ProjectsSearchGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ProjectsSearchGetParametersOrderBy"},"ProjectsSearchGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsSearchGetResponsesContentApplicationJsonSchemaCode"},"SearchProjectsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsSearchGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"SearchProjectsRequestBadRequestError"},"SearchProjectsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsSearchGetResponsesContentApplicationJsonSchemaCode"}},"title":"SearchProjectsRequestUnauthorizedError"},"ProjectsProjectIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdGetResponsesContentApplicationJsonSchemaCode"},"GetProjectRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectRequestUnauthorizedError"},"GetProjectRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectRequestNotFoundError"},"ProjectsPostParametersMatchBy":{"type":"string","enum":["title","primaryEmail","primaryPhone","address"],"default":"title","title":"ProjectsPostParametersMatchBy"},"ProjectsPostParametersMatchFoundStrategy":{"type":"string","enum":["skip","replace","enrich"],"default":"skip","description":"- skip: Return existing record without changes\n- replace: Replace existing record with new data\n- enrich: Update only empty fields in existing record\n","title":"ProjectsPostParametersMatchFoundStrategy"},"ProjectCreate":{"type":"object","properties":{"title":{"type":"string","description":"Project title/name"},"description":{"type":["string","null"],"description":"Project description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full project location/address."},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types, defaults to 'Solar'"},"accountId":{"type":"integer","description":"ID of associated account"},"workflowId":{"type":"integer","description":"ID of associated workflow"},"value":{"type":"number","format":"double","description":"Project value"},"size":{"type":"number","format":"double","description":"Project size"},"status":{"$ref":"#/components/schemas/ProjectStatus"},"primaryEmail":{"type":"string","format":"email","description":"Primary contact email"},"primaryPhone":{"type":"string","description":"Primary contact phone"},"contacts":{"type":"array","items":{"type":"integer"},"description":"Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts. The first ID in the array is treated as the primary contact."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"required":["title","address"],"title":"ProjectCreate"},"ProjectProjectManager":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"description":"Assigned project manager, `null` when unset. Same shape as `owner` and `salesRep`.","title":"ProjectProjectManager"},"ProjectStageSlaStatus":{"type":"string","enum":["VIOLATED","NON_VIOLATED"],"description":"Current SLA violation status","title":"ProjectStageSlaStatus"},"ProjectStage":{"type":"object","properties":{"id":{"type":"integer","description":"Stage identifier"},"name":{"type":"string","description":"Stage name"},"type":{"type":"string","description":"Stage type"},"scope":{"type":"string","description":"Stage scope"},"redSla":{"type":"integer","description":"Red SLA threshold in days"},"yellowSla":{"type":"integer","description":"Yellow SLA threshold in days"},"timeInStageDays":{"type":"integer","description":"Number of days in current stage"},"slaStatus":{"$ref":"#/components/schemas/ProjectStageSlaStatus","description":"Current SLA violation status"}},"description":"Current stage information (Workflows 1.0).\n\nThis object is present only for records still using the original Stage-based workflow engine.\nWhen the project is managed by Workflows 2.0 (Phase engine) the `stage` object and\nrelated fields (`stageId`, `timeInStageDays`, `slaStatus`) are omitted.\n","title":"ProjectStage"},"ProjectPhaseSlaStatus":{"type":"string","enum":["VIOLATED","NON_VIOLATED"],"description":"Current SLA violation status for the phase","title":"ProjectPhaseSlaStatus"},"ProjectPhase":{"type":"object","properties":{"instanceId":{"type":"integer","description":"Phase instance identifier"},"templateId":{"type":"integer","description":"Phase template identifier"},"name":{"type":"string","description":"Phase name"},"status":{"type":"string","description":"Current phase status"},"type":{"type":"string","description":"Phase type"},"redSla":{"type":"integer","description":"Red SLA threshold in days (from template)"},"yellowSla":{"type":"integer","description":"Yellow SLA threshold in days (from template)"},"timeInStageDays":{"type":"integer","description":"Number of days in current phase (mirrors `timeInStageDays` metric)"},"slaStatus":{"$ref":"#/components/schemas/ProjectPhaseSlaStatus","description":"Current SLA violation status for the phase"},"startedAt":{"type":["string","null"],"format":"date-time","description":"When the current phase started. Present on `GET /projects/{project_id}` and on lists with `include_phases=true`."},"completedAt":{"type":["string","null"],"format":"date-time","description":"When the current phase completed. Present on `GET /projects/{project_id}` and on lists with `include_phases=true`."}},"description":"Current phase information (Workflows 2.0).\n\nThis object replaces `stage` when a project is attached to the Phase-based workflow engine.\nIf the project is still on Workflows 1.0 this object will be omitted.\nOnly populated on GET (list, search, get by id) — omitted on create/update responses.\n","title":"ProjectPhase"},"ProjectPhaseTimelineItems":{"type":"object","properties":{"phaseTemplateId":{"type":"integer"},"startedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the project entered this phase template"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the project exited this phase template"}},"title":"ProjectPhaseTimelineItems"},"Project":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent update to the record, including changes to its custom property values."},"title":{"type":"string","description":"Record title/name"},"description":{"type":["string","null"],"description":"Record description"},"address":{"type":"array","items":{"type":"string"},"description":"Record location/address"},"isActive":{"type":"boolean","description":"Whether the record is active"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"number":{"type":"integer","description":"Record number (e.g., 1234)"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who created the record. Null when the record was created by a non-user actor (e.g. automation or a contact)."},"updatedBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who last edited a field on the record, derived from the changelog. Null when the record has never been edited or the last edit was made by a non-user actor. Returned by single-record GET only; list and search responses omit it."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types"},"value":{"type":["string","null"],"title":"float","description":"Project value"},"size":{"type":["string","null"],"title":"float","description":"Project size"},"workflowId":{"type":["integer","null"],"description":"Associated workflow ID"},"accountId":{"type":["integer","null"],"description":"Associated account ID"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"salesRepId":{"type":["integer","null"],"description":"ID of the assigned sales rep"},"projectManagerId":{"type":["integer","null"],"description":"ID of the assigned project manager"},"projectManager":{"oneOf":[{"$ref":"#/components/schemas/ProjectProjectManager"},{"type":"null"}],"description":"Assigned project manager, `null` when unset. Same shape as `owner` and `salesRep`."},"status":{"$ref":"#/components/schemas/ProjectStatus"},"stage":{"$ref":"#/components/schemas/ProjectStage","description":"Current stage information (Workflows 1.0).\n\nThis object is present only for records still using the original Stage-based workflow engine.\nWhen the project is managed by Workflows 2.0 (Phase engine) the `stage` object and\nrelated fields (`stageId`, `timeInStageDays`, `slaStatus`) are omitted.\n"},"phase":{"$ref":"#/components/schemas/ProjectPhase","description":"Current phase information (Workflows 2.0).\n\nThis object replaces `stage` when a project is attached to the Phase-based workflow engine.\nIf the project is still on Workflows 1.0 this object will be omitted.\nOnly populated on GET (list, search, get by id) — omitted on create/update responses.\n"},"phaseTimeline":{"type":"array","items":{"$ref":"#/components/schemas/ProjectPhaseTimelineItems"},"description":"Only present on `GET /projects` and `/projects/search` when `entered_phase_id`/`exited_phase_id` is used to filter the results. Contains the project's full phase-transition history (not just the matched phase) in compact form — use `GET /projects/{project_id}` for the complete `phaseInstances` with names, positions, and SLA info.\n"},"lineItemsUpdatedAt":{"type":["string","null"],"format":"date-time","description":"Only present on `GET /projects` and `/projects/search` when `include_line_item_updates=true` is passed together with `updated_after` and/or `updated_before`. The most recent `updatedAt` among the project's own scope line items (estimate/scope items; line items on quotes/invoices are excluded). `null` if the project has no scope line items. Useful for telling whether a row matched the date window via its own `updatedAt` or via a line item edit.\n"},"workflowName":{"type":"string","description":"Name of the associated workflow.\n"},"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactRef"},"description":"Contacts associated with this project (independent of, and not inherited from, the parent account's contacts). Set on create or update via the `contacts` request field. On GET requests, only populated when include_contacts=true is passed. Always populated on POST (create) and PATCH (update) responses. Ordered with the primary contact first, capped at 20 contacts."}},"title":"Project"},"ProjectsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectRequestBadRequestError"},"CreateProjectRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectRequestUnauthorizedError"},"ProjectUpdate":{"type":"object","properties":{"title":{"type":"string","description":"Project title/name"},"description":{"type":["string","null"],"description":"Project description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full project location/address."},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types"},"workflowId":{"type":"integer","description":"ID of associated workflow"},"phaseId":{"type":["integer","null"],"description":"ID of associated phase template"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"salesRepId":{"type":["integer","null"],"description":"ID of the assigned sales rep"},"projectManagerId":{"type":["integer","null"],"description":"ID of the assigned project manager"},"value":{"type":"number","format":"double","description":"Project value"},"size":{"type":"number","format":"double","description":"Project size"},"status":{"$ref":"#/components/schemas/ProjectStatus"},"primaryEmail":{"type":"string","format":"email","description":"Primary contact email"},"primaryPhone":{"type":"string","description":"Primary contact phone"},"contacts":{"type":"array","items":{"type":"integer"},"description":"Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts. The first ID in the array is treated as the primary contact."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"description":"All fields are optional. Changing account association is not supported via update — delete and re-create the project under the new account.\n","title":"ProjectUpdate"},"ProjectsProjectIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateProjectRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateProjectRequestBadRequestError"},"UpdateProjectRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateProjectRequestUnauthorizedError"},"UpdateProjectRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateProjectRequestNotFoundError"},"ProjectsProjectIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteProjectRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteProjectRequestUnauthorizedError"},"DeleteProjectRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteProjectRequestNotFoundError"},"OpportunitiesGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesGetParametersUpdatedAfter"},"OpportunitiesGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesGetParametersUpdatedBefore"},"OpportunitiesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"OpportunitiesGetParametersOrderBy"},"OpportunityStatus":{"type":"string","enum":["ACTIVE","ON_HOLD","WON","LOST"],"description":"Status of the opportunity:\n* `ACTIVE` - Opportunity is open\n* `ON_HOLD` - Opportunity is temporarily paused\n* `WON` - Opportunity was won\n* `LOST` - Opportunity was lost\n","title":"OpportunityStatus"},"OpportunityWithPhaseInstancesPhaseTimelineItems":{"type":"object","properties":{"phaseTemplateId":{"type":"integer"},"startedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the deal entered this phase template"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the deal exited this phase template"}},"title":"OpportunityWithPhaseInstancesPhaseTimelineItems"},"OpportunityWithPhaseInstancesOwner":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]}},"title":"OpportunityWithPhaseInstancesOwner"},"OpportunityWithPhaseInstancesSalesRep":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]}},"title":"OpportunityWithPhaseInstancesSalesRep"},"OpportunityWithPhaseInstancesProjectManager":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]}},"title":"OpportunityWithPhaseInstancesProjectManager"},"OpportunityWithPhaseInstancesJurisdiction":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"uuid":{"type":"string"}},"title":"OpportunityWithPhaseInstancesJurisdiction"},"OpportunityWithPhaseInstancesPhase":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"description":"Current phase. `startedAt` and `completedAt` are present on `GET /opportunities/{opportunity_id}` and on lists with `include_phases=true`.","title":"OpportunityWithPhaseInstancesPhase"},"OpportunityWithPhaseInstancesPhaseInstancesItemsStatus":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"],"title":"OpportunityWithPhaseInstancesPhaseInstancesItemsStatus"},"OpportunityWithPhaseInstancesPhaseInstancesItems":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesPhaseInstancesItemsStatus"},"position":{"type":"integer"},"type":{"type":"string"},"phaseTemplateId":{"type":"integer"},"phaseTemplate":{"$ref":"#/components/schemas/PhaseTemplateSummary"},"startedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the phase instance started"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the phase instance completed"}},"title":"OpportunityWithPhaseInstancesPhaseInstancesItems"},"OpportunityWithPhaseInstances":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent update to the record, including changes to its custom property values."},"title":{"type":"string","description":"Record title/name"},"description":{"type":["string","null"],"description":"Record description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full opportunity location/address."},"isActive":{"type":"boolean","description":"Whether the record is active"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"number":{"type":"integer","description":"Sequential opportunity number"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who created the record. Null when the record was created by a non-user actor (e.g. automation or a contact)."},"updatedBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who last edited a field on the record, derived from the changelog. Null when the record has never been edited or the last edit was made by a non-user actor. Returned by single-record GET only; list and search responses omit it."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"salesRepId":{"type":["integer","null"],"description":"ID of the assigned sales rep"},"projectManagerId":{"type":["integer","null"],"description":"ID of the assigned project manager"},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types"},"value":{"type":["string","null"],"title":"float","description":"Deal value"},"size":{"type":["string","null"],"title":"float","description":"Deal size"},"confidence":{"type":["string","null"],"title":"float","description":"Deal confidence score (0-100)"},"status":{"$ref":"#/components/schemas/OpportunityStatus"},"workflowId":{"type":["integer","null"],"description":"Associated workflow ID"},"accountId":{"type":["integer","null"],"description":"Associated account ID"},"geoLocation":{"type":"array","items":{"type":"string"},"description":"Latitude/Longitude in \"lat,lon\" format. Read-only here — settable only via `PATCH /sites/{id}` on the linked site.\n"},"imageUrl":{"type":["string","null"],"description":"Image URL for the opportunity. Read-only — not settable via this API."},"streetViewUrl":{"type":["string","null"],"description":"Street view image URL. Read-only — derived from geoLocation, not settable directly."},"city":{"type":"string"},"zipcode":{"type":"string"},"state":{"type":"string"},"street":{"type":"string"},"phaseTimeline":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesPhaseTimelineItems"},"description":"Only present on `GET /opportunities` and `/opportunities/search` when `entered_phase_id`/`exited_phase_id` is used to filter the results. Contains the deal's full phase-transition history (not just the matched phase) in compact form — use `GET /opportunities/{opportunity_id}` for the complete `phaseInstances` with names, positions, and SLA info.\n"},"owner":{"oneOf":[{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesOwner"},{"type":"null"}]},"salesRep":{"oneOf":[{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesSalesRep"},{"type":"null"}]},"projectManager":{"oneOf":[{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesProjectManager"},{"type":"null"}]},"jurisdiction":{"oneOf":[{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesJurisdiction"},{"type":"null"}]},"lastActivity":{"type":["string","null"],"format":"date-time"},"phaseId":{"type":["integer","null"]},"workflowName":{"type":"string","description":"Name of the associated workflow.\n"},"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactRef"},"description":"Contacts associated with this opportunity (independent of, and not inherited from, the parent account's contacts). Set on create or update via the `contacts` request field. On GET requests, only populated when include_contacts=true is passed. Always populated on POST (create) and PATCH (update) responses. Ordered with the primary contact first, capped at 20 contacts."},"phase":{"oneOf":[{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesPhase"},{"type":"null"}],"description":"Current phase. `startedAt` and `completedAt` are present on `GET /opportunities/{opportunity_id}` and on lists with `include_phases=true`."},"phaseInstances":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityWithPhaseInstancesPhaseInstancesItems"},"description":"Ordered list of phase instances for the opportunity. Returned by `GET /opportunities/{opportunity_id}`, and on lists and search with `include_phases=true`."}},"title":"OpportunityWithPhaseInstances"},"OpportunitiesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesGetResponsesContentApplicationJsonSchemaCode"},"ListOpportunitiesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListOpportunitiesRequestBadRequestError"},"ListOpportunitiesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListOpportunitiesRequestUnauthorizedError"},"OpportunitiesSearchGetParametersOp1":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"OpportunitiesSearchGetParametersOp1"},"OpportunitiesSearchGetParametersLogic":{"type":"string","enum":["and","or"],"default":"and","title":"OpportunitiesSearchGetParametersLogic"},"OpportunitiesSearchGetParametersOp2":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"OpportunitiesSearchGetParametersOp2"},"OpportunitiesSearchGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"OpportunitiesSearchGetParametersOrderBy"},"OpportunitiesSearchGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesSearchGetResponsesContentApplicationJsonSchemaCode"},"SearchOpportunitiesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesSearchGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"SearchOpportunitiesRequestBadRequestError"},"SearchOpportunitiesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesSearchGetResponsesContentApplicationJsonSchemaCode"}},"title":"SearchOpportunitiesRequestUnauthorizedError"},"OpportunitiesOpportunityIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdGetResponsesContentApplicationJsonSchemaCode"},"GetOpportunityRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityRequestUnauthorizedError"},"GetOpportunityRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityRequestNotFoundError"},"OpportunitiesPostParametersMatchBy":{"type":"string","enum":["title","primaryEmail","primaryPhone","address"],"default":"title","title":"OpportunitiesPostParametersMatchBy"},"OpportunitiesPostParametersMatchFoundStrategy":{"type":"string","enum":["skip","replace","enrich"],"default":"skip","description":"- skip: Return existing record without changes\n- replace: Replace existing record with new data\n- enrich: Update only empty fields in existing record\n","title":"OpportunitiesPostParametersMatchFoundStrategy"},"OpportunityUpsert":{"type":"object","properties":{"title":{"type":"string","description":"Opportunity title/name"},"description":{"type":["string","null"],"description":"Opportunity description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full opportunity location/address."},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types"},"accountId":{"type":"integer","description":"ID of associated account. Only accepted on create."},"workflowId":{"type":["integer","null"],"description":"ID of associated workflow"},"phaseId":{"type":["integer","null"],"description":"ID of associated phase template"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"salesRepId":{"type":["integer","null"],"description":"ID of the assigned sales rep"},"projectManagerId":{"type":["integer","null"],"description":"ID of the assigned project manager"},"value":{"type":"number","format":"double","description":"Project value"},"size":{"type":"number","format":"double","description":"Project size"},"confidence":{"type":["number","null"],"format":"double","description":"Deal confidence score (0-100)"},"status":{"$ref":"#/components/schemas/OpportunityStatus"},"primaryEmail":{"type":"string","format":"email","description":"Primary contact email"},"primaryPhone":{"type":"string","description":"Primary contact phone"},"contacts":{"type":"array","items":{"type":"integer"},"description":"Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts. The first ID in the array is treated as the primary contact."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"required":["title","address","trades"],"description":"Used for both create and update. `accountId` is only accepted on create — passing it on a PATCH update will return a 400 error.\n","title":"OpportunityUpsert"},"OpportunityPhaseTimelineItems":{"type":"object","properties":{"phaseTemplateId":{"type":"integer"},"startedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the deal entered this phase template"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the deal exited this phase template"}},"title":"OpportunityPhaseTimelineItems"},"OpportunityOwner":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]}},"title":"OpportunityOwner"},"OpportunitySalesRep":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]}},"title":"OpportunitySalesRep"},"OpportunityProjectManager":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]}},"title":"OpportunityProjectManager"},"OpportunityJurisdiction":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"uuid":{"type":"string"}},"title":"OpportunityJurisdiction"},"Opportunity":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent update to the record, including changes to its custom property values."},"title":{"type":"string","description":"Record title/name"},"description":{"type":["string","null"],"description":"Record description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full opportunity location/address."},"isActive":{"type":"boolean","description":"Whether the record is active"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"number":{"type":"integer","description":"Sequential opportunity number"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who created the record. Null when the record was created by a non-user actor (e.g. automation or a contact)."},"updatedBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who last edited a field on the record, derived from the changelog. Null when the record has never been edited or the last edit was made by a non-user actor. Returned by single-record GET only; list and search responses omit it."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"salesRepId":{"type":["integer","null"],"description":"ID of the assigned sales rep"},"projectManagerId":{"type":["integer","null"],"description":"ID of the assigned project manager"},"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeType"},"description":"Array of trade types"},"value":{"type":["string","null"],"title":"float","description":"Deal value"},"size":{"type":["string","null"],"title":"float","description":"Deal size"},"confidence":{"type":["string","null"],"title":"float","description":"Deal confidence score (0-100)"},"status":{"$ref":"#/components/schemas/OpportunityStatus"},"workflowId":{"type":["integer","null"],"description":"Associated workflow ID"},"accountId":{"type":["integer","null"],"description":"Associated account ID"},"geoLocation":{"type":"array","items":{"type":"string"},"description":"Latitude/Longitude in \"lat,lon\" format. Read-only here — settable only via `PATCH /sites/{id}` on the linked site.\n"},"imageUrl":{"type":["string","null"],"description":"Image URL for the opportunity. Read-only — not settable via this API."},"streetViewUrl":{"type":["string","null"],"description":"Street view image URL. Read-only — derived from geoLocation, not settable directly."},"city":{"type":"string"},"zipcode":{"type":"string"},"state":{"type":"string"},"street":{"type":"string"},"phaseTimeline":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityPhaseTimelineItems"},"description":"Only present on `GET /opportunities` and `/opportunities/search` when `entered_phase_id`/`exited_phase_id` is used to filter the results. Contains the deal's full phase-transition history (not just the matched phase) in compact form — use `GET /opportunities/{opportunity_id}` for the complete `phaseInstances` with names, positions, and SLA info.\n"},"owner":{"oneOf":[{"$ref":"#/components/schemas/OpportunityOwner"},{"type":"null"}]},"salesRep":{"oneOf":[{"$ref":"#/components/schemas/OpportunitySalesRep"},{"type":"null"}]},"projectManager":{"oneOf":[{"$ref":"#/components/schemas/OpportunityProjectManager"},{"type":"null"}]},"jurisdiction":{"oneOf":[{"$ref":"#/components/schemas/OpportunityJurisdiction"},{"type":"null"}]},"lastActivity":{"type":["string","null"],"format":"date-time"},"phaseId":{"type":["integer","null"]},"workflowName":{"type":"string","description":"Name of the associated workflow.\n"},"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactRef"},"description":"Contacts associated with this opportunity (independent of, and not inherited from, the parent account's contacts). Set on create or update via the `contacts` request field. On GET requests, only populated when include_contacts=true is passed. Always populated on POST (create) and PATCH (update) responses. Ordered with the primary contact first, capped at 20 contacts."}},"title":"Opportunity"},"OpportunitiesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityRequestBadRequestError"},"CreateOpportunityRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityRequestUnauthorizedError"},"OpportunitiesOpportunityIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateOpportunityRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateOpportunityRequestBadRequestError"},"UpdateOpportunityRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateOpportunityRequestUnauthorizedError"},"UpdateOpportunityRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateOpportunityRequestNotFoundError"},"OpportunitiesOpportunityIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteOpportunityRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteOpportunityRequestUnauthorizedError"},"DeleteOpportunityRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteOpportunityRequestNotFoundError"},"AccountsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsGetParametersUpdatedAfter"},"AccountsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsGetParametersUpdatedBefore"},"AccountsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"AccountsGetParametersOrderBy"},"AccountAccountType":{"type":"string","enum":["RESIDENTIAL","COMMERCIAL"],"description":"Type of account (residential or commercial)","title":"AccountAccountType"},"Account":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent update to the record, including changes to its custom property values."},"title":{"type":"string","description":"Record title/name"},"description":{"type":["string","null"],"description":"Record description"},"address":{"type":"array","items":{"type":"string"},"description":"Record location/address"},"isActive":{"type":"boolean","description":"Whether the record is active"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"number":{"type":"integer","description":"Record number (e.g., 1234)"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who created the record. Null when the record was created by a non-user actor (e.g. automation or a contact)."},"updatedBy":{"oneOf":[{"$ref":"#/components/schemas/UserSummary"},{"type":"null"}],"description":"User who last edited a field on the record, derived from the changelog. Null when the record has never been edited or the last edit was made by a non-user actor. Returned by single-record GET only; list and search responses omit it."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"},"accountType":{"oneOf":[{"$ref":"#/components/schemas/AccountAccountType"},{"type":"null"}],"description":"Type of account (residential or commercial)"},"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactRef"},"description":"On GET requests, only populated when include_contacts=true is passed. Always populated on POST (create) and PATCH (update) responses. Ordered with the primary contact first, capped at 20 contacts."}},"title":"Account"},"AccountsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsGetResponsesContentApplicationJsonSchemaCode"},"ListAccountsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListAccountsRequestUnauthorizedError"},"AccountsSearchGetParametersOp1":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"AccountsSearchGetParametersOp1"},"AccountsSearchGetParametersLogic":{"type":"string","enum":["and","or"],"default":"and","title":"AccountsSearchGetParametersLogic"},"AccountsSearchGetParametersOp2":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"AccountsSearchGetParametersOp2"},"AccountsSearchGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"AccountsSearchGetParametersOrderBy"},"AccountsSearchGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsSearchGetResponsesContentApplicationJsonSchemaCode"},"SearchAccountsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsSearchGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"SearchAccountsRequestBadRequestError"},"SearchAccountsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsSearchGetResponsesContentApplicationJsonSchemaCode"}},"title":"SearchAccountsRequestUnauthorizedError"},"AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode"},"GetAccountRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountRequestUnauthorizedError"},"GetAccountRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountRequestNotFoundError"},"AccountsPostParametersMatchBy":{"type":"string","enum":["title","primaryEmail","primaryPhone","address"],"default":"title","title":"AccountsPostParametersMatchBy"},"AccountsPostParametersMatchFoundStrategy":{"type":"string","enum":["skip","replace","enrich"],"default":"skip","description":"- skip: Return existing record without changes\n- replace: Replace existing record with new data\n- enrich: Update only empty fields in existing record\n","title":"AccountsPostParametersMatchFoundStrategy"},"AccountUpsertAccountType":{"type":"string","enum":["RESIDENTIAL","COMMERCIAL"],"description":"Account type","title":"AccountUpsertAccountType"},"AccountUpsert":{"type":"object","properties":{"title":{"type":"string","description":"Account name"},"description":{"type":["string","null"],"description":"Account description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the primary account location/address."},"accountType":{"$ref":"#/components/schemas/AccountUpsertAccountType","description":"Account type"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"primaryEmail":{"type":"string","format":"email","description":"Primary contact email"},"primaryPhone":{"type":"string","description":"Primary contact phone"},"contacts":{"type":["array","null"],"items":{"type":"integer"},"description":"Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts. The first ID in the array is treated as the primary contact."},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"required":["title","address"],"title":"AccountUpsert"},"AccountsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsPostResponsesContentApplicationJsonSchemaCode"},"CreateAccountRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateAccountRequestBadRequestError"},"CreateAccountRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateAccountRequestUnauthorizedError"},"AccountUpdateAccountType":{"type":"string","enum":["RESIDENTIAL","COMMERCIAL"],"description":"Account type","title":"AccountUpdateAccountType"},"AccountUpdate":{"type":"object","properties":{"title":{"type":"string","description":"Account name"},"description":{"type":["string","null"],"description":"Account description"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the primary account location/address."},"accountType":{"oneOf":[{"$ref":"#/components/schemas/AccountUpdateAccountType"},{"type":"null"}],"description":"Account type"},"ownerId":{"type":["integer","null"],"description":"ID of the owning user"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"contacts":{"type":["array","null"],"items":{"type":"integer"},"description":"Contact IDs to associate with this account. The contacts must be created first via POST /contacts. The first ID in the array is treated as the primary contact."},"isActive":{"type":"boolean","description":"Whether the account is active"},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"description":"Partial update payload for an account. All fields are optional.","title":"AccountUpdate"},"AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateAccountRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateAccountRequestBadRequestError"},"UpdateAccountRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAccountRequestUnauthorizedError"},"UpdateAccountRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAccountRequestNotFoundError"},"AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteAccountRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteAccountRequestUnauthorizedError"},"DeleteAccountRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteAccountRequestNotFoundError"},"Site":{"type":"object","properties":{"id":{"type":"integer","description":"Unique site ID."},"accountId":{"type":"integer","description":"ID of the account this site belongs to."},"title":{"type":["string","null"],"description":"Human-readable label for the site (e.g. \"Main Office\")."},"fullAddress":{"type":["string","null"],"description":"Full formatted address string."},"street":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"zipcode":{"type":["string","null"]},"geoLocation":{"type":["string","null"],"description":"Latitude/longitude as \"lat,lng\" (e.g. \"37.7749,-122.4194\")."},"timezone":{"type":["string","null"],"description":"IANA timezone string (e.g. \"America/Los_Angeles\")."},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"title":"Site"},"SitesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"SitesGetResponsesContentApplicationJsonSchemaCode"},"ListSitesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListSitesRequestBadRequestError"},"ListSitesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListSitesRequestUnauthorizedError"},"SitesSiteIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"SitesSiteIdGetResponsesContentApplicationJsonSchemaCode"},"GetSiteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetSiteRequestBadRequestError"},"GetSiteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetSiteRequestUnauthorizedError"},"GetSiteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetSiteRequestNotFoundError"},"SiteCreate":{"type":"object","properties":{"accountId":{"type":"integer","description":"ID of the account this site belongs to."},"fullAddress":{"type":"string","description":"Full address string. Either `fullAddress` or `geoLocation` must be provided."},"geoLocation":{"type":"string","description":"Latitude/longitude as \"lat,lng\". Either `fullAddress` or `geoLocation` must be provided."},"title":{"type":"string","maxLength":255,"description":"Human-readable label for the site."},"street":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipcode":{"type":"string"}},"required":["accountId"],"title":"SiteCreate"},"SitesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"SitesPostResponsesContentApplicationJsonSchemaCode"},"CreateSiteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateSiteRequestBadRequestError"},"CreateSiteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateSiteRequestUnauthorizedError"},"SitesSiteIdMovePostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"SitesSiteIdMovePostResponsesContentApplicationJsonSchemaCode"},"MoveSiteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdMovePostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"MoveSiteRequestBadRequestError"},"MoveSiteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdMovePostResponsesContentApplicationJsonSchemaCode"}},"title":"MoveSiteRequestUnauthorizedError"},"MoveSiteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdMovePostResponsesContentApplicationJsonSchemaCode"}},"title":"MoveSiteRequestNotFoundError"},"SiteUpdate":{"type":"object","properties":{"fullAddress":{"type":"string","description":"Full address string. Backend will re-geocode when updated."},"geoLocation":{"type":"string","description":"Latitude/longitude as \"lat,lng\". **On update**, sending this triggers a full re-geocode — the backend snaps to the nearest address via Google Maps, so the stored value may differ from what you sent.\n"},"title":{"type":"string","maxLength":255},"street":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipcode":{"type":"string"},"timezone":{"type":"string","description":"IANA timezone string (e.g. \"America/Los_Angeles\"). Use this to manually override the timezone if the geocoded value is incorrect or you are migrating from a system that has an explicit timezone already set.\n"}},"description":"All fields are optional. To move a site to a different account, use `POST /sites/{site_id}/move` instead of setting `accountId` here.\n","title":"SiteUpdate"},"SitesSiteIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"SitesSiteIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateSiteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateSiteRequestBadRequestError"},"UpdateSiteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateSiteRequestUnauthorizedError"},"UpdateSiteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateSiteRequestNotFoundError"},"SitesSiteIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"SitesSiteIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteSiteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteSiteRequestUnauthorizedError"},"DeleteSiteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/SitesSiteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteSiteRequestNotFoundError"},"AssetsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"desc","title":"AssetsGetParametersOrderBy"},"AssetStatus":{"type":"string","enum":["DRAFT","ACTIVE","MAINTENANCE","INACTIVE","RETIRED"],"description":"Asset lifecycle status.","title":"AssetStatus"},"AssetType":{"type":"string","enum":["BATTERY_SYSTEM","CHARGING_GATEWAY","COMBINER_BOX","EV_CHARGER","LOAD_CENTER","MICROINVERTER","POWER_OPTIMIZER","PRODUCTION_METER","RAPID_SHUTDOWN_DEVICE","PV_INVERTER","TRACKER","WEATHER_STATION","AIR_CONDITIONER","AIR_HANDLING_UNIT","BOILER","CHILLER","COOLING_TOWER","FAN","HEAT_EXCHANGER","HEAT_PUMP","MAKE_UP_AIR_UNIT","PUMP","ROOFTOP_UNIT","THERMOSTAT","VARIABLE_FREQUENCY_DRIVE","AUTOMATIC_TRANSFER_SWITCH","BREAKER","DISCONNECT_SWITCH","ELECTRIC_METER","GENERATOR","LIGHTING_PANEL","PANELBOARD","SWITCHGEAR","TRANSFORMER","UNINTERRUPTIBLE_POWER_SUPPLY","BACKFLOW_PREVENTER","BOOSTER_PUMP","GREASE_INTERCEPTOR","STORAGE_TANK","SUMP_PUMP","VALVE","WATER_FILTRATION_SYSTEM","WATER_HEATER","WATER_SOFTENER","ACCESS_CONTROLLER","AUTOMATION_CONTROLLER","CAMERA","CARD_READER","DOOR_STRIKE","MAGLOCK","NETWORK_SWITCH","NETWORK_VIDEO_RECORDER","SENSOR","WIRELESS_ACCESS_POINT","OTHER"],"description":"Asset type enum.","title":"AssetType"},"AssetsGetParametersIsArchived":{"type":"string","enum":["true","false","1","0"],"default":"false","title":"AssetsGetParametersIsArchived"},"AssetLabelType":{"type":"string","enum":["ASSET","TASK"],"title":"AssetLabelType"},"AssetLabel":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"color":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/AssetLabelType"}},"required":["id","name","type"],"description":"Label attached to an asset (read-only expansion of the label id).","title":"AssetLabel"},"Asset":{"type":"object","properties":{"id":{"type":"integer","description":"Asset identifier."},"uid":{"type":["integer","null"],"description":"Short human-readable identifier for the asset (nullable for older records)."},"name":{"type":["string","null"]},"type":{"oneOf":[{"$ref":"#/components/schemas/AssetType"},{"type":"null"}]},"status":{"$ref":"#/components/schemas/AssetStatus"},"manufacturer":{"type":["string","null"]},"model":{"type":["string","null"]},"serialNumber":{"type":["string","null"]},"siteId":{"type":"integer"},"accountId":{"type":["integer","null"],"description":"ID of the account (project with type ACCOUNT) the asset belongs to."},"size":{"type":["number","null"],"format":"double"},"labels":{"type":"array","items":{"$ref":"#/components/schemas/AssetLabel"},"description":"Labels attached to the asset, ordered by position."},"installDate":{"type":["string","null"],"format":"date"},"manufacturingDate":{"type":["string","null"],"format":"date"},"expectedLifetime":{"type":["number","null"],"format":"double","description":"Expected lifetime in years"},"description":{"type":["string","null"]},"coverImageFileId":{"type":["integer","null"]},"nameplateImageFileId":{"type":["integer","null"]},"isArchived":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","status","siteId","labels","isArchived"],"title":"Asset"},"AssetsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AssetsGetResponsesContentApplicationJsonSchemaCode"},"ListAssetsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListAssetsRequestBadRequestError"},"ListAssetsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListAssetsRequestUnauthorizedError"},"AssetsAssetIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AssetsAssetIdGetResponsesContentApplicationJsonSchemaCode"},"GetAssetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsAssetIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAssetRequestUnauthorizedError"},"GetAssetRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsAssetIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAssetRequestNotFoundError"},"AssetCreate":{"type":"object","properties":{"accountId":{"type":"integer","description":"ID of the account (project with type ACCOUNT) the asset should belong to."},"siteId":{"type":"integer"},"type":{"$ref":"#/components/schemas/AssetType"},"manufacturer":{"type":"string"},"model":{"type":"string"},"serialNumber":{"type":"string"},"status":{"$ref":"#/components/schemas/AssetStatus"},"size":{"type":"number","format":"double"},"labelIds":{"type":"array","items":{"type":"integer"},"description":"Label IDs to attach to the asset."},"installDate":{"type":"string","format":"date"},"manufacturingDate":{"type":"string","format":"date"},"expectedLifetime":{"type":"number","format":"double","description":"Expected lifetime in years"},"description":{"type":"string"},"coverImageFileId":{"type":"integer"},"nameplateImageFileId":{"type":"integer"}},"required":["accountId","siteId","type","manufacturer","model","serialNumber"],"description":"Body for `POST /assets`.","title":"AssetCreate"},"AssetsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AssetsPostResponsesContentApplicationJsonSchemaCode"},"CreateAssetRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateAssetRequestBadRequestError"},"CreateAssetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateAssetRequestUnauthorizedError"},"AssetUpdate":{"type":"object","properties":{"name":{"type":"string"},"type":{"$ref":"#/components/schemas/AssetType"},"status":{"$ref":"#/components/schemas/AssetStatus"},"manufacturer":{"type":"string"},"model":{"type":"string"},"serialNumber":{"type":"string"},"size":{"type":"number","format":"double"},"labelIds":{"type":"array","items":{"type":"integer"},"description":"Replaces the asset's label list."},"installDate":{"type":["string","null"],"format":"date"},"manufacturingDate":{"type":["string","null"],"format":"date"},"expectedLifetime":{"type":"number","format":"double","description":"Expected lifetime in years"},"description":{"type":"string"},"coverImageFileId":{"type":"integer"},"nameplateImageFileId":{"type":"integer"},"isArchived":{"type":"boolean"}},"description":"Partial update body for `PATCH /assets/{asset_id}`. All fields are optional.\n`siteId` and `accountId` cannot be changed after creation. Including either field in the request body is rejected with a `400 Bad Request` validation error.\nSet `isArchived: true` to archive the asset, or `isArchived: false` to unarchive it.\n","title":"AssetUpdate"},"AssetsAssetIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AssetsAssetIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateAssetRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsAssetIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateAssetRequestBadRequestError"},"UpdateAssetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsAssetIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAssetRequestUnauthorizedError"},"UpdateAssetRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AssetsAssetIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAssetRequestNotFoundError"},"VendorsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"VendorsGetParametersUpdatedAfter"},"VendorsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"VendorsGetParametersUpdatedBefore"},"VendorsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"VendorsGetParametersOrderBy"},"VendorsGetParametersVendorType":{"type":"string","enum":["CONSULTANT","FINANCING","LOGISTICS","MANUFACTURER","SUBCONTRACTOR","SUPPLIER"],"title":"VendorsGetParametersVendorType"},"VendorVendorType":{"type":"string","enum":["CONSULTANT","FINANCING","LOGISTICS","MANUFACTURER","SUBCONTRACTOR","SUPPLIER"],"description":"The type of vendor","title":"VendorVendorType"},"Vendor":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"name":{"type":"string","description":"Vendor name"},"description":{"type":["string","null"],"description":"Vendor description"},"address":{"type":"array","items":{"type":"string"},"description":"Vendor location/address"},"isActive":{"type":"boolean","description":"Whether the vendor is active"},"primaryEmail":{"type":["string","null"],"format":"email","description":"Primary contact email"},"primaryPhone":{"type":["string","null"],"description":"Primary contact phone"},"number":{"type":"integer","description":"Vendor number (e.g., 1234)"},"vendorType":{"oneOf":[{"$ref":"#/components/schemas/VendorVendorType"},{"type":"null"}],"description":"The type of vendor"},"website":{"type":["string","null"],"description":"Vendor website URL"},"projectIds":{"type":"array","items":{"type":"integer"},"description":"IDs of projects this vendor is linked to"},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"title":"Vendor"},"VendorsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"VendorsGetResponsesContentApplicationJsonSchemaCode"},"ListVendorsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListVendorsRequestUnauthorizedError"},"VendorsSearchGetParametersOp1":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"VendorsSearchGetParametersOp1"},"VendorsSearchGetParametersLogic":{"type":"string","enum":["and","or"],"default":"and","title":"VendorsSearchGetParametersLogic"},"VendorsSearchGetParametersOp2":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","contains","in","nin","between"],"title":"VendorsSearchGetParametersOp2"},"VendorsSearchGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"VendorsSearchGetResponsesContentApplicationJsonSchemaCode"},"SearchVendorsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsSearchGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"SearchVendorsRequestBadRequestError"},"SearchVendorsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsSearchGetResponsesContentApplicationJsonSchemaCode"}},"title":"SearchVendorsRequestUnauthorizedError"},"VendorsVendorIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"VendorsVendorIdGetResponsesContentApplicationJsonSchemaCode"},"GetVendorRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetVendorRequestUnauthorizedError"},"GetVendorRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetVendorRequestNotFoundError"},"VendorCreateVendorType":{"type":"string","enum":["CONSULTANT","FINANCING","LOGISTICS","MANUFACTURER","SUBCONTRACTOR","SUPPLIER"],"description":"The type of vendor","title":"VendorCreateVendorType"},"VendorCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500,"description":"Vendor name"},"vendorType":{"$ref":"#/components/schemas/VendorCreateVendorType","description":"The type of vendor"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full vendor location/address."},"website":{"type":["string","null"],"maxLength":2048,"description":"Vendor website URL"},"description":{"type":["string","null"],"description":"Vendor description"},"isActive":{"type":"boolean","default":true,"description":"Whether the vendor is active"},"contacts":{"type":["array","null"],"items":{"type":"integer"},"description":"Contact IDs to associate with this vendor"},"projectIds":{"type":["array","null"],"items":{"type":"integer"},"description":"Project IDs to link this vendor to"},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"required":["name","vendorType"],"title":"VendorCreate"},"VendorsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"VendorsPostResponsesContentApplicationJsonSchemaCode"},"CreateVendorRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateVendorRequestBadRequestError"},"CreateVendorRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateVendorRequestUnauthorizedError"},"Vendors_createVendorProjectLink_Response_200":{"type":"object","properties":{"message":{"type":"string"}},"title":"Vendors_createVendorProjectLink_Response_200"},"ProjectsProjectIdVendorsVendorIdPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdVendorsVendorIdPostResponsesContentApplicationJsonSchemaCode"},"CreateVendorProjectLinkRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdVendorsVendorIdPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateVendorProjectLinkRequestUnauthorizedError"},"CreateVendorProjectLinkRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdVendorsVendorIdPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateVendorProjectLinkRequestNotFoundError"},"VendorUpdateVendorType":{"type":"string","enum":["CONSULTANT","FINANCING","LOGISTICS","MANUFACTURER","SUBCONTRACTOR","SUPPLIER"],"description":"The type of vendor","title":"VendorUpdateVendorType"},"VendorUpdate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500,"description":"Vendor name"},"vendorType":{"$ref":"#/components/schemas/VendorUpdateVendorType","description":"The type of vendor"},"address":{"type":"array","items":{"type":"string"},"description":"An array containing a single string, which represents the full vendor location/address."},"website":{"type":["string","null"],"maxLength":2048,"description":"Vendor website URL"},"description":{"type":["string","null"],"description":"Vendor description"},"isActive":{"type":"boolean","description":"Whether the vendor is active"},"contacts":{"type":["array","null"],"items":{"type":"integer"},"description":"Contact IDs to associate with this vendor"},"projectIds":{"type":["array","null"],"items":{"type":"integer"},"description":"Project IDs to link this vendor to"},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom fields"}},"title":"VendorUpdate"},"VendorsVendorIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"VendorsVendorIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateVendorRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateVendorRequestBadRequestError"},"UpdateVendorRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateVendorRequestUnauthorizedError"},"UpdateVendorRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateVendorRequestNotFoundError"},"VendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"VendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteVendorRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteVendorRequestUnauthorizedError"},"DeleteVendorRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/VendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteVendorRequestNotFoundError"},"Vendors_deleteVendorProjectLink_Response_200":{"type":"object","properties":{"message":{"type":"string"}},"title":"Vendors_deleteVendorProjectLink_Response_200"},"ProjectsProjectIdVendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdVendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteVendorProjectLinkRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdVendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteVendorProjectLinkRequestUnauthorizedError"},"DeleteVendorProjectLinkRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdVendorsVendorIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteVendorProjectLinkRequestNotFoundError"},"AhjsGetParametersType":{"type":"string","enum":["STATE","COUNTY","CITY","MUNICIPALITY","TOWNSHIP","TRIBAL"],"title":"AhjsGetParametersType"},"AhjsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"AhjsGetParametersOrderBy"},"AhjType":{"type":"string","enum":["STATE","COUNTY","CITY","MUNICIPALITY","TOWNSHIP","TRIBAL"],"description":"Jurisdiction type.","title":"AhjType"},"AHJ":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier."},"uuid":{"type":["string","null"],"description":"AHJID UUID (when known)."},"name":{"type":"string","description":"Full AHJ name (e.g. \"City of San Francisco\")."},"type":{"oneOf":[{"$ref":"#/components/schemas/AhjType"},{"type":"null"}],"description":"Jurisdiction type."},"country":{"type":"string","description":"Two-letter country code (e.g. \"US\")."},"state":{"type":["string","null"],"description":"Two-letter state code (e.g. \"CA\")."},"stateName":{"type":["string","null"],"description":"Full state name (e.g. \"California\")."},"parentCounty":{"type":["string","null"],"description":"For sub-county jurisdictions, the containing county name."},"geoId":{"type":["string","null"],"description":"US Census TIGER GEOID for the boundary."},"ahjRegistryCode":{"type":["string","null"],"description":"AHJ Registry composite code (e.g. \"TX-4805000\")."},"isActive":{"type":"boolean","description":"Whether this AHJ is currently active in the catalog."},"isPrivate":{"type":["boolean","null"],"description":"True for company-private jurisdictions, false for global catalog entries."},"pointOfContact":{"type":["string","null"]},"submissionMethod":{"type":["string","null"],"description":"How permit submissions are accepted (online, in-person, etc.)."},"emails":{"type":"array","items":{"type":"string","format":"email"}},"phones":{"type":"array","items":{"type":"string"}},"address":{"type":["string","null"]},"website":{"type":["string","null"]},"portal":{"type":["string","null"],"description":"Permit portal URL."},"turnaround":{"type":["integer","null"],"description":"Typical permit turnaround in days."},"fees":{"type":["string","null"]},"notes":{"type":["string","null"]},"permitSubmissionNotes":{"type":["string","null"]},"buildingCodeModel":{"type":["string","null"]},"buildingCodeLocal":{"type":["string","null"]},"residentialCodeModel":{"type":["string","null"]},"residentialCodeLocal":{"type":["string","null"]},"fireCodeModel":{"type":["string","null"]},"fireCodeLocal":{"type":["string","null"]},"electricalCodeModel":{"type":["string","null"]},"electricalCodeLocal":{"type":["string","null"]},"windCodeModel":{"type":["string","null"]},"windCodeLocal":{"type":["string","null"]},"codesOther":{"type":["string","null"]},"firePathwaysEnforced":{"type":["boolean","null"]},"electricalEngineerStampRequired":{"type":["boolean","null"]},"structuralStampRequired":{"type":["boolean","null"]},"climateZone":{"type":["string","null"]},"ashraeMinTempC":{"type":["number","null"],"format":"double"},"ashraeMaxTempC":{"type":["number","null"],"format":"double"},"ashraeMinTempF":{"type":["number","null"],"format":"double","description":"Auto-computed from ashraeMinTempC. Used for NEC 690.7 max-Voc string sizing."},"ashraeMaxTempF":{"type":["number","null"],"format":"double","description":"Auto-computed from ashraeMaxTempC. Used for thermal derating in PV performance modeling."},"centroidLatitude":{"type":["number","null"],"format":"double"},"centroidLongitude":{"type":["number","null"],"format":"double"},"landAreaSqMiles":{"type":["number","null"],"format":"double"},"specialZones":{"type":["array","null"],"items":{"type":"string"}},"buildingDeptHours":{"type":["array","null"],"items":{"type":"string"}},"tigerYear":{"type":["integer","null"]},"funcstat":{"type":["string","null"],"description":"US Census functional status code."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom field values keyed by property keyName. This includes only customer-defined custom columns (see GET /properties?record_type=ahj). Built-in catalog AHJ fields (turnaround, website, fees, notes, etc.) are exposed as top-level fields on the AHJ object and are read-only."}},"description":"An Authority Having Jurisdiction (AHJ). Most fields are read-only catalog data sourced from the US Census TIGER dataset; only fields under `custom` are user-editable.","title":"AHJ"},"AhjsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"AhjsGetResponsesContentApplicationJsonSchemaCode"},"List-ahjsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"List-ahjsRequestBadRequestError"},"List-ahjsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsGetResponsesContentApplicationJsonSchemaCode"}},"title":"List-ahjsRequestUnauthorizedError"},"List-ahjsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsGetResponsesContentApplicationJsonSchemaCode"}},"title":"List-ahjsRequestBadGatewayError"},"AhjsAhjIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"AhjsAhjIdGetResponsesContentApplicationJsonSchemaCode"},"GetAhjRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAhjRequestUnauthorizedError"},"GetAhjRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAhjRequestNotFoundError"},"GetAhjRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAhjRequestBadGatewayError"},"AHJUpdate":{"type":"object","properties":{"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom field values keyed by property keyName. Pass `null` to clear a value. Unknown keyNames are rejected with a 400 — fetch valid keys via GET /properties?record_type=ahj."}},"required":["custom"],"title":"AHJUpdate"},"AhjsAhjIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"AhjsAhjIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateAhjRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateAhjRequestBadRequestError"},"UpdateAhjRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAhjRequestUnauthorizedError"},"UpdateAhjRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAhjRequestNotFoundError"},"UpdateAhjRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AhjsAhjIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAhjRequestBadGatewayError"},"UtilitiesGetParametersOwnershipType":{"type":"string","enum":["INVESTOR","MUNICIPAL","MUNICIPAL_MARKETING_AUTHORITY","COOPERATIVE","FEDERAL","STATE","POLITICAL","COMMUNITY_CHOICE_AGGREGATOR","WHOLESALE_POWER_MARKETER","OTHER"],"title":"UtilitiesGetParametersOwnershipType"},"UtilitiesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"UtilitiesGetParametersOrderBy"},"UtilityOwnershipType":{"type":"string","enum":["INVESTOR","MUNICIPAL","MUNICIPAL_MARKETING_AUTHORITY","COOPERATIVE","FEDERAL","STATE","POLITICAL","COMMUNITY_CHOICE_AGGREGATOR","WHOLESALE_POWER_MARKETER","OTHER"],"title":"UtilityOwnershipType"},"Utility":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier."},"name":{"type":"string","description":"Utility name."},"state":{"type":["string","null"],"description":"Two-letter state code (e.g. \"CA\")."},"stateName":{"type":["string","null"],"description":"Full state name (e.g. \"California\")."},"ownershipType":{"oneOf":[{"$ref":"#/components/schemas/UtilityOwnershipType"},{"type":"null"}]},"holdingCompany":{"type":["string","null"]},"address":{"type":["string","null"]},"phone":{"type":["string","null"]},"website":{"type":["string","null"]},"hoursOfOperation":{"type":["string","null"]},"isActive":{"type":"boolean","description":"Whether this utility is currently active in the catalog."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom field values keyed by property keyName. This includes only customer-defined custom columns (see GET /properties?record_type=utility). Built-in catalog utility fields (name, state, ownershipType, holdingCompany, etc.) are exposed as top-level fields on the utility object and are read-only."}},"description":"A utility. Most fields are read-only catalog data sourced from the HIFLD dataset; only fields under `custom` are user-editable.","title":"Utility"},"UtilitiesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"UtilitiesGetResponsesContentApplicationJsonSchemaCode"},"List-utilitiesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"List-utilitiesRequestBadRequestError"},"List-utilitiesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesGetResponsesContentApplicationJsonSchemaCode"}},"title":"List-utilitiesRequestUnauthorizedError"},"List-utilitiesRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesGetResponsesContentApplicationJsonSchemaCode"}},"title":"List-utilitiesRequestBadGatewayError"},"UtilitiesUtilityIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"UtilitiesUtilityIdGetResponsesContentApplicationJsonSchemaCode"},"GetUtilityRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetUtilityRequestUnauthorizedError"},"GetUtilityRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetUtilityRequestNotFoundError"},"GetUtilityRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetUtilityRequestBadGatewayError"},"UtilityUpdate":{"type":"object","properties":{"custom":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Custom field values keyed by property keyName. Pass `null` to clear a value. Unknown keyNames are rejected with a 400 — fetch valid keys via GET /properties?record_type=utility."}},"required":["custom"],"title":"UtilityUpdate"},"UtilitiesUtilityIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"UtilitiesUtilityIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateUtilityRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateUtilityRequestBadRequestError"},"UpdateUtilityRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateUtilityRequestUnauthorizedError"},"UpdateUtilityRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateUtilityRequestNotFoundError"},"UpdateUtilityRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/UtilitiesUtilityIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateUtilityRequestBadGatewayError"},"ContactsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ContactsGetParametersUpdatedAfter"},"ContactsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ContactsGetParametersUpdatedBefore"},"ContactsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ContactsGetParametersOrderBy"},"ContactCreatedByUser":{"type":"object","properties":{"id":{"type":"integer","description":"User identifier"}},"title":"ContactCreatedByUser"},"ContactRelatedRecordRef":{"type":"object","properties":{"id":{"type":"integer","description":"Record identifier"},"title":{"type":"string","description":"Record title"}},"title":"ContactRelatedRecordRef"},"Contact":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"name":{"type":"string","description":"Contact's full name"},"phones":{"type":"array","items":{"type":"string"},"description":"List of contact phone numbers"},"emails":{"type":"array","items":{"type":"string"},"description":"List of contact email addresses"},"title":{"type":["string","null"],"description":"Contact title"},"description":{"type":["string","null"],"description":"Contact description"},"createdByUser":{"$ref":"#/components/schemas/ContactCreatedByUser"},"accounts":{"type":"array","items":{"$ref":"#/components/schemas/ContactRelatedRecordRef"},"description":"List of linked accounts"},"projects":{"type":"array","items":{"$ref":"#/components/schemas/ContactRelatedRecordRef"},"description":"List of linked projects"},"opportunities":{"type":"array","items":{"$ref":"#/components/schemas/ContactRelatedRecordRef"},"description":"List of linked opportunities"},"vendors":{"type":"array","items":{"$ref":"#/components/schemas/ContactRelatedRecordRef"},"description":"List of linked vendors"}},"required":["name"],"title":"Contact"},"ContactsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ContactsGetResponsesContentApplicationJsonSchemaCode"},"ListContactsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListContactsRequestUnauthorizedError"},"ContactsContactIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ContactsContactIdGetResponsesContentApplicationJsonSchemaCode"},"GetContactRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetContactRequestUnauthorizedError"},"GetContactRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetContactRequestNotFoundError"},"ContactCreate":{"type":"object","properties":{"name":{"type":"string","description":"Contact's full name"},"phones":{"type":"array","items":{"type":"string"},"description":"List of contact phone numbers"},"emails":{"type":"array","items":{"type":"string"},"description":"List of contact email addresses"},"title":{"type":"string","description":"Contact title"},"accountIds":{"type":"array","items":{"type":"integer"},"description":"Account IDs to associate with the contact"},"projectIds":{"type":"array","items":{"type":"integer"},"description":"Project IDs to associate with the contact"}},"required":["name"],"title":"ContactCreate"},"ContactsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ContactsPostResponsesContentApplicationJsonSchemaCode"},"CreateContactRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateContactRequestBadRequestError"},"CreateContactRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateContactRequestUnauthorizedError"},"ContactUpdate":{"type":"object","properties":{"name":{"type":"string","description":"Contact's full name"},"phones":{"type":"array","items":{"type":"string"},"description":"List of contact phone numbers"},"emails":{"type":"array","items":{"type":"string"},"description":"List of contact email addresses"},"title":{"type":"string","description":"Contact title"},"accountIds":{"type":"array","items":{"type":"integer"},"description":"Account IDs to associate with the contact"},"projectIds":{"type":"array","items":{"type":"integer"},"description":"Project IDs to associate with the contact"}},"title":"ContactUpdate"},"ContactsContactIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ContactsContactIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateContactRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateContactRequestBadRequestError"},"UpdateContactRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateContactRequestUnauthorizedError"},"UpdateContactRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateContactRequestNotFoundError"},"ContactsContactIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ContactsContactIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteContactRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteContactRequestUnauthorizedError"},"DeleteContactRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ContactsContactIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteContactRequestNotFoundError"},"NoteListItemCreatedByUser":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"}},"title":"NoteListItemCreatedByUser"},"NoteListItem":{"type":"object","properties":{"id":{"type":"integer"},"note":{"type":"string"},"createdByUser":{"$ref":"#/components/schemas/NoteListItemCreatedByUser"},"createdAt":{"type":"string","format":"date-time"}},"title":"NoteListItem"},"ListNotesResponse":{"type":"object","properties":{"notes":{"type":"array","items":{"$ref":"#/components/schemas/NoteListItem"}},"totalCount":{"type":"integer"}},"title":"ListNotesResponse"},"ProjectsProjectIdNotesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdNotesGetResponsesContentApplicationJsonSchemaCode"},"ListProjectNotesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdNotesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectNotesRequestUnauthorizedError"},"ListProjectNotesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdNotesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectNotesRequestNotFoundError"},"WorkOrderNoteAuthor":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"email":{"type":["string","null"]}},"title":"WorkOrderNoteAuthor"},"WorkOrderNoteListItem":{"type":"object","properties":{"id":{"type":"integer"},"note":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"createdByUser":{"oneOf":[{"$ref":"#/components/schemas/WorkOrderNoteAuthor"},{"type":"null"}]}},"title":"WorkOrderNoteListItem"},"Notes_listWorkOrderNotes_Response_200":{"type":"object","properties":{"notes":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderNoteListItem"}},"totalCount":{"type":"integer","description":"Total number of notes for this work order"}},"title":"Notes_listWorkOrderNotes_Response_200"},"WorkOrdersWorkOrderIdNotesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"WorkOrdersWorkOrderIdNotesGetResponsesContentApplicationJsonSchemaCode"},"ListWorkOrderNotesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListWorkOrderNotesRequestBadRequestError"},"ListWorkOrderNotesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListWorkOrderNotesRequestUnauthorizedError"},"ListWorkOrderNotesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListWorkOrderNotesRequestNotFoundError"},"NoteCreate":{"type":"object","properties":{"body":{"type":"string","description":"Note text content.\n\nTo mention (@) a user, team, or AI agent, embed a mention token directly in the body string using the format `[Display Name|~id:USER_ID]`. The display-name portion is cosmetic; the trailing token is what drives the mention. A valid mention creates a feed notification (and downstream channels) for the mentioned recipient(s).\n\nSupported tokens:\n- User: `[Display Name|~id:USER_ID]` — e.g. `Please review [Nicolaus Copernicus|~id:99001]`\n- Team: `[Team Name|~team:TEAM_ID]` — notifies all team members\n- AI agent: `[Name|~agent:slug]`\n\nNote: the author is excluded from their own mention notifications, so mentioning the same user the API key authenticates as will not fire a notification. Mention a different user to test.\n"},"replyToId":{"type":"integer","description":"ID of the parent note to reply to. When provided, the new note is created as a threaded reply under the specified note."}},"required":["body"],"title":"NoteCreate"},"NoteCreateResponse":{"type":"object","properties":{"id":{"type":"integer","description":"Note identifier"},"note":{"type":"string","description":"Note text content"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["id","note","createdAt","updatedAt"],"description":"Response returned when a note is created. Does not include author details; retrieve them from the corresponding note list endpoint (e.g., GET `/projects/{project_id}/notes` or GET `/accounts/{account_id}/notes`).","title":"NoteCreateResponse"},"ProjectsProjectIdNotesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdNotesPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectNoteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdNotesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectNoteRequestBadRequestError"},"CreateProjectNoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdNotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectNoteRequestUnauthorizedError"},"CreateProjectNoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdNotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectNoteRequestNotFoundError"},"NoteCreateOnWorkOrderResponse":{"type":"object","properties":{"id":{"type":"integer","description":"Note identifier"},"note":{"type":"string","description":"Note text content"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"}},"required":["id","note","createdAt","updatedAt"],"description":"Response returned when a note is created on a work order.","title":"NoteCreateOnWorkOrderResponse"},"WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["RATE_LIMIT_EXCEEDED"],"title":"WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode"},"CreateWorkOrderNoteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateWorkOrderNoteRequestBadRequestError"},"CreateWorkOrderNoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderNoteRequestUnauthorizedError"},"CreateWorkOrderNoteRequestForbiddenError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderNoteRequestForbiddenError"},"CreateWorkOrderNoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderNoteRequestNotFoundError"},"CreateWorkOrderNoteRequestTooManyRequestsError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdNotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderNoteRequestTooManyRequestsError"},"NoteUpdate":{"type":"object","properties":{"body":{"type":"string","description":"Updated note text content.\n\nMention (@) tokens are supported in the body string using the format `[Display Name|~id:USER_ID]` (users), `[Team Name|~team:TEAM_ID]` (teams, notifies all members), or `[Name|~agent:slug]` (AI agents). The display-name portion is cosmetic; the trailing token drives the mention. A valid mention creates a feed notification for the mentioned recipient(s). The author is excluded from their own mention notifications.\n"}},"required":["body"],"title":"NoteUpdate"},"NoteAuthor":{"type":"object","properties":{"id":{"type":"integer","description":"Author identifier"},"firstName":{"type":"string","description":"Author first name"},"lastName":{"type":"string","description":"Author last name"},"email":{"type":"string","description":"Author email"},"phone":{"type":"string","description":"Author phone"},"avatarUrl":{"type":"string","description":"Author avatar URL"}},"title":"NoteAuthor"},"Note":{"type":"object","properties":{"id":{"type":"integer","description":"Note identifier"},"note":{"type":"string","description":"Note text content"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"author":{"$ref":"#/components/schemas/NoteAuthor"}},"required":["id","note","createdAt","updatedAt"],"title":"Note"},"NotesNoteIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"NotesNoteIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateNoteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/NotesNoteIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateNoteRequestBadRequestError"},"UpdateNoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/NotesNoteIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateNoteRequestUnauthorizedError"},"UpdateNoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/NotesNoteIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateNoteRequestNotFoundError"},"NotesNoteIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"NotesNoteIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteNoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/NotesNoteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteNoteRequestUnauthorizedError"},"DeleteNoteRequestForbiddenError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/NotesNoteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteNoteRequestForbiddenError"},"DeleteNoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/NotesNoteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteNoteRequestNotFoundError"},"WorkOrdersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"WorkOrdersGetParametersUpdatedAfter"},"WorkOrdersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"WorkOrdersGetParametersUpdatedBefore"},"WorkOrdersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"WorkOrdersGetParametersOrderBy"},"WorkOrderLabelsItemsLabel":{"type":"object","properties":{"id":{"type":"integer","description":"Label identifier"},"label":{"type":"string","description":"Label name"},"color":{"type":"string","description":"Label color (hex code)"}},"title":"WorkOrderLabelsItemsLabel"},"WorkOrderLabelsItems":{"type":"object","properties":{"label":{"$ref":"#/components/schemas/WorkOrderLabelsItemsLabel"}},"title":"WorkOrderLabelsItems"},"WorkOrderProject":{"type":"object","properties":{"id":{"type":"integer","description":"Project identifier"},"uid":{"type":"integer","description":"Project number"},"title":{"type":"string","description":"Project title"},"address":{"type":"array","items":{"type":"string"},"description":"Project address"},"stage":{"type":["string","null"],"description":"Project stage (if available)"}},"description":"Project associated with the work order","title":"WorkOrderProject"},"WorkOrderAssignee":{"type":"object","properties":{"id":{"type":"integer","description":"User identifier"},"firstName":{"type":"string","description":"User's first name"},"lastName":{"type":"string","description":"User's last name"},"email":{"type":"string","description":"User's email address"}},"description":"User assigned to the work order","title":"WorkOrderAssignee"},"Visit":{"type":"object","properties":{"id":{"type":"integer","description":"Visit identifier"},"description":{"type":["string","null"],"description":"Free-text note on the visit, as written by `PATCH /projects/{project_id}/work-orders/{work_order_id}`. `null` when none was set."},"startDate":{"type":["string","null"],"format":"date-time"},"endDate":{"type":["string","null"],"format":"date-time"},"startDateAllDay":{"type":"boolean","default":false},"endDateAllDay":{"type":"boolean","default":false},"isCompleted":{"type":"boolean"}},"description":"Only applicable on field work orders.","title":"Visit"},"WorkOrderVisits":{"type":"object","properties":{"visits":{"type":"array","items":{"$ref":"#/components/schemas/Visit"},"description":"List of visits"}},"description":"Site visits associated with the work order (legacy shape)","title":"WorkOrderVisits"},"WorkOrderStatusesItems":{"type":"object","properties":{"count":{"type":"string","description":"Number of times this status was entered"},"endedAt":{"type":"string","format":"date-time","description":"When the status ended"},"spentTime":{"type":"number","format":"double","description":"Time spent in this status in seconds"},"startedAt":{"type":"string","format":"date-time","description":"When the status started"},"status":{"type":"string","description":"Status identifier"}},"title":"WorkOrderStatusesItems"},"WorkOrderStatus":{"type":"object","properties":{"id":{"type":["string","null"],"description":"Status identifier"},"label":{"type":["string","null"],"description":"Human readable status label"}},"description":"Current status of the work order","title":"WorkOrderStatus"},"ChecklistItem":{"type":"object","properties":{"id":{"type":"integer","description":"Checklist item identifier"},"detail":{"type":"string","description":"Checklist task detail"},"isCompleted":{"type":"boolean","description":"Whether the checklist item is completed"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Completion timestamp, if completed"}},"title":"ChecklistItem"},"WorkOrderFormItemType":{"type":"string","enum":["FORM"],"title":"WorkOrderFormItemType"},"WorkOrderFileRequestItemType":{"type":"string","enum":["FILE_REQUEST"],"title":"WorkOrderFileRequestItemType"},"WorkOrderWorkItem":{"oneOf":[{"type":"object","properties":{"type":{"$ref":"#/components/schemas/WorkOrderFormItemType"},"id":{"type":"integer","description":"Form instance ID"},"name":{"type":["string","null"],"description":"Form name"},"templateId":{"type":["integer","null"],"description":"Template the form was created from"},"dueDate":{"type":["string","null"],"format":"date-time","description":"Due date ISO string"},"status":{"type":["string","null"],"description":"Form status (e.g. OPEN, IN_PROGRESS, COMPLETED)"},"isCompleted":{"type":"boolean"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["type","id"],"description":"A form work item linked to the work order via Blueprint workflow."},{"type":"object","properties":{"type":{"$ref":"#/components/schemas/WorkOrderFileRequestItemType"},"id":{"type":"integer","description":"Action instance ID"},"name":{"type":["string","null"],"description":"File request title"},"status":{"type":["string","null"],"description":"Element instance status (e.g. OPEN, IN_PROGRESS, COMPLETED)"}},"required":["type","id"],"description":"A file request (document upload) work item linked to the work order via Blueprint workflow."}],"discriminator":{"propertyName":"type"},"title":"WorkOrderWorkItem"},"WorkOrderLineItemCatalogItem":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"sku":{"type":["string","null"]},"type":{"type":["string","null"]},"manufacturer":{"type":["string","null"]}},"title":"WorkOrderLineItemCatalogItem"},"WorkOrderLineItem":{"type":"object","properties":{"id":{"type":"integer"},"quantity":{"type":"integer"},"description":{"type":["string","null"]},"unitCost":{"type":"number","format":"double"},"totalCost":{"type":["number","null"],"format":"double"},"unitPrice":{"type":"number","format":"double"},"totalPrice":{"type":["number","null"],"format":"double"},"sectionName":{"type":["string","null"]},"catalogItem":{"oneOf":[{"$ref":"#/components/schemas/WorkOrderLineItemCatalogItem"},{"type":"null"}]}},"title":"WorkOrderLineItem"},"WorkOrder":{"type":"object","properties":{"id":{"type":"integer","description":"Work order identifier"},"uid":{"type":"integer","description":"Unique work order number within the project"},"templateId":{"type":"integer","description":"Template identifier for the work order"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"title":{"type":"string","description":"Work order title"},"description":{"type":"string","description":"Work order description"},"priority":{"type":"integer","description":"Priority level"},"startDate":{"type":["string","null"],"format":"date-time","description":"Scheduled start date"},"startDateAllDay":{"type":"boolean","description":"Whether the start date is an all-day event"},"endDate":{"type":["string","null"],"format":"date-time","description":"Scheduled end date"},"endDateAllDay":{"type":"boolean","description":"Whether the end date is an all-day event"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Timestamp when the work order was completed"},"isActive":{"type":"boolean","description":"Whether the work order is active (not archived)"},"isArchived":{"type":"boolean","description":"Deprecated: use `isActive` instead. Kept for backward compatibility.","deprecated":true},"isCompleted":{"type":"boolean","description":"Whether the work order is completed"},"isField":{"type":"boolean","description":"Whether the work order is a field task"},"labels":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderLabelsItems"},"description":"Labels associated with the work order"},"project":{"$ref":"#/components/schemas/WorkOrderProject","description":"Project associated with the work order"},"assignee":{"oneOf":[{"$ref":"#/components/schemas/WorkOrderAssignee"},{"type":"null"}],"description":"User assigned to the work order"},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/UserSummary"},"description":"Additional users collaborating on the work order"},"visits":{"$ref":"#/components/schemas/WorkOrderVisits","description":"Site visits associated with the work order (legacy shape)"},"statuses":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderStatusesItems"},"description":"History of status changes and time spent in each status"},"status":{"oneOf":[{"$ref":"#/components/schemas/WorkOrderStatus"},{"type":"null"}],"description":"Current status of the work order"},"checklist":{"type":"array","items":{"$ref":"#/components/schemas/ChecklistItem"},"description":"Checklist items for the work order"},"workItems":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderWorkItem"},"description":"Work items linked to this work order via Blueprint workflow. Includes forms (`FORM`) and file requests (`FILE_REQUEST`). Returns [] when none are linked."},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderLineItem"},"description":"Present only for service work orders on an **account** (parent project type `ACCOUNT`), and only when at least one line item exists.\nAmounts are in dollars with cent precision. Replace via `PUT /work-orders/{work_order_id}/line-items`.\nOmitted from the response when not applicable or when there are no line items.\n"}},"title":"WorkOrder"},"WorkOrdersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"WorkOrdersGetResponsesContentApplicationJsonSchemaCode"},"ListWorkOrdersRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListWorkOrdersRequestUnauthorizedError"},"ProjectsProjectIdWorkOrdersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdWorkOrdersGetParametersUpdatedAfter"},"ProjectsProjectIdWorkOrdersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdWorkOrdersGetParametersUpdatedBefore"},"ProjectsProjectIdWorkOrdersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ProjectsProjectIdWorkOrdersGetParametersOrderBy"},"ProjectsProjectIdWorkOrdersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdWorkOrdersGetResponsesContentApplicationJsonSchemaCode"},"ListProjectWorkOrdersRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectWorkOrdersRequestUnauthorizedError"},"ListProjectWorkOrdersRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectWorkOrdersRequestNotFoundError"},"OpportunitiesOpportunityIdWorkOrdersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdWorkOrdersGetParametersUpdatedAfter"},"OpportunitiesOpportunityIdWorkOrdersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdWorkOrdersGetParametersUpdatedBefore"},"OpportunitiesOpportunityIdWorkOrdersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"OpportunitiesOpportunityIdWorkOrdersGetParametersOrderBy"},"AccountsAccountIdWorkOrdersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsAccountIdWorkOrdersGetParametersUpdatedAfter"},"AccountsAccountIdWorkOrdersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsAccountIdWorkOrdersGetParametersUpdatedBefore"},"AccountsAccountIdWorkOrdersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"AccountsAccountIdWorkOrdersGetParametersOrderBy"},"WorkOrdersWorkOrderIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"WorkOrdersWorkOrderIdGetResponsesContentApplicationJsonSchemaCode"},"GetWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetWorkOrderRequestUnauthorizedError"},"GetWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetWorkOrderRequestNotFoundError"},"TemplateUser":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]}},"description":"A user reference reduced to non-sensitive identity fields.","title":"TemplateUser"},"WorkOrderTemplateLabelsItemsLabel":{"type":"object","properties":{"id":{"type":["integer","null"]},"label":{"type":["string","null"]},"color":{"type":["string","null"]}},"title":"WorkOrderTemplateLabelsItemsLabel"},"WorkOrderTemplateLabelsItems":{"type":"object","properties":{"label":{"$ref":"#/components/schemas/WorkOrderTemplateLabelsItemsLabel"}},"title":"WorkOrderTemplateLabelsItems"},"WorkOrderTemplateChecklistsItems":{"type":"object","properties":{"id":{"type":"integer"},"detail":{"type":["string","null"]}},"title":"WorkOrderTemplateChecklistsItems"},"TradeGroup":{"type":"string","enum":["ENERGY","MECHANICAL","ELECTRICAL","PLUMBING","LOW_VOLTAGE","ENVELOPE","OTHER"],"description":"High-level trade group for catalog items.","title":"TradeGroup"},"CatalogItemType":{"type":"string","enum":["PRODUCT","SERVICE"],"description":"Catalog item type","title":"CatalogItemType"},"ProductCategory":{"type":"string","enum":["BATTERY_SYSTEM","BATTERY_MANAGEMENT_SYSTEM","CHARGING_GATEWAY","COMBINER_BOX","EV_CHARGER","LOAD_CENTER","MICROINVERTER","MOUNTING","POWER_OPTIMIZER","PRODUCTION_METER","PV_INVERTER","PV_MODULE","RACKING","RAPID_SHUTDOWN_DEVICE","TRACKER","WEATHER_STATION","AIR_CONDITIONER","AIR_HANDLING_UNIT","BOILER","CHILLER","COOLING_TOWER","FAN","HEAT_EXCHANGER","HEAT_PUMP","MAKE_UP_AIR_UNIT","PUMP","ROOFTOP_UNIT","THERMOSTAT","VARIABLE_FREQUENCY_DRIVE","AUTOMATIC_TRANSFER_SWITCH","BREAKER","DISCONNECT_SWITCH","ELECTRIC_METER","GENERATOR","LIGHTING_PANEL","PANELBOARD","SWITCHGEAR","TRANSFORMER","UNINTERRUPTIBLE_POWER_SUPPLY","WIRE","BACKFLOW_PREVENTER","BOOSTER_PUMP","GREASE_INTERCEPTOR","STORAGE_TANK","SUMP_PUMP","VALVE","WATER_FILTRATION_SYSTEM","WATER_HEATER","WATER_SOFTENER","ACCESS_CONTROLLER","AUTOMATION_CONTROLLER","CAMERA","CARD_READER","DOOR_STRIKE","MAGLOCK","NETWORK_SWITCH","NETWORK_VIDEO_RECORDER","SENSOR","WIRELESS_ACCESS_POINT","ROOF_COVERING","ROOF_UNDERLAYMENT","ROOF_MEMBRANE","ROOF_FLASHING","ROOF_VENT","WALL_CLADDING","WALL_TRIM","WEATHER_BARRIER","WINDOW","EXTERIOR_DOOR","SKYLIGHT","OPENING_FLASHING","GUTTER","DOWNSPOUT","INSULATION","SEALANT","SHEATHING","OTHER"],"description":"Product catalog category.","title":"ProductCategory"},"ServiceCategory":{"type":"string","enum":["ADJUSTMENT","BALANCING","CALIBRATION","CLEANING","COMMISSIONING","DECOMMISSIONING","DIAGNOSTICS","ENGINEERING","EQUIPMENT_RENTAL","INSPECTION","INSTALLATION","MAINTENANCE","MONITORING","OPTIMIZATION","PERMITTING","RELOCATION","REMOVAL","REPAIR","REPLACEMENT","RETROFIT","SITE_SURVEY","TESTING","TRAINING","OTHER"],"description":"Service catalog category.","title":"ServiceCategory"},"CatalogCategoryCode":{"oneOf":[{"$ref":"#/components/schemas/ProductCategory"},{"$ref":"#/components/schemas/ServiceCategory"}],"description":"Catalog item category code.\nMust be:\n- one of `ProductCategory` when `type` is `PRODUCT`, or\n- one of `ServiceCategory` when `type` is `SERVICE`.\n","title":"CatalogCategoryCode"},"CatalogItemImage":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"url":{"type":"string","description":"URL to download the image"}},"title":"CatalogItemImage"},"CatalogUnitDimension":{"type":"string","enum":["LENGTH","AREA","COUNT"],"description":"The physical dimension this unit measures, if any. Null for packaging-style units (e.g. bundle, roll) that can't be used on a measurement.","title":"CatalogUnitDimension"},"CatalogUnit":{"type":"object","properties":{"id":{"type":"integer","description":"Catalog unit identifier"},"code":{"type":"string","description":"Stable short code for the unit (e.g. \"SF\", \"EA\")"},"label":{"type":"string","description":"Human-readable label for the unit (e.g. \"Square Feet\")"},"dimension":{"oneOf":[{"$ref":"#/components/schemas/CatalogUnitDimension"},{"type":"null"}],"description":"The physical dimension this unit measures, if any. Null for packaging-style units (e.g. bundle, roll) that can't be used on a measurement."},"isCustom":{"type":"boolean","description":"Whether this unit was defined by the company, as opposed to one of the seeded defaults."},"isArchived":{"type":"boolean","description":"Whether this unit has been archived."}},"required":["id","code","label"],"description":"A unit of measure from the company's unit registry (e.g. Each, Square Feet, Linear Feet). Referenced by catalog items and measurements via `unitId`.","title":"CatalogUnit"},"MeasurementType":{"type":"string","enum":["MEASUREMENT","SUB_CALCULATION"],"description":"A plain MEASUREMENT is a raw input value; a SUB_CALCULATION (\"sub-measurement\") derives its value from a formula over other measurements.","title":"MeasurementType"},"MeasurementFormulaOperandsItems":{"type":"object","properties":{"name":{"type":"string"},"measurementId":{"type":"integer"}},"title":"MeasurementFormulaOperandsItems"},"MeasurementFormulaAst":{"type":"object","properties":{},"description":"Binary-operation AST node or leaf. See the formula description above.","title":"MeasurementFormulaAst"},"MeasurementFormula":{"type":"object","properties":{"operands":{"type":"array","items":{"$ref":"#/components/schemas/MeasurementFormulaOperandsItems"}},"ast":{"$ref":"#/components/schemas/MeasurementFormulaAst","description":"Binary-operation AST node or leaf. See the formula description above."},"sourceText":{"type":"string","description":"The formula as originally authored (e.g. \"( m1 + m2 ) / 100\")"}},"description":"The formula driving a SUB_CALCULATION measurement's quantity. Read-only — there is no API to create or edit a measurement's formula; it can only be authored in the app. Shape: `operands` names each referenced measurement (`{name, measurementId}`); `ast` is a binary-operation tree (`ADD`/`SUB`/`MUL`/`DIV`) whose leaves are either `{operandRef}` (referencing an entry in `operands` by name) or `{constant}` (a literal number); `sourceText` is the original formula text as authored.\n","title":"MeasurementFormula"},"Measurement":{"type":"object","properties":{"id":{"type":"integer","description":"Measurement identifier"},"name":{"type":"string","description":"Measurement name"},"type":{"$ref":"#/components/schemas/MeasurementType","description":"A plain MEASUREMENT is a raw input value; a SUB_CALCULATION (\"sub-measurement\") derives its value from a formula over other measurements."},"unit":{"oneOf":[{"$ref":"#/components/schemas/CatalogUnit"},{"type":"null"}],"description":"The unit this measurement is expressed in, if any."},"minimumValue":{"type":["number","null"],"format":"double","description":"Minimum allowed value. Only meaningful for type MEASUREMENT."},"formula":{"$ref":"#/components/schemas/MeasurementFormula"},"isArchived":{"type":"boolean","description":"Whether this measurement has been archived."}},"required":["id","name","type"],"description":"A named measurement or sub-calculation that a catalog item can link to (via `measurementIds`) to drive its quantity. A \"sub-measurement\" is simply a Measurement with `type: SUB_CALCULATION` — not a separate structure.\n","title":"Measurement"},"CatalogItemWasteFactorMode":{"type":"string","enum":["STATIC"],"description":"Waste factor mode applied when computing this item's quantity. Currently only STATIC is supported. Paired with wasteFactorValue — both are set, or neither.","title":"CatalogItemWasteFactorMode"},"CatalogItem":{"type":"object","properties":{"id":{"type":"integer","description":"Catalog item identifier"},"name":{"type":"string","description":"Catalog item name"},"catalog":{"oneOf":[{"$ref":"#/components/schemas/TradeGroup"},{"type":"null"}],"description":"High-level trade group for this item."},"type":{"$ref":"#/components/schemas/CatalogItemType","description":"Catalog item type"},"category":{"$ref":"#/components/schemas/CatalogCategoryCode","description":"Catalog item category code (ProductCategory or ServiceCategory)"},"manufacturer":{"type":["string","null"],"description":"Catalog item manufacturer"},"sku":{"type":["string","null"],"description":"Catalog item SKU"},"code":{"type":["string","null"],"description":"Catalog item code"},"cost":{"type":["number","null"],"format":"double","minimum":0,"description":"Catalog item cost"},"price":{"type":["number","null"],"format":"double","minimum":0,"description":"Catalog item price"},"description":{"type":["string","null"],"description":"Catalog item description"},"image":{"oneOf":[{"$ref":"#/components/schemas/CatalogItemImage"},{"type":"null"}]},"isArchived":{"type":["boolean","null"],"description":"Whether the catalog item is archived"},"createdById":{"type":"integer","description":"Identifier of the user who created the catalog item"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"preferredVendorId":{"type":["integer","null"],"description":"ID of the preferred vendor (must be an existing active vendor for this company)"},"unit":{"oneOf":[{"$ref":"#/components/schemas/CatalogUnit"},{"type":"null"}],"description":"The unit this item is sold/measured in, if any. Set on write via `unitId`."},"measurements":{"type":"array","items":{"$ref":"#/components/schemas/Measurement"},"description":"Measurements (and sub-measurements) linked to this item to drive its quantity calculation. A sub-measurement is a linked Measurement with `type SUB_CALCULATION`; at most one may be linked, and it must be the only link when present."},"coverage":{"type":["number","null"],"format":"double","description":"Measurement units covered per item unit (e.g. a bundle covering ~33.33 SF). Used to size quantity from summed linked measurements; not used when the item is linked to a sub-calculation, which derives quantity from its own formula."},"wasteFactorMode":{"oneOf":[{"$ref":"#/components/schemas/CatalogItemWasteFactorMode"},{"type":"null"}],"description":"Waste factor mode applied when computing this item's quantity. Currently only STATIC is supported. Paired with wasteFactorValue — both are set, or neither."},"wasteFactorValue":{"type":["number","null"],"format":"double","description":"Waste factor percentage (0-100) applied when computing this item's quantity. Paired with wasteFactorMode."}},"required":["id","name","catalog","type","category","cost","price"],"title":"CatalogItem"},"WorkOrderTemplateLineItemsItems":{"type":"object","properties":{"id":{"type":"integer"},"quantity":{"type":"number","format":"double"},"description":{"type":["string","null"]},"unitCost":{"type":"number","format":"double"},"totalCost":{"type":"number","format":"double"},"unitPrice":{"type":"number","format":"double"},"totalPrice":{"type":"number","format":"double"},"catalogItem":{"oneOf":[{"$ref":"#/components/schemas/CatalogItem"},{"type":"null"}],"description":"The linked catalog item, in the same shape as GET /catalog-items/{catalogItemId}."}},"title":"WorkOrderTemplateLineItemsItems"},"WorkOrderTemplate":{"type":"object","properties":{"id":{"type":"integer","description":"Template identifier"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"title":{"type":["string","null"],"description":"Template title"},"description":{"type":["string","null"],"description":"Template description"},"instructions":{"type":["string","null"],"description":"Template instructions (same text as description)"},"type":{"type":["string","null"],"description":"Work order type (e.g. FIELD, OFFICE)"},"priority":{"type":["integer","null"]},"dueDate":{"type":["string","null"],"description":"Deadline for work orders created from this template"},"yellowSla":{"type":["integer","null"],"description":"Yellow SLA threshold (days)"},"redSla":{"type":["integer","null"],"description":"Red SLA threshold (days)"},"assignee":{"oneOf":[{"$ref":"#/components/schemas/TemplateUser"},{"type":"null"}]},"assigneeProperty":{"type":["string","null"],"description":"Set when the assignee is a role rather than a specific user (e.g. SALES_REP, PROJECT_MANAGER)."},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/TemplateUser"}},"collaboratorProperties":{"type":"array","items":{"type":"string"},"description":"Role-based collaborators (e.g. SALES_REP, PROJECT_MANAGER) as property keys."},"labels":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderTemplateLabelsItems"}},"checklists":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderTemplateChecklistsItems"}},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/WorkOrderTemplateLineItemsItems"},"description":"Present only when the template has line items."}},"title":"WorkOrderTemplate"},"WorkOrdersTemplatesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"WorkOrdersTemplatesGetResponsesContentApplicationJsonSchemaCode"},"ListWorkOrderTemplatesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersTemplatesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListWorkOrderTemplatesRequestUnauthorizedError"},"WorkOrderCreateResponse":{"type":"object","properties":{"id":{"type":"integer","description":"Created workflow element (task) identifier"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"description":{"type":["string","null"]},"position":{"type":"integer","description":"Position within phase"},"phaseInstanceId":{"type":"integer"},"projectId":{"type":"integer"},"createdById":{"type":"integer"}},"title":"WorkOrderCreateResponse"},"ProjectsProjectIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectWorkOrderRequestBadRequestError"},"CreateProjectWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectWorkOrderRequestUnauthorizedError"},"CreateProjectWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectWorkOrderRequestNotFoundError"},"OpportunitiesOpportunityIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityWorkOrderRequestBadRequestError"},"CreateOpportunityWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityWorkOrderRequestUnauthorizedError"},"CreateOpportunityWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityWorkOrderRequestNotFoundError"},"AccountsAccountIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsAccountIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"},"CreateAccountWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateAccountWorkOrderRequestBadRequestError"},"CreateAccountWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateAccountWorkOrderRequestUnauthorizedError"},"VisitUpsert":{"type":"object","properties":{"id":{"type":"integer","description":"Include to update an existing visit; omit to create new. When `visits` is sent, any existing visit not included will be deleted."},"description":{"type":"string"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"},"startDateAllDay":{"type":"boolean","default":false},"endDateAllDay":{"type":"boolean","default":false},"isCompleted":{"type":"boolean"}},"description":"Shape used to create or update visits in work order PATCH requests.","title":"VisitUpsert"},"ChecklistItemUpdate":{"type":"object","properties":{"id":{"type":"integer","description":"Checklist item identifier to update (required)."},"detail":{"type":"string","description":"New detail text."},"isCompleted":{"type":"boolean","description":"Completion flag."}},"required":["id"],"description":"Checklist item update payload. Only fields provided are updated.","title":"ChecklistItemUpdate"},"WorkOrderUpdate":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"priority":{"type":"integer"},"startDate":{"type":"string","format":"date-time"},"startDateAllDay":{"type":"boolean"},"endDate":{"type":"string","format":"date-time"},"endDateAllDay":{"type":"boolean"},"status":{"type":"string","description":"Status label"},"assigneeId":{"type":"integer","description":"User identifier to assign to the work order"},"collaborators":{"type":"array","items":{"type":"integer"},"description":"User identifiers to assign as collaborators to the work order"},"visits":{"type":"array","items":{"$ref":"#/components/schemas/VisitUpsert"},"description":"Only applicable on field work orders. When provided, the `visits` array REPLACES the full set of visits for the work order. Include all existing visits you wish to keep or update (with their `id`), and include new visits without an `id`. Any existing visit not included in the request will be removed. Visit booleans default to false when omitted."},"checklist":{"type":"array","items":{"$ref":"#/components/schemas/ChecklistItemUpdate"},"description":"Update the checklist for the work order.\nWhen this field is provided, the `checklist` array REPLACES the full set of checklist items on the work order.\n- Include every existing item you want to keep or modify (identified by `id`). \n- Any existing item NOT included in this array will be removed.\n- Each item MUST include an `id`. Items without an `id` are ignored (checklist item creation is not supported).\n"},"isActive":{"type":["boolean","null"],"description":"Set to `false` to archive the work order, or `true` to unarchive it. Applied independently of any other fields present in the same request."}},"description":"Payload for updating a work order. Supports partial updates.","title":"WorkOrderUpdate"},"ProjectsProjectIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateProjectWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateProjectWorkOrderRequestBadRequestError"},"UpdateProjectWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateProjectWorkOrderRequestUnauthorizedError"},"UpdateProjectWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateProjectWorkOrderRequestNotFoundError"},"OpportunitiesOpportunityIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateOpportunityWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateOpportunityWorkOrderRequestBadRequestError"},"UpdateOpportunityWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateOpportunityWorkOrderRequestUnauthorizedError"},"UpdateOpportunityWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateOpportunityWorkOrderRequestNotFoundError"},"AccountsAccountIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AccountsAccountIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateAccountWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateAccountWorkOrderRequestBadRequestError"},"UpdateAccountWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAccountWorkOrderRequestUnauthorizedError"},"UpdateAccountWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersWorkOrderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAccountWorkOrderRequestNotFoundError"},"DeleteProjectWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"title":"DeleteProjectWorkOrderRequestBadRequestError"},"ProjectsProjectIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteProjectWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteProjectWorkOrderRequestUnauthorizedError"},"DeleteProjectWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteProjectWorkOrderRequestNotFoundError"},"OpportunitiesOpportunityIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteOpportunityWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"DeleteOpportunityWorkOrderRequestBadRequestError"},"DeleteOpportunityWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteOpportunityWorkOrderRequestUnauthorizedError"},"DeleteOpportunityWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteOpportunityWorkOrderRequestNotFoundError"},"AccountsAccountIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AccountsAccountIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteAccountWorkOrderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"DeleteAccountWorkOrderRequestBadRequestError"},"DeleteAccountWorkOrderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteAccountWorkOrderRequestUnauthorizedError"},"DeleteAccountWorkOrderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdWorkOrdersWorkOrderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteAccountWorkOrderRequestNotFoundError"},"FileMetaDataGps":{"type":"object","properties":{},"description":"GPS coordinates if applicable","title":"FileMetaDataGps"},"FileMetaData":{"type":"object","properties":{"acl":{"type":"string","description":"Access control level"},"gps":{"$ref":"#/components/schemas/FileMetaDataGps","description":"GPS coordinates if applicable"},"size":{"type":"integer","description":"File size in bytes"},"userId":{"type":"integer","description":"User who uploaded the file"},"mimeType":{"type":"string","description":"MIME type of the file"},"extention":{"type":"string","description":"File extension"},"originalName":{"type":"string","description":"Original file name"},"thumbnailUrl":{"type":"string","description":"URL to the thumbnail version"},"generatedName":{"type":"string","description":"Generated unique file name"},"thumbnailName":{"type":"string","description":"Generated thumbnail file name"},"requestFileName":{"type":"string","description":"Original request file name"}},"required":["acl","size","userId","mimeType","extention","originalName","generatedName"],"title":"FileMetaData"},"FileCreatedByUser":{"type":"object","properties":{"id":{"type":"integer","description":"User identifier"},"firstName":{"type":"string","description":"User's first name"},"lastName":{"type":"string","description":"User's last name"}},"title":"FileCreatedByUser"},"File":{"type":"object","properties":{"id":{"type":"integer","description":"File identifier"},"name":{"type":"string","description":"File name"},"downloadUrl":{"type":"string","description":"URL to download the file"},"type":{"type":"string","description":"File type"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"isArchived":{"type":"boolean","description":"Whether the file is archived"},"metaData":{"$ref":"#/components/schemas/FileMetaData"},"source":{"type":"string","description":"File source (e.g., INTERNAL)"},"createdByUser":{"$ref":"#/components/schemas/FileCreatedByUser"}},"required":["id","name","downloadUrl","type","updatedAt","createdAt","metaData","source","createdByUser"],"title":"File"},"ProjectsProjectIdFilesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"ProjectsProjectIdFilesGetResponsesContentApplicationJsonSchemaCode"},"GetProjectFilesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetProjectFilesRequestBadRequestError"},"GetProjectFilesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectFilesRequestNotFoundError"},"GetProjectFilesRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectFilesRequestInternalServerError"},"OpportunitiesOpportunityIdFilesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"OpportunitiesOpportunityIdFilesGetResponsesContentApplicationJsonSchemaCode"},"GetRequestFilesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetRequestFilesRequestBadRequestError"},"GetRequestFilesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetRequestFilesRequestNotFoundError"},"GetRequestFilesRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetRequestFilesRequestInternalServerError"},"AccountsAccountIdFilesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"AccountsAccountIdFilesGetResponsesContentApplicationJsonSchemaCode"},"GetAccountFilesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetAccountFilesRequestBadRequestError"},"GetAccountFilesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountFilesRequestNotFoundError"},"GetAccountFilesRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountFilesRequestInternalServerError"},"FilesFileIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"FilesFileIdGetResponsesContentApplicationJsonSchemaCode"},"GetFileRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetFileRequestBadRequestError"},"GetFileRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFileRequestNotFoundError"},"GetFileRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFileRequestInternalServerError"},"ProjectsProjectIdFilesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"ProjectsProjectIdFilesPostResponsesContentApplicationJsonSchemaCode"},"UploadProjectFileFromUrlRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UploadProjectFileFromUrlRequestBadRequestError"},"UploadProjectFileFromUrlRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadProjectFileFromUrlRequestNotFoundError"},"UploadProjectFileFromUrlRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadProjectFileFromUrlRequestInternalServerError"},"FileUploadResponseMetaDataGps":{"type":"object","properties":{},"description":"GPS coordinates if applicable","title":"FileUploadResponseMetaDataGps"},"FileUploadResponseMetaData":{"type":"object","properties":{"acl":{"type":"string","description":"Access control level"},"gps":{"$ref":"#/components/schemas/FileUploadResponseMetaDataGps","description":"GPS coordinates if applicable"},"size":{"type":"integer","description":"File size in bytes"},"userId":{"type":"integer","description":"User who uploaded the file"},"mimeType":{"type":"string","description":"MIME type of the file"},"extention":{"type":"string","description":"File extension"},"originalName":{"type":"string","description":"Original file name"},"thumbnailUrl":{"type":"string","description":"URL to the thumbnail version"},"generatedName":{"type":"string","description":"Generated unique file name"},"thumbnailName":{"type":"string","description":"Generated thumbnail file name"},"requestFileName":{"type":"string","description":"Original request file name"}},"required":["acl","size","userId","mimeType","extention","originalName","generatedName"],"title":"FileUploadResponseMetaData"},"FileUploadResponse":{"type":"object","properties":{"id":{"type":"integer","description":"File identifier"},"name":{"type":"string","description":"File name"},"downloadUrl":{"type":"string","description":"URL to download the file"},"metaData":{"$ref":"#/components/schemas/FileUploadResponseMetaData"}},"required":["id","name","downloadUrl","metaData"],"description":"Response returned after a successful file upload.","title":"FileUploadResponse"},"ProjectsProjectIdFilesUploadPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"ProjectsProjectIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"},"UploadProjectFileRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UploadProjectFileRequestBadRequestError"},"UploadProjectFileRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadProjectFileRequestNotFoundError"},"UploadProjectFileRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadProjectFileRequestInternalServerError"},"OpportunitiesOpportunityIdFilesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"OpportunitiesOpportunityIdFilesPostResponsesContentApplicationJsonSchemaCode"},"UploadRequestFileFromUrlRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UploadRequestFileFromUrlRequestBadRequestError"},"UploadRequestFileFromUrlRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadRequestFileFromUrlRequestNotFoundError"},"UploadRequestFileFromUrlRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadRequestFileFromUrlRequestInternalServerError"},"OpportunitiesOpportunityIdFilesUploadPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"OpportunitiesOpportunityIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"},"UploadRequestFileRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UploadRequestFileRequestBadRequestError"},"UploadRequestFileRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadRequestFileRequestNotFoundError"},"UploadRequestFileRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadRequestFileRequestInternalServerError"},"AccountsAccountIdFilesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"AccountsAccountIdFilesPostResponsesContentApplicationJsonSchemaCode"},"UploadAccountFileFromUrlRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UploadAccountFileFromUrlRequestBadRequestError"},"UploadAccountFileFromUrlRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadAccountFileFromUrlRequestNotFoundError"},"UploadAccountFileFromUrlRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadAccountFileFromUrlRequestInternalServerError"},"AccountsAccountIdFilesUploadPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"AccountsAccountIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"},"UploadAccountFileRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UploadAccountFileRequestBadRequestError"},"UploadAccountFileRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadAccountFileRequestNotFoundError"},"UploadAccountFileRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdFilesUploadPostResponsesContentApplicationJsonSchemaCode"}},"title":"UploadAccountFileRequestInternalServerError"},"FileUpdateResponseMetaData":{"type":"object","properties":{},"description":"File metadata (size, MIME type, etc.) — see the `File` schema for the full shape","title":"FileUpdateResponseMetaData"},"FileUpdateResponseCreatedByUser":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"title":"FileUpdateResponseCreatedByUser"},"FileUpdateResponse":{"type":"object","properties":{"id":{"type":"integer","description":"File identifier"},"name":{"type":"string","description":"File name"},"downloadUrl":{"type":"string","description":"URL to download the file"},"type":{"type":"string","description":"File type"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"companyId":{"type":"integer","description":"Owning company identifier"},"metaData":{"$ref":"#/components/schemas/FileUpdateResponseMetaData","description":"File metadata (size, MIME type, etc.) — see the `File` schema for the full shape"},"source":{"type":"string","description":"File source (e.g., INTERNAL)"},"isActive":{"type":"boolean","description":"Whether the file is active (false if archived)"},"folderId":{"type":["integer","null"],"description":"Folder this file is filed in, if any"},"phaseInstanceId":{"type":["integer","null"],"description":"Phase instance this file sits at the root of, if any"},"createdByUser":{"$ref":"#/components/schemas/FileUpdateResponseCreatedByUser"}},"required":["id","name","downloadUrl","type","updatedAt","createdAt","isActive"],"description":"Response from PATCH /files/{file_id}. Uses `isActive` (rather than `isArchived`, as on the `File` schema) and adds `folderId`/`phaseInstanceId` to reflect the file's current placement.","title":"FileUpdateResponse"},"FilesFileIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"FilesFileIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateFileRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateFileRequestBadRequestError"},"UpdateFileRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFileRequestNotFoundError"},"UpdateFileRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFileRequestInternalServerError"},"Files_deleteFile_Response_200":{"type":"object","properties":{},"description":"Empty response body","title":"Files_deleteFile_Response_200"},"FilesFileIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FilesFileIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteFileRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdDeleteResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"DeleteFileRequestBadRequestError"},"DeleteFileRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FilesFileIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteFileRequestNotFoundError"},"FolderListItemType":{"type":"string","enum":["folder"],"title":"FolderListItemType"},"FoldersListItem":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["phase"],"description":"Discriminator value: phase"},"id":{"type":"integer","description":"Phase instance identifier"},"name":{"type":"string","description":"Phase name"},"position":{"type":"integer","description":"Phase's position in the project's workflow"},"status":{"type":"string","description":"Phase status"},"phaseTemplateId":{"type":"integer","description":"Phase template this instance was created from"},"projectId":{"type":"integer","description":"Project this phase belongs to"},"createdAt":{"type":["string","null"],"format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"Last update timestamp"}},"required":["type","id","name","position","status","phaseTemplateId","projectId"],"description":"A virtual \"folder\" row synthesized from a workflow phase — not a real Folder database record. Use its `id` as `phase_instance_id` on GET /phases/{phase_instance_id}/contents."},{"type":"object","properties":{"type":{"$ref":"#/components/schemas/FolderListItemType"},"id":{"type":"integer","description":"Folder identifier"},"name":{"type":"string","description":"Folder name"},"companyId":{"type":"integer","description":"Owning company identifier"},"projectId":{"type":"integer","description":"Project (or opportunity/account, under the hood) this folder belongs to"},"parentId":{"type":["integer","null"],"description":"Parent folder id, if this folder is nested under another folder. Mutually exclusive with `phaseInstanceId`. Folders nest at most 2 levels deep."},"phaseInstanceId":{"type":["integer","null"],"description":"Phase instance id, if this folder sits at the root of a phase. Mutually exclusive with `parentId`."},"isActive":{"type":"boolean","description":"Whether the folder is active (false if archived)"},"createdBy":{"type":["integer","null"],"description":"User who created the folder"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["type","id","name","projectId","isActive","createdAt","updatedAt"],"description":"A real doc folder, as returned by GET /projects/{project_id}/folders."}],"discriminator":{"propertyName":"type"},"description":"One row from GET /projects/{project_id}/folders or GET /opportunities/{opportunity_id}/folders — either a phase or a root-level real folder. Discriminated by `type`.","title":"FoldersListItem"},"ProjectsProjectIdFoldersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"ProjectsProjectIdFoldersGetResponsesContentApplicationJsonSchemaCode"},"GetProjectFoldersRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFoldersGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetProjectFoldersRequestBadRequestError"},"GetProjectFoldersRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFoldersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectFoldersRequestNotFoundError"},"GetProjectFoldersRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFoldersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectFoldersRequestInternalServerError"},"OpportunitiesOpportunityIdFoldersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"OpportunitiesOpportunityIdFoldersGetResponsesContentApplicationJsonSchemaCode"},"GetOpportunityFoldersRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFoldersGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetOpportunityFoldersRequestBadRequestError"},"GetOpportunityFoldersRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFoldersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityFoldersRequestNotFoundError"},"GetOpportunityFoldersRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFoldersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityFoldersRequestInternalServerError"},"Folder":{"type":"object","properties":{"id":{"type":"integer","description":"Folder identifier"},"name":{"type":"string","description":"Folder name"},"companyId":{"type":"integer","description":"Owning company identifier"},"projectId":{"type":"integer","description":"Project (or opportunity/account, under the hood) this folder belongs to"},"parentId":{"type":["integer","null"],"description":"Parent folder id, if this folder is nested under another folder. Mutually exclusive with `phaseInstanceId`. Folders nest at most 2 levels deep."},"phaseInstanceId":{"type":["integer","null"],"description":"Phase instance id, if this folder sits at the root of a phase. Mutually exclusive with `parentId`."},"isActive":{"type":"boolean","description":"Whether the folder is active (false if archived)"},"createdBy":{"type":["integer","null"],"description":"User who created the folder"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["id","name","projectId","isActive","createdAt","updatedAt"],"title":"Folder"},"FoldersFolderIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"FoldersFolderIdGetResponsesContentApplicationJsonSchemaCode"},"GetFolderByIdRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetFolderByIdRequestBadRequestError"},"GetFolderByIdRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFolderByIdRequestNotFoundError"},"GetFolderByIdRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFolderByIdRequestInternalServerError"},"FolderContentsItemDiscriminatorMappingFormMetaData":{"type":"object","properties":{},"description":"File metadata (size, MIME type, etc.) — see the `File` schema for the full shape","title":"FolderContentsItemDiscriminatorMappingFormMetaData"},"FolderContentsItemDiscriminatorMappingFormCreatedByUser":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"title":"FolderContentsItemDiscriminatorMappingFormCreatedByUser"},"FolderContentsItem":{"oneOf":[{"type":"object","properties":{"type":{"$ref":"#/components/schemas/FolderListItemType"},"id":{"type":"integer","description":"Folder identifier"},"name":{"type":"string","description":"Folder name"},"companyId":{"type":"integer","description":"Owning company identifier"},"projectId":{"type":"integer","description":"Project (or opportunity/account, under the hood) this folder belongs to"},"parentId":{"type":["integer","null"],"description":"Parent folder id, if this folder is nested under another folder. Mutually exclusive with `phaseInstanceId`. Folders nest at most 2 levels deep."},"phaseInstanceId":{"type":["integer","null"],"description":"Phase instance id, if this folder sits at the root of a phase. Mutually exclusive with `parentId`."},"isActive":{"type":"boolean","description":"Whether the folder is active (false if archived)"},"createdBy":{"type":["integer","null"],"description":"User who created the folder"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["type","id","name","projectId","isActive","createdAt","updatedAt"],"description":"A real doc folder, as returned by GET /projects/{project_id}/folders."},{"type":"object","properties":{"type":{"type":"string","enum":["file"],"description":"Discriminator value: file"},"id":{"type":"integer","description":"File identifier"},"name":{"type":"string","description":"File name"},"downloadUrl":{"type":"string","description":"URL to download the file"},"fileType":{"type":"string","description":"The file's MIME/category label (named `type` on GET /projects/{project_id}/files — renamed here to avoid colliding with this endpoint's folder/file/form discriminator)."},"formId":{"type":["integer","null"],"description":"Linked Form entity id, present when `type` is `form`"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"companyId":{"type":"integer","description":"Owning company identifier"},"metaData":{"$ref":"#/components/schemas/FolderContentsItemDiscriminatorMappingFormMetaData","description":"File metadata (size, MIME type, etc.) — see the `File` schema for the full shape"},"source":{"type":"string","description":"File source (e.g., INTERNAL)"},"isArchived":{"type":"boolean","description":"Whether the file is archived"},"createdByUser":{"$ref":"#/components/schemas/FolderContentsItemDiscriminatorMappingFormCreatedByUser"}},"required":["type","id","name","downloadUrl","fileType","updatedAt","createdAt"],"description":"A file (or form — see `type`) inside a folder or phase's direct contents."},{"type":"object","properties":{"type":{"type":"string","enum":["form"],"description":"Discriminator value: form"},"id":{"type":"integer","description":"File identifier"},"name":{"type":"string","description":"File name"},"downloadUrl":{"type":"string","description":"URL to download the file"},"fileType":{"type":"string","description":"The file's MIME/category label (named `type` on GET /projects/{project_id}/files — renamed here to avoid colliding with this endpoint's folder/file/form discriminator)."},"formId":{"type":["integer","null"],"description":"Linked Form entity id, present when `type` is `form`"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"companyId":{"type":"integer","description":"Owning company identifier"},"metaData":{"$ref":"#/components/schemas/FolderContentsItemDiscriminatorMappingFormMetaData","description":"File metadata (size, MIME type, etc.) — see the `File` schema for the full shape"},"source":{"type":"string","description":"File source (e.g., INTERNAL)"},"isArchived":{"type":"boolean","description":"Whether the file is archived"},"createdByUser":{"$ref":"#/components/schemas/FolderContentsItemDiscriminatorMappingFormCreatedByUser"}},"required":["type","id","name","downloadUrl","fileType","updatedAt","createdAt"],"description":"A file (or form — see `type`) inside a folder or phase's direct contents."}],"discriminator":{"propertyName":"type"},"description":"One row from a folder's or phase's `/contents` endpoint — a subfolder, file, or form. Discriminated by `type`.","title":"FolderContentsItem"},"FoldersFolderIdContentsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"FoldersFolderIdContentsGetResponsesContentApplicationJsonSchemaCode"},"GetFolderContentsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdContentsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetFolderContentsRequestBadRequestError"},"GetFolderContentsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdContentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFolderContentsRequestNotFoundError"},"GetFolderContentsRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdContentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFolderContentsRequestInternalServerError"},"PhasesPhaseInstanceIdContentsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"PhasesPhaseInstanceIdContentsGetResponsesContentApplicationJsonSchemaCode"},"GetPhaseContentsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PhasesPhaseInstanceIdContentsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetPhaseContentsRequestBadRequestError"},"GetPhaseContentsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PhasesPhaseInstanceIdContentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetPhaseContentsRequestNotFoundError"},"GetPhaseContentsRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PhasesPhaseInstanceIdContentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetPhaseContentsRequestInternalServerError"},"FolderCreateResponse":{"type":"object","properties":{"id":{"type":"integer","description":"Folder identifier"},"name":{"type":"string","description":"Folder name"},"companyId":{"type":"integer","description":"Owning company identifier"},"parentId":{"type":["integer","null"],"description":"Parent folder id, if this folder is nested under another folder. Mutually exclusive with `phaseInstanceId`. Folders nest at most 2 levels deep."},"phaseInstanceId":{"type":["integer","null"],"description":"Phase instance id, if this folder sits at the root of a phase. Mutually exclusive with `parentId`."},"isActive":{"type":"boolean","description":"Whether the folder is active (false if archived)"},"createdBy":{"type":["integer","null"],"description":"User who created the folder"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["id","name","isActive","createdAt","updatedAt"],"description":"Response from creating a folder. Omits `projectId` — the caller already knows it, it's in the URL they just posted to.","title":"FolderCreateResponse"},"ProjectsProjectIdFoldersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"ProjectsProjectIdFoldersPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectFolderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFoldersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectFolderRequestBadRequestError"},"CreateProjectFolderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFoldersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectFolderRequestNotFoundError"},"CreateProjectFolderRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFoldersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectFolderRequestInternalServerError"},"OpportunitiesOpportunityIdFoldersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"OpportunitiesOpportunityIdFoldersPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityFolderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFoldersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityFolderRequestBadRequestError"},"CreateOpportunityFolderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFoldersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityFolderRequestNotFoundError"},"CreateOpportunityFolderRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFoldersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityFolderRequestInternalServerError"},"FoldersFolderIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"FoldersFolderIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateFolderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateFolderRequestBadRequestError"},"UpdateFolderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFolderRequestNotFoundError"},"UpdateFolderRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFolderRequestInternalServerError"},"Folders_deleteFolder_Response_200":{"type":"object","properties":{},"description":"Empty response body","title":"Folders_deleteFolder_Response_200"},"FoldersFolderIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FoldersFolderIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteFolderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdDeleteResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"DeleteFolderRequestBadRequestError"},"DeleteFolderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FoldersFolderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteFolderRequestNotFoundError"},"LineItemCatalogItemType":{"type":"string","enum":["PRODUCT","SERVICE"],"description":"Item type (e.g., PRODUCT)","title":"LineItemCatalogItemType"},"LineItemCatalogItem":{"type":"object","properties":{"id":{"type":"integer","description":"Catalog item identifier"},"name":{"type":"string","description":"Catalog item name"},"manufacturer":{"type":["string","null"],"description":"Manufacturer name"},"sku":{"type":["string","null"],"description":"Stock keeping unit"},"type":{"$ref":"#/components/schemas/LineItemCatalogItemType","description":"Item type (e.g., PRODUCT)"},"description":{"type":["string","null"],"description":"Item description"}},"required":["id","name","type"],"title":"LineItemCatalogItem"},"LineItem":{"type":"object","properties":{"id":{"type":"integer","description":"Line item identifier"},"quantity":{"type":"integer","description":"Quantity of items"},"description":{"type":"string","description":"Line item description"},"unitCost":{"type":"string","title":"float","description":"Cost per unit"},"totalCost":{"type":"string","title":"float","description":"Total cost (unitCost * quantity)"},"totalPrice":{"type":"string","title":"float","description":"Total price (unitPrice * quantity)"},"unitPrice":{"type":"string","title":"float","description":"Price per unit"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"sectionName":{"type":["string","null"],"description":"Section name; null when the item is ungrouped"},"catalogItem":{"$ref":"#/components/schemas/LineItemCatalogItem"}},"required":["id","quantity","description","unitCost","totalCost","totalPrice","unitPrice","createdAt","catalogItem"],"title":"LineItem"},"ProjectsProjectIdLineItemsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdLineItemsGetResponsesContentApplicationJsonSchemaCode"},"ListProjectLineItemsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdLineItemsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectLineItemsRequestUnauthorizedError"},"ListProjectLineItemsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdLineItemsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectLineItemsRequestNotFoundError"},"ProjectLineItemCreate":{"type":"object","properties":{"id":{"type":"integer","description":"Existing line item ID (omit for new items)"},"catalogItemId":{"type":"integer","description":"Catalog item identifier"},"quantity":{"type":"integer","minimum":1,"description":"Quantity"},"unitCost":{"type":"number","format":"double","minimum":0,"description":"Cost per unit"},"unitPrice":{"type":"number","format":"double","description":"Price per unit (may be negative for discount line items)"},"description":{"type":["string","null"],"description":"Line item description"}},"required":["catalogItemId","quantity","unitCost","unitPrice"],"title":"ProjectLineItemCreate"},"ProjectLineItemSection":{"type":"object","properties":{"id":{"type":"integer","description":"Existing section ID (omit for new sections)"},"name":{"type":["string","null"],"minLength":1,"maxLength":500,"description":"Section name (1–500 chars). Omit or pass null for an unnamed section."},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/ProjectLineItemCreate"},"description":"Line items within this section (at least one required)"}},"required":["lineItems"],"description":"A named section grouping one or more project line items.","title":"ProjectLineItemSection"},"ProjectLineItemsPutRequest":{"type":"object","properties":{"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/ProjectLineItemCreate"},"description":"Ungrouped line items. May be combined with `sections` (a catalogItemId may appear only once across both)."},"sections":{"type":"array","items":{"$ref":"#/components/schemas/ProjectLineItemSection"},"description":"Line items grouped into named sections. May be combined with `lineItems` (ungrouped items)."}},"description":"Replace all project line items. Provide `lineItems`, `sections`, or both — a `catalogItemId`\nmay appear at most once across the flattened set.\n\n> **Deprecated:** the previous request shape is still accepted for backwards compatibility but is\n> deprecated and will not be supported in a future version.\n","title":"ProjectLineItemsPutRequest"},"ProjectsProjectIdLineItemsPutResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdLineItemsPutResponsesContentApplicationJsonSchemaCode"},"ReplaceProjectLineItemsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdLineItemsPutResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ReplaceProjectLineItemsRequestBadRequestError"},"ReplaceProjectLineItemsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdLineItemsPutResponsesContentApplicationJsonSchemaCode"}},"title":"ReplaceProjectLineItemsRequestUnauthorizedError"},"ReplaceProjectLineItemsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdLineItemsPutResponsesContentApplicationJsonSchemaCode"}},"title":"ReplaceProjectLineItemsRequestNotFoundError"},"QuoteLineItemCreate":{"type":"object","properties":{"id":{"type":"integer","description":"Existing line item ID (omit for new items)"},"catalogItemId":{"type":"integer","description":"Catalog item identifier"},"quantity":{"type":"integer","minimum":1,"description":"Quantity"},"unitCost":{"type":"number","format":"double","minimum":0,"multipleOf":0.01,"description":"Cost per unit (dollars, cent precision)"},"unitPrice":{"type":"number","format":"double","exclusiveMinimum":0,"multipleOf":0.01,"description":"Price per unit (dollars, must be positive with cent precision)"},"description":{"type":["string","null"],"description":"Line item description"}},"required":["catalogItemId","quantity","unitCost","unitPrice"],"title":"QuoteLineItemCreate"},"QuoteSection":{"type":"object","properties":{"id":{"type":"integer","description":"Section identifier"},"name":{"type":["string","null"],"minLength":1,"maxLength":500,"description":"Section name (1–500 chars)"},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLineItemCreate"},"description":"Line items within this section (at least one required)"}},"required":["lineItems"],"title":"QuoteSection"},"WorkOrderLineItemsPutRequest":{"type":"object","properties":{"sections":{"type":"array","items":{"$ref":"#/components/schemas/QuoteSection"}},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLineItemCreate"}}},"description":"Provide either `sections` or `lineItems` (not both). Same shapes as quote create.","title":"WorkOrderLineItemsPutRequest"},"WorkOrdersWorkOrderIdLineItemsPutResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"WorkOrdersWorkOrderIdLineItemsPutResponsesContentApplicationJsonSchemaCode"},"ReplaceWorkOrderLineItemsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdLineItemsPutResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ReplaceWorkOrderLineItemsRequestBadRequestError"},"ReplaceWorkOrderLineItemsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdLineItemsPutResponsesContentApplicationJsonSchemaCode"}},"title":"ReplaceWorkOrderLineItemsRequestUnauthorizedError"},"ReplaceWorkOrderLineItemsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdLineItemsPutResponsesContentApplicationJsonSchemaCode"}},"title":"ReplaceWorkOrderLineItemsRequestNotFoundError"},"ReplaceWorkOrderLineItemsRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdLineItemsPutResponsesContentApplicationJsonSchemaCode"}},"title":"ReplaceWorkOrderLineItemsRequestInternalServerError"},"FormTemplateSummaryCreatedBy":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"}},"title":"FormTemplateSummaryCreatedBy"},"FormTemplateSummary":{"type":"object","properties":{"id":{"type":"integer","description":"Form template identifier"},"name":{"type":"string","description":"Template name"},"fileId":{"type":["integer","null"],"description":"Associated file identifier"},"isArchived":{"type":"boolean","description":"Whether the template is archived"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/FormTemplateSummaryCreatedBy"},{"type":"null"}]},"parentWorkOrderTemplateId":{"type":["integer","null"]}},"title":"FormTemplateSummary"},"FormTemplatesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"FormTemplatesGetResponsesContentApplicationJsonSchemaCode"},"ListFormTemplatesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListFormTemplatesRequestUnauthorizedError"},"FormTemplateDetailAssignee":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"}},"description":"Direct user assignment. Null if assigneeProperty is used instead.","title":"FormTemplateDetailAssignee"},"FormTemplateDetailCollaboratorsItems":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"}},"title":"FormTemplateDetailCollaboratorsItems"},"FormTemplateDetailLabelsItems":{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":"string"},"color":{"type":"string"}},"title":"FormTemplateDetailLabelsItems"},"FormTemplateLayoutType":{"type":"string","enum":["GROUP","COLUMN"],"description":"GROUP = section header containing child items in properties. COLUMN = an actual form field.","title":"FormTemplateLayoutType"},"FormTemplateLayoutColumn":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string","description":"Field type: DROPDOWN, NUMERIC, BOOLEAN, DATE, DATETIME, TEXT, LONG_TEXT, PERSON, FILE, SEPARATOR, PROJECT, LINK, TIMERANGEDAYS"},"multiple":{"type":"boolean"},"isRequired":{"type":"boolean"},"isReadOnly":{"type":"boolean"}},"description":"Field metadata. Only present for COLUMN type.","title":"FormTemplateLayoutColumn"},"FormTemplateChildLayoutType":{"type":"string","enum":["COLUMN"],"title":"FormTemplateChildLayoutType"},"FormTemplateChildLayoutColumn":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string"},"multiple":{"type":"boolean"},"isRequired":{"type":"boolean"},"isReadOnly":{"type":"boolean"}},"description":"Field metadata","title":"FormTemplateChildLayoutColumn"},"FormTemplateChildLayout":{"type":"object","properties":{"id":{"type":"integer","description":"Layout row identifier"},"name":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/FormTemplateChildLayoutType"},"columnId":{"type":["integer","null"],"description":"Column (property) identifier"},"column":{"$ref":"#/components/schemas/FormTemplateChildLayoutColumn","description":"Field metadata"}},"title":"FormTemplateChildLayout"},"FormTemplateLayout":{"type":"object","properties":{"id":{"type":"integer","description":"Layout row identifier"},"name":{"type":["string","null"],"description":"Group label for GROUP type, null for COLUMN type"},"type":{"$ref":"#/components/schemas/FormTemplateLayoutType","description":"GROUP = section header containing child items in properties. COLUMN = an actual form field."},"columnId":{"type":["integer","null"],"description":"Column (property) identifier. Null for GROUP items."},"column":{"$ref":"#/components/schemas/FormTemplateLayoutColumn","description":"Field metadata. Only present for COLUMN type."},"properties":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateChildLayout"},"description":"Nested child items. Populated for GROUP items (containing COLUMN children). Empty array for COLUMN items."},"fields":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateChildLayout"},"description":"Deprecated alias of properties; kept for backward compatibility. Use properties instead.","deprecated":true}},"title":"FormTemplateLayout"},"FormTemplateDetail":{"type":"object","properties":{"id":{"type":"integer","description":"Form template identifier"},"name":{"type":"string","description":"Template name"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"assignee":{"oneOf":[{"$ref":"#/components/schemas/FormTemplateDetailAssignee"},{"type":"null"}],"description":"Direct user assignment. Null if assigneeProperty is used instead."},"assigneeProperty":{"type":["string","null"],"description":"Property-based assignee key. Returns a standard key (`OWNER`, `SALES_REP`, `PROJECT_MANAGER`, `CREATED_BY`) or the keyName of a custom PERSON property. Null if a direct user assignee is set.\n"},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateDetailCollaboratorsItems"},"description":"Direct user collaborators."},"collaboratorProperties":{"type":"array","items":{"type":"string"},"description":"Property-based collaborator keys. Each value is a standard key (`OWNER`, `SALES_REP`, `PROJECT_MANAGER`, `CREATED_BY`) or the keyName of a custom PERSON property.\n"},"labels":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateDetailLabelsItems"}},"dueDateXDaysAfter":{"type":["integer","null"],"description":"Number of days after creation that the form is due"},"formLayouts":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateLayout"},"description":"Top-level layout items (GROUP sections and standalone COLUMN fields). Only root-level items are returned; child items are nested inside each GROUP's properties array."}},"title":"FormTemplateDetail"},"FormTemplatesFormTemplateIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FormTemplatesFormTemplateIdGetResponsesContentApplicationJsonSchemaCode"},"GetFormTemplateByIdRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesFormTemplateIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetFormTemplateByIdRequestBadRequestError"},"GetFormTemplateByIdRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesFormTemplateIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormTemplateByIdRequestUnauthorizedError"},"GetFormTemplateByIdRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesFormTemplateIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormTemplateByIdRequestNotFoundError"},"ProjectsProjectIdFormsGetParametersStatus":{"type":"string","enum":["UNASSIGNED","ASSIGNED","REVIEW","CHANGES_REQUESTED","COMPLETED","CANCELLED"],"title":"ProjectsProjectIdFormsGetParametersStatus"},"FormStatus":{"type":"string","enum":["UNASSIGNED","ASSIGNED","REVIEW","CHANGES_REQUESTED","COMPLETED","CANCELLED"],"description":"Form status","title":"FormStatus"},"Form":{"type":"object","properties":{"id":{"type":"integer","description":"Form identifier"},"name":{"type":"string","description":"Form name"},"description":{"type":["string","null"],"description":"Form description"},"isCompleted":{"type":"boolean","description":"Whether the form is completed"},"createdBy":{"type":"integer","description":"ID of user who created the form"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"templateId":{"type":["integer","null"],"description":"Template ID"},"status":{"$ref":"#/components/schemas/FormStatus","description":"Form status"},"dueDate":{"type":["string","null"],"format":"date-time","description":"Due date"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Completion timestamp"},"assignee":{"$ref":"#/components/schemas/UserSummary"},"projectId":{"type":"integer","description":"Associated project ID"},"phaseId":{"type":["integer","null"],"description":"Phase template ID (if available)"},"phaseName":{"type":["string","null"],"description":"Phase template name (if available)"},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/UserSummary"},"description":"Additional users collaborating on the form"}},"title":"Form"},"ProjectsProjectIdFormsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsProjectIdFormsGetResponsesContentApplicationJsonSchemaCode"},"ListProjectFormsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFormsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectFormsRequestUnauthorizedError"},"OpportunitiesOpportunityIdFormsGetParametersStatus":{"type":"string","enum":["UNASSIGNED","ASSIGNED","REVIEW","CHANGES_REQUESTED","COMPLETED","CANCELLED"],"title":"OpportunitiesOpportunityIdFormsGetParametersStatus"},"OpportunityFormStatus":{"type":"string","enum":["UNASSIGNED","ASSIGNED","REVIEW","CHANGES_REQUESTED","COMPLETED","CANCELLED"],"description":"Form status","title":"OpportunityFormStatus"},"OpportunityForm":{"type":"object","properties":{"id":{"type":"integer","description":"Form identifier"},"name":{"type":"string","description":"Form name"},"description":{"type":["string","null"],"description":"Form description"},"isCompleted":{"type":"boolean","description":"Whether the form is completed"},"createdBy":{"type":"integer","description":"ID of user who created the form"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"templateId":{"type":["integer","null"],"description":"Template ID"},"status":{"$ref":"#/components/schemas/OpportunityFormStatus","description":"Form status"},"dueDate":{"type":["string","null"],"format":"date-time","description":"Due date"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Completion timestamp"},"assignee":{"$ref":"#/components/schemas/UserSummary"},"requestId":{"type":"integer","description":"Associated opportunity ID"},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/UserSummary"},"description":"Additional users collaborating on the form"}},"title":"OpportunityForm"},"OpportunitiesOpportunityIdFormsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdFormsGetResponsesContentApplicationJsonSchemaCode"},"ListOpportunityFormsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFormsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListOpportunityFormsRequestUnauthorizedError"},"FormDetailStatus":{"type":"string","enum":["UNASSIGNED","ASSIGNED","REVIEW","CHANGES_REQUESTED","COMPLETED","CANCELLED"],"description":"Form status","title":"FormDetailStatus"},"FormLayoutGroupId":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Group identifier (\"default\" for ungrouped properties)","title":"FormLayoutGroupId"},"FormLayoutGroupType":{"type":"string","enum":["GROUP"],"title":"FormLayoutGroupType"},"FormFile":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"downloadUrl":{"type":"string"},"metaData":{"type":"object","additionalProperties":{"description":"Any type"}}},"title":"FormFile"},"FormFieldValue3":{"type":"array","items":{"$ref":"#/components/schemas/FormFile"},"description":"Array of file objects","title":"FormFieldValue3"},"FormFieldValue":{"oneOf":[{"type":"string"},{"type":"number","format":"double"},{"$ref":"#/components/schemas/UserSummary"},{"$ref":"#/components/schemas/FormFieldValue3"},{"type":"array","items":{"type":"string"}}],"description":"Normalized field value","title":"FormFieldValue"},"FormField":{"type":"object","properties":{"id":{"type":"integer","description":"Child form layout identifier"},"columnId":{"type":"integer","description":"Column identifier on the form layout"},"name":{"type":"string","description":"Field label"},"type":{"type":"string","description":"Field type"},"value":{"oneOf":[{"$ref":"#/components/schemas/FormFieldValue"},{"type":"null"}],"description":"Normalized field value"}},"title":"FormField"},"FormLayoutGroup":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/FormLayoutGroupId","description":"Group identifier (\"default\" for ungrouped properties)"},"type":{"$ref":"#/components/schemas/FormLayoutGroupType"},"name":{"type":"string","description":"Group name"},"properties":{"type":"array","items":{"$ref":"#/components/schemas/FormField"}},"fields":{"type":"array","items":{"$ref":"#/components/schemas/FormField"},"description":"Alias for properties. Both keys are returned in responses for backwards compatibility."}},"title":"FormLayoutGroup"},"FormDetail":{"type":"object","properties":{"id":{"type":"integer","description":"Form identifier"},"name":{"type":"string","description":"Form name"},"description":{"type":["string","null"],"description":"Form description"},"templateId":{"type":["integer","null"],"description":"Template ID"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"status":{"$ref":"#/components/schemas/FormDetailStatus","description":"Form status"},"isCompleted":{"type":"boolean","description":"Whether the form is completed"},"completedAt":{"type":["string","null"],"format":"date-time","description":"Completion timestamp"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"createdByUser":{"$ref":"#/components/schemas/UserSummary"},"assignee":{"$ref":"#/components/schemas/UserSummary"},"dueDate":{"type":["string","null"],"format":"date-time","description":"Due date"},"projectId":{"type":"integer","description":"Associated project ID"},"phaseId":{"type":["integer","null"],"description":"Phase template ID (if available)"},"phaseName":{"type":["string","null"],"description":"Phase template name (if available)"},"formLayouts":{"type":"array","items":{"$ref":"#/components/schemas/FormLayoutGroup"},"description":"Form layout sections"},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/UserSummary"},"description":"Additional users collaborating on the form"}},"title":"FormDetail"},"FormsFormIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FormsFormIdGetResponsesContentApplicationJsonSchemaCode"},"GetFormRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormRequestUnauthorizedError"},"GetFormRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormRequestNotFoundError"},"Forms_createProjectForm_Response_201":{"type":"object","properties":{"id":{"type":"integer","description":"Created form identifier"},"templateId":{"type":"integer"},"phaseInstanceId":{"type":"integer"},"projectId":{"type":"integer"},"type":{"type":"string"},"status":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"title":"Forms_createProjectForm_Response_201"},"ProjectsProjectIdFormsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdFormsPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectFormRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFormsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectFormRequestBadRequestError"},"CreateProjectFormRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectFormRequestUnauthorizedError"},"CreateProjectFormRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectFormRequestNotFoundError"},"Forms_createOpportunityForm_Response_201":{"type":"object","properties":{"id":{"type":"integer","description":"Created form identifier"},"templateId":{"type":"integer"},"opportunityId":{"type":"integer"},"type":{"type":"string"},"status":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"title":"Forms_createOpportunityForm_Response_201"},"OpportunitiesOpportunityIdFormsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"OpportunitiesOpportunityIdFormsPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityFormRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFormsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityFormRequestBadRequestError"},"CreateOpportunityFormRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityFormRequestUnauthorizedError"},"CreateOpportunityFormRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityFormRequestNotFoundError"},"Forms_createWorkOrderForm_Response_201":{"type":"object","properties":{"id":{"type":"integer","description":"Created form identifier"},"templateId":{"type":"integer"},"workOrderId":{"type":"integer"},"projectId":{"type":"integer"},"phaseInstanceId":{"type":"integer"},"phaseTemplateId":{"type":"integer"},"type":{"type":"string"},"status":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"title":"Forms_createWorkOrderForm_Response_201"},"WorkOrdersWorkOrderIdFormsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"WorkOrdersWorkOrderIdFormsPostResponsesContentApplicationJsonSchemaCode"},"CreateWorkOrderFormRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdFormsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateWorkOrderFormRequestBadRequestError"},"CreateWorkOrderFormRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderFormRequestUnauthorizedError"},"CreateWorkOrderFormRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderFormRequestNotFoundError"},"CreateWorkOrderFormRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkOrdersWorkOrderIdFormsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateWorkOrderFormRequestInternalServerError"},"FormsFormIdFieldsFileFromUrlPostRequestBodyContentApplicationJsonSchemaAction":{"type":"string","enum":["add","replace"],"description":"Whether to append to existing files (add) or replace them entirely (replace). Defaults to add.","title":"FormsFormIdFieldsFileFromUrlPostRequestBodyContentApplicationJsonSchemaAction"},"Forms_attachFileToFormFieldFromUrl_Response_200":{"type":"object","properties":{"success":{"type":"boolean"},"fileId":{"type":"integer"},"formId":{"type":"integer"},"columnId":{"type":"integer"},"projectId":{"type":["integer","null"]},"action":{"type":"string"}},"title":"Forms_attachFileToFormFieldFromUrl_Response_200"},"FormsFormIdFieldsFileFromUrlPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FormsFormIdFieldsFileFromUrlPostResponsesContentApplicationJsonSchemaCode"},"AttachFileToFormFieldFromUrlRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdFieldsFileFromUrlPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"AttachFileToFormFieldFromUrlRequestBadRequestError"},"AttachFileToFormFieldFromUrlRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdFieldsFileFromUrlPostResponsesContentApplicationJsonSchemaCode"}},"title":"AttachFileToFormFieldFromUrlRequestUnauthorizedError"},"AttachFileToFormFieldFromUrlRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdFieldsFileFromUrlPostResponsesContentApplicationJsonSchemaCode"}},"title":"AttachFileToFormFieldFromUrlRequestNotFoundError"},"FormsFormIdPdfPostRequestBodyContentApplicationJsonSchemaImagesInRow":{"type":"string","enum":["0","1","2","3","4","5","6"],"description":"Number of images to lay out per row. Defaults to 2.","title":"FormsFormIdPdfPostRequestBodyContentApplicationJsonSchemaImagesInRow"},"FormsFormIdPdfPostResponsesContentApplicationJsonSchemaContentType":{"type":"string","enum":["application/pdf"],"title":"FormsFormIdPdfPostResponsesContentApplicationJsonSchemaContentType"},"Forms_getFormPdf_Response_200":{"type":"object","properties":{"pdfBase64":{"type":"string","description":"Base64-encoded PDF bytes"},"contentType":{"$ref":"#/components/schemas/FormsFormIdPdfPostResponsesContentApplicationJsonSchemaContentType"},"name":{"type":["string","null"],"description":"Suggested file name for the exported PDF"}},"required":["pdfBase64","contentType"],"title":"Forms_getFormPdf_Response_200"},"FormsFormIdPdfPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"FormsFormIdPdfPostResponsesContentApplicationJsonSchemaCode"},"GetFormPdfRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPdfPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetFormPdfRequestBadRequestError"},"GetFormPdfRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPdfPostResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormPdfRequestUnauthorizedError"},"GetFormPdfRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPdfPostResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormPdfRequestNotFoundError"},"GetFormPdfRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPdfPostResponsesContentApplicationJsonSchemaCode"}},"title":"GetFormPdfRequestInternalServerError"},"FormUpdateStatus":{"type":"string","enum":["UNASSIGNED","ASSIGNED","REVIEW","CHANGES_REQUESTED","COMPLETED","CANCELLED"],"description":"Form status","title":"FormUpdateStatus"},"FormUpdateArrayValueItems":{"oneOf":[{"type":"string"},{"type":"number","format":"double"},{"type":"boolean"}],"title":"FormUpdateArrayValueItems"},"FormUpdateArrayValue":{"type":"array","items":{"$ref":"#/components/schemas/FormUpdateArrayValueItems"},"description":"Array value for the field, used when the field is a dropdown or file field (requires file IDs)","title":"FormUpdateArrayValue"},"FormUpdatePropertiesItemsValue":{"oneOf":[{"type":"string"},{"type":"number","format":"double"},{"type":"boolean"},{"$ref":"#/components/schemas/FormUpdateArrayValue"}],"description":"New value for the field","title":"FormUpdatePropertiesItemsValue"},"FormUpdatePropertiesItems":{"type":"object","properties":{"columnId":{"type":"integer","description":"Column identifier on the form"},"value":{"oneOf":[{"$ref":"#/components/schemas/FormUpdatePropertiesItemsValue"},{"type":"null"}],"description":"New value for the field"},"description":{"type":"string","description":"Field description when action is update-description"}},"required":["columnId"],"title":"FormUpdatePropertiesItems"},"FormUpdateFieldsItemsValue":{"oneOf":[{"type":"string"},{"type":"number","format":"double"},{"type":"boolean"},{"$ref":"#/components/schemas/FormUpdateArrayValue"}],"description":"New value for the field","title":"FormUpdateFieldsItemsValue"},"FormUpdateFieldsItems":{"type":"object","properties":{"columnId":{"type":"integer","description":"Column identifier on the form"},"value":{"oneOf":[{"$ref":"#/components/schemas/FormUpdateFieldsItemsValue"},{"type":"null"}],"description":"New value for the field"}},"required":["columnId"],"title":"FormUpdateFieldsItems"},"FormUpdate":{"type":"object","properties":{"name":{"type":"string","description":"Form name"},"description":{"type":["string","null"],"description":"Form description"},"assigneeId":{"type":"integer","description":"Primary assignee user ID"},"dueDate":{"type":"string","format":"date-time","description":"Absolute due date (ISO 8601)"},"status":{"$ref":"#/components/schemas/FormUpdateStatus","description":"Form status"},"labels":{"type":"array","items":{"type":"integer"},"description":"Label IDs applied to the form"},"collaborators":{"type":"array","items":{"type":"integer"},"description":"Collaborator user IDs"},"properties":{"type":"array","items":{"$ref":"#/components/schemas/FormUpdatePropertiesItems"},"description":"Individual field/column updates."},"fields":{"type":"array","items":{"$ref":"#/components/schemas/FormUpdateFieldsItems"},"description":"Deprecated alias for properties. Accepted for backwards compatibility — new integrations should use properties.","deprecated":true}},"description":"Payload for updating a form via the public API.","title":"FormUpdate"},"FormsFormIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FormsFormIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateFormRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateFormRequestBadRequestError"},"UpdateFormRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFormRequestUnauthorizedError"},"UpdateFormRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormsFormIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFormRequestNotFoundError"},"FormTemplatePropertyInputType":{"type":"string","enum":["TEXT","NUMERIC","DROPDOWN","FILE"],"description":"Field type. Required when projectPropertyKey is not provided. TEXT = text input, NUMERIC = number input, DROPDOWN = single or multi-select (set multiple: true for multi-select), FILE = file attachment.\n","title":"FormTemplatePropertyInputType"},"FormTemplatePropertyInputOptions":{"type":"object","properties":{},"description":"Field-type-specific configuration (e.g. dropdown choices).","title":"FormTemplatePropertyInputOptions"},"FormTemplatePropertyInput":{"type":"object","properties":{"id":{"type":"integer","description":"ID of an existing field from a recent GET response. When provided without other fields (and without projectPropertyKey), the API carries forward the field's current name, type, isRequired, and all other attributes. Note: IDs change after every update — only use an id obtained from the most recent GET on this template.\n"},"projectPropertyKey":{"type":"string","description":"The keyName of an existing project property. When provided, the API resolves the property and auto-populates all field attributes. All other fields on this object become optional overrides.\n"},"name":{"type":"string","description":"Field label. When projectPropertyKey is used, providing name overrides the property's display name on the form."},"type":{"$ref":"#/components/schemas/FormTemplatePropertyInputType","description":"Field type. Required when projectPropertyKey is not provided. TEXT = text input, NUMERIC = number input, DROPDOWN = single or multi-select (set multiple: true for multi-select), FILE = file attachment.\n"},"isRequired":{"type":"boolean","description":"Whether the field is required. Overrides the property default when projectPropertyKey is used."},"isReadOnly":{"type":"boolean","description":"Whether the field is read-only. Overrides the property default when projectPropertyKey is used."},"multiple":{"type":"boolean","description":"When true, allows multiple selections. Applicable to DROPDOWN fields."},"notes":{"type":["string","null"],"description":"Helper text shown beneath the field."},"options":{"$ref":"#/components/schemas/FormTemplatePropertyInputOptions","description":"Field-type-specific configuration (e.g. dropdown choices)."},"referenceFileIds":{"type":"array","items":{"type":"integer"},"description":"File IDs attached as reference documents to this field."}},"description":"A single field inside a form group.\n\n**Using `projectPropertyKey` (recommended for project-linked fields)**\n\nWhen `projectPropertyKey` is provided, the API looks up the project property by its key\nand automatically fills in `name`, `type`, `isRequired`, `isReadOnly`, `multiple`, and `options`\nfrom the property definition. All other fields become optional overrides — for example, you can\npass `isRequired: true` to override the property's default.\n\nExample — link to a project property by key:\n```json\n{ \"projectPropertyKey\": \"sales_rep\" }\n```\n\nExample — link and override required:\n```json\n{ \"projectPropertyKey\": \"sales_rep\", \"isRequired\": true }\n```\n\n**Manual field (no `projectPropertyKey`)**\n\nWhen `projectPropertyKey` is omitted, `type` is required and all other fields\n(name, isRequired, isReadOnly) should be provided explicitly.\n","title":"FormTemplatePropertyInput"},"FormTemplateLayoutInput":{"type":"object","properties":{"id":{"type":"integer","description":"ID of an existing group from a recent GET response. When provided without other fields, the API carries forward the group's current name. Note: IDs change after every update — only use an id obtained from the most recent GET on this template.\n"},"name":{"type":["string","null"],"description":"Group title displayed above the fields."},"properties":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplatePropertyInput"},"description":"Ordered list of fields inside this group."}},"description":"A form group containing a title and an ordered list of field properties.","title":"FormTemplateLayoutInput"},"FormTemplateUpdate":{"type":"object","properties":{"name":{"type":"string","description":"Template name. Optional — omit to leave the existing name untouched."},"formLayouts":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplateLayoutInput"},"description":"Optional. When provided, **fully replaces** all layout groups and their fields. Include existing groups with their `id` to keep/update them; omit the `id` for new groups. Groups not included are removed. Array order determines position.\n\nIf omitted, the existing layout is left untouched.\n"},"assigneeId":{"type":["integer","null"],"description":"Direct user ID to assign. Mutually exclusive with `assigneeProperty` and `assigneeTeamId`."},"assigneeProperty":{"type":["string","null"],"description":"Property-based assignee. Use a standard key (`OWNER`, `SALES_REP`, `PROJECT_MANAGER`, `CREATED_BY`) or a custom PERSON property keyName. Mutually exclusive with `assigneeId` and `assigneeTeamId`.\n"},"assigneeTeamId":{"type":["integer","null"],"description":"Assign a team: the team lead becomes the assignee and all other team members are added as collaborators. Mutually exclusive with `assigneeId` and `assigneeProperty`.\n"},"collaborators":{"type":"array","items":{"type":"integer"},"description":"Replaces the list of direct user collaborator IDs."},"collaboratorProperties":{"type":"array","items":{"type":"string"},"description":"Property-based collaborators. Each value is a standard key (`OWNER`, `SALES_REP`, `PROJECT_MANAGER`, `CREATED_BY`) or a custom PERSON property keyName.\n"},"collaboratorTeamIds":{"type":"array","items":{"type":"integer"},"description":"Team IDs whose members are added as collaborators. Resolved to individual user IDs and merged (deduplicated) with any direct `collaborators` and members from `assigneeTeamId`.\n"},"labels":{"type":"array","items":{"type":"integer"},"description":"Replaces the list of label IDs applied to the template."},"dueDateXDaysAfter":{"type":["integer","null"],"description":"Number of days after creation that the form is due."}},"title":"FormTemplateUpdate"},"FormTemplatesFormTemplateIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"FormTemplatesFormTemplateIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateFormTemplateRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesFormTemplateIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateFormTemplateRequestBadRequestError"},"UpdateFormTemplateRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesFormTemplateIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFormTemplateRequestUnauthorizedError"},"UpdateFormTemplateRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/FormTemplatesFormTemplateIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateFormTemplateRequestNotFoundError"},"QuotesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"QuotesGetParametersOrderBy"},"QuotesGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"QuotesGetParametersUpdatedAfter"},"QuotesGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"QuotesGetParametersUpdatedBefore"},"QuotesGetParametersStatus":{"type":"string","enum":["DRAFT","SENT","APPROVED","CHANGES_REQUESTED","DECLINED"],"title":"QuotesGetParametersStatus"},"QuoteStatus":{"type":"string","enum":["DRAFT","SENT","APPROVED","CHANGES_REQUESTED","DECLINED"],"description":"Quote status","title":"QuoteStatus"},"QuoteDiscountType":{"type":"string","enum":["PERCENTAGE","FIXED"],"description":"Discount type","title":"QuoteDiscountType"},"QuoteAccount":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":["string","null"]}},"title":"QuoteAccount"},"QuoteRecord":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":["string","null"]},"type":{"type":["string","null"]}},"title":"QuoteRecord"},"QuoteLineItemCatalogItem":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"sku":{"type":["string","null"]},"type":{"type":["string","null"]},"manufacturer":{"type":["string","null"]}},"title":"QuoteLineItemCatalogItem"},"QuoteLineItem":{"type":"object","properties":{"id":{"type":"integer","description":"Line item identifier"},"quantity":{"type":"integer","description":"Quantity"},"description":{"type":["string","null"],"description":"Line item description"},"unitCost":{"type":"number","format":"double","description":"Cost per unit (dollars)"},"totalCost":{"type":"number","format":"double","description":"Total cost (dollars)"},"unitPrice":{"type":"number","format":"double","description":"Price per unit (dollars)"},"totalPrice":{"type":"number","format":"double","description":"Total price (dollars)"},"sectionName":{"type":["string","null"],"description":"Line item section name; null when the item is ungrouped"},"catalogItem":{"oneOf":[{"$ref":"#/components/schemas/QuoteLineItemCatalogItem"},{"type":"null"}]}},"required":["id","quantity","unitCost","unitPrice"],"title":"QuoteLineItem"},"Quote":{"type":"object","properties":{"id":{"type":"integer","description":"Quote identifier"},"quoteNumber":{"type":["integer","null"],"description":"Unique quote number (uid)"},"description":{"type":["string","null"],"description":"Quote description"},"status":{"$ref":"#/components/schemas/QuoteStatus","description":"Quote status"},"amount":{"type":"number","format":"double","description":"Total quote amount (dollars)"},"discountType":{"oneOf":[{"$ref":"#/components/schemas/QuoteDiscountType"},{"type":"null"}],"description":"Discount type"},"discountValue":{"type":["number","null"],"format":"double","description":"Discount amount or percentage value"},"taxId":{"type":["integer","null"],"description":"Tax configuration ID"},"issueDate":{"type":["string","null"],"format":"date-time","description":"Issue date when the quote has been issued"},"subtotal":{"type":["number","null"],"format":"double","description":"Subtotal in dollars (before tax)"},"taxRate":{"type":["number","null"],"format":"double","description":"Applied tax rate"},"isArchived":{"type":"boolean","description":"Whether the quote is archived"},"sharedWithPortal":{"type":"boolean","description":"Whether the quote is shared with the client portal"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"account":{"oneOf":[{"$ref":"#/components/schemas/QuoteAccount"},{"type":"null"}]},"record":{"oneOf":[{"$ref":"#/components/schemas/QuoteRecord"},{"type":"null"}]},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLineItem"}}},"required":["id","status","amount","createdAt","updatedAt"],"title":"Quote"},"QuoteListResponse":{"type":"array","items":{"$ref":"#/components/schemas/Quote"},"title":"QuoteListResponse"},"QuotesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"QuotesGetResponsesContentApplicationJsonSchemaCode"},"ListQuotesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListQuotesRequestBadRequestError"},"ListQuotesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListQuotesRequestUnauthorizedError"},"OpportunitiesOpportunityIdQuotesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"OpportunitiesOpportunityIdQuotesGetParametersOrderBy"},"OpportunitiesOpportunityIdQuotesGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdQuotesGetParametersUpdatedAfter"},"OpportunitiesOpportunityIdQuotesGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdQuotesGetParametersUpdatedBefore"},"OpportunitiesOpportunityIdQuotesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdQuotesGetResponsesContentApplicationJsonSchemaCode"},"GetOpportunityQuotesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdQuotesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityQuotesRequestUnauthorizedError"},"QuotesQuoteIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"QuotesQuoteIdGetResponsesContentApplicationJsonSchemaCode"},"GetQuoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetQuoteRequestUnauthorizedError"},"GetQuoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetQuoteRequestNotFoundError"},"Quotes_getQuotePdf_Response_200":{"type":"object","properties":{"pdfBase64":{"type":"string"},"contentType":{"type":"string"}},"title":"Quotes_getQuotePdf_Response_200"},"QuotesQuoteIdPdfGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"QuotesQuoteIdPdfGetResponsesContentApplicationJsonSchemaCode"},"GetQuotePdfRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdPdfGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetQuotePdfRequestUnauthorizedError"},"GetQuotePdfRequestForbiddenError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdPdfGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetQuotePdfRequestForbiddenError"},"GetQuotePdfRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdPdfGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetQuotePdfRequestNotFoundError"},"QuoteCreateDiscountType":{"type":"string","enum":["PERCENTAGE","FIXED"],"description":"Discount type","title":"QuoteCreateDiscountType"},"QuoteCreateStatus":{"type":"string","enum":["DRAFT","SENT","APPROVED","CHANGES_REQUESTED","DECLINED"],"description":"Initial status (defaults to DRAFT)","title":"QuoteCreateStatus"},"QuoteCreate":{"type":"object","properties":{"opportunityId":{"type":"integer","minimum":1,"description":"Opportunity / project / account record ID"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/QuoteSection"},"description":"Grouped line items. Required if `lineItems` is not provided."},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLineItemCreate"},"description":"Flat line items (grouped into one section automatically). Required if `sections` is not provided."},"discountType":{"$ref":"#/components/schemas/QuoteCreateDiscountType","description":"Discount type"},"discountValue":{"type":"number","format":"double","minimum":0,"description":"Discount amount or percentage"},"taxId":{"type":"integer","description":"Tax configuration ID"},"issueDate":{"type":"string","format":"date-time","description":"Issue date. Requires `status` to be `SENT` or `APPROVED`."},"status":{"$ref":"#/components/schemas/QuoteCreateStatus","description":"Initial status (defaults to DRAFT)"},"description":{"type":["string","null"]},"title":{"type":"string","description":"Quote title (defaults to \"Quote\")"},"servicePlanInstanceId":{"type":"integer"},"siteId":{"type":"integer"}},"required":["opportunityId"],"description":"`opportunityId` is the record (project/opportunity/account) id used by the payment service.\n\nWhen the quote is for a **Client (Account)** record, provide **`siteId`** (or use work-order line items via `PUT /work-orders/{work_order_id}/line-items`) so the quote can be linked correctly.\n","title":"QuoteCreate"},"QuotesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"QuotesPostResponsesContentApplicationJsonSchemaCode"},"CreateQuoteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateQuoteRequestBadRequestError"},"CreateQuoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateQuoteRequestUnauthorizedError"},"QuotesQuoteIdSendPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"QuotesQuoteIdSendPostResponsesContentApplicationJsonSchemaCode"},"SendQuoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdSendPostResponsesContentApplicationJsonSchemaCode"}},"title":"SendQuoteRequestUnauthorizedError"},"SendQuoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdSendPostResponsesContentApplicationJsonSchemaCode"}},"title":"SendQuoteRequestNotFoundError"},"QuoteUpdateDiscountType":{"type":"string","enum":["PERCENTAGE","FIXED"],"title":"QuoteUpdateDiscountType"},"QuoteUpdateStatus":{"type":"string","enum":["DRAFT","SENT","APPROVED","CHANGES_REQUESTED","DECLINED"],"title":"QuoteUpdateStatus"},"QuoteUpdate":{"type":"object","properties":{"sections":{"type":"array","items":{"$ref":"#/components/schemas/QuoteSection"}},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLineItemCreate"}},"discountType":{"$ref":"#/components/schemas/QuoteUpdateDiscountType"},"discountValue":{"type":"number","format":"double","minimum":0},"taxId":{"type":["integer","null"]},"issueDate":{"type":"string","format":"date-time"},"status":{"$ref":"#/components/schemas/QuoteUpdateStatus"},"description":{"type":["string","null"]},"sharedWithPortal":{"type":"boolean","description":"When true, the quote is visible on the client portal; when false, it is hidden."},"isArchived":{"type":"boolean","description":"Set true to archive or false to unarchive (maps to payment service archive/unarchive routes)"}},"title":"QuoteUpdate"},"QuotesQuoteIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"QuotesQuoteIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateQuoteRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateQuoteRequestBadRequestError"},"UpdateQuoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateQuoteRequestUnauthorizedError"},"UpdateQuoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateQuoteRequestNotFoundError"},"QuotesQuoteIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"QuotesQuoteIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteQuoteRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteQuoteRequestUnauthorizedError"},"DeleteQuoteRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/QuotesQuoteIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteQuoteRequestNotFoundError"},"InvoicesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"InvoicesGetParametersOrderBy"},"InvoicesGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"InvoicesGetParametersUpdatedAfter"},"InvoicesGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"InvoicesGetParametersUpdatedBefore"},"InvoiceStatus":{"type":"string","enum":["DRAFT","SENT","DECLINED","PAID","PARTIALLY_PAID","OVERDUE"],"description":"Invoice status","title":"InvoiceStatus"},"InvoiceAccount":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"}},"title":"InvoiceAccount"},"InvoiceRecord":{"type":"object","properties":{"id":{"type":"integer"},"uid":{"type":"integer"},"title":{"type":"string"}},"title":"InvoiceRecord"},"InvoiceLineItemCatalogItemType":{"type":"string","enum":["PRODUCT","SERVICE"],"title":"InvoiceLineItemCatalogItemType"},"InvoiceLineItemCatalogItem":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"manufacturer":{"type":["string","null"]},"sku":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/InvoiceLineItemCatalogItemType"}},"title":"InvoiceLineItemCatalogItem"},"InvoiceLineItem":{"type":"object","properties":{"id":{"type":"integer","description":"Line item identifier"},"catalogItemId":{"type":"integer","description":"Catalog item identifier"},"quantity":{"type":"integer","description":"Quantity"},"unitCost":{"type":"number","format":"double","description":"Cost per unit"},"unitPrice":{"type":"number","format":"double","description":"Price per unit"},"description":{"type":["string","null"],"description":"Line item description"},"catalogItem":{"oneOf":[{"$ref":"#/components/schemas/InvoiceLineItemCatalogItem"},{"type":"null"}]}},"required":["id","catalogItemId","quantity","unitCost","unitPrice"],"title":"InvoiceLineItem"},"Invoice":{"type":"object","properties":{"id":{"type":"integer","description":"Invoice identifier"},"invoiceNumber":{"type":"integer","description":"Unique invoice number"},"description":{"type":["string","null"],"description":"Invoice description"},"internalMemo":{"type":["string","null"],"description":"Internal-only memo, never shown to customers or on the PDF or portal. Rich text (HTML, like the app's editor stores). On update, send null or \"\" to clear it; responses return null when empty. Invoices and bills created in the app from a quote or purchase order inherit its memo."},"status":{"$ref":"#/components/schemas/InvoiceStatus","description":"Invoice status"},"basedOnId":{"type":["integer","null"],"description":"ID of the record this invoice is based on"},"basedOnUid":{"type":["integer","null"],"description":"UID of the record this invoice is based on"},"dueDate":{"type":"string","format":"date-time","description":"Due date"},"issueDate":{"type":["string","null"],"format":"date-time","description":"Issue date when the invoice has been issued"},"amount":{"type":"number","format":"double","description":"Total invoice amount"},"amountPaid":{"type":"number","format":"double","description":"Amount paid"},"isArchived":{"type":"boolean","description":"Whether the invoice is archived"},"sharedWithPortal":{"type":"boolean","description":"Whether the invoice is shared with portal"},"calculationMethod":{"type":"string","description":"Calculation method (e.g., LINE_ITEMS)"},"percentage":{"type":["number","null"],"format":"double","description":"Percentage if applicable"},"baseAmount":{"type":["number","null"],"format":"double","description":"Base amount if applicable"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"account":{"oneOf":[{"$ref":"#/components/schemas/InvoiceAccount"},{"type":"null"}]},"record":{"oneOf":[{"$ref":"#/components/schemas/InvoiceRecord"},{"type":"null"}]},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineItem"}}},"required":["id","invoiceNumber","status","amount","amountPaid","calculationMethod","createdAt","updatedAt"],"title":"Invoice"},"InvoiceListResponse":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"},"title":"InvoiceListResponse"},"InvoicesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"InvoicesGetResponsesContentApplicationJsonSchemaCode"},"ListInvoicesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListInvoicesRequestBadRequestError"},"ListInvoicesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListInvoicesRequestUnauthorizedError"},"InvoicesInvoiceIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"InvoicesInvoiceIdGetResponsesContentApplicationJsonSchemaCode"},"GetInvoiceRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetInvoiceRequestUnauthorizedError"},"GetInvoiceRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetInvoiceRequestNotFoundError"},"ProjectsProjectIdInvoicesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ProjectsProjectIdInvoicesGetParametersOrderBy"},"ProjectsProjectIdInvoicesGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdInvoicesGetParametersUpdatedAfter"},"ProjectsProjectIdInvoicesGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdInvoicesGetParametersUpdatedBefore"},"ProjectsProjectIdInvoicesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdInvoicesGetResponsesContentApplicationJsonSchemaCode"},"GetProjectInvoicesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdInvoicesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetProjectInvoicesRequestBadRequestError"},"GetProjectInvoicesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdInvoicesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectInvoicesRequestUnauthorizedError"},"GetProjectInvoicesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdInvoicesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectInvoicesRequestNotFoundError"},"AccountsAccountIdInvoicesGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"AccountsAccountIdInvoicesGetParametersOrderBy"},"AccountsAccountIdInvoicesGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsAccountIdInvoicesGetParametersUpdatedAfter"},"AccountsAccountIdInvoicesGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsAccountIdInvoicesGetParametersUpdatedBefore"},"AccountsAccountIdInvoicesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AccountsAccountIdInvoicesGetResponsesContentApplicationJsonSchemaCode"},"GetAccountInvoicesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdInvoicesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetAccountInvoicesRequestBadRequestError"},"GetAccountInvoicesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdInvoicesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountInvoicesRequestUnauthorizedError"},"GetAccountInvoicesRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdInvoicesGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountInvoicesRequestNotFoundError"},"InvoiceCreateCalculationMethod":{"type":"string","enum":["LINE_ITEMS","PERCENTAGE"],"description":"Calculation method","title":"InvoiceCreateCalculationMethod"},"InvoiceLineItemCreate":{"type":"object","properties":{"id":{"type":"integer","default":0,"description":"Line item ID (0 for new items)"},"catalogItemId":{"type":"integer","description":"Catalog item identifier"},"quantity":{"type":"integer","minimum":1,"description":"Quantity"},"unitCost":{"type":"number","format":"double","minimum":0,"description":"Cost per unit"},"unitPrice":{"type":"number","format":"double","description":"Price per unit (may be negative for discount line items)"},"description":{"type":["string","null"],"description":"Line item description"}},"required":["catalogItemId","quantity","unitCost","unitPrice"],"title":"InvoiceLineItemCreate"},"InvoiceSection":{"type":"object","properties":{"id":{"type":"integer","description":"Existing section ID (omit for new sections)"},"name":{"type":["string","null"],"minLength":1,"maxLength":500,"description":"Section name (1–500 chars). Omit or pass null for an unnamed section."},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineItemCreate"},"description":"Line items within this section (at least one required)"}},"required":["lineItems"],"description":"A named section grouping one or more invoice line items.","title":"InvoiceSection"},"InvoiceCreateStatus":{"type":"string","enum":["DRAFT","SENT","PARTIALLY_PAID","PAID"],"description":"Optional; defaults to DRAFT when omitted. To finalize the invoice, set `SENT`,\n`PARTIALLY_PAID`, or `PAID` — `issueDate` is then required. Lifecycle statuses\n(DECLINED, OVERDUE) cannot be set at creation.\n","title":"InvoiceCreateStatus"},"InvoiceCreate":{"type":"object","properties":{"recordId":{"type":"integer","minimum":1,"description":"Project or account ID"},"calculationMethod":{"$ref":"#/components/schemas/InvoiceCreateCalculationMethod","description":"Calculation method"},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineItemCreate"},"description":"Required when `calculationMethod` is `LINE_ITEMS` and `sections` is not provided.\nFlat array of line items (auto-grouped into one unnamed section).\n"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceSection"},"description":"Required when `calculationMethod` is `LINE_ITEMS` and `lineItems` is not provided.\nGrouped line items with named sections. May be combined with `lineItems` (ungrouped items).\n"},"percentage":{"type":"number","format":"double","minimum":0,"description":"Required when `calculationMethod` is `PERCENTAGE`."},"status":{"$ref":"#/components/schemas/InvoiceCreateStatus","description":"Optional; defaults to DRAFT when omitted. To finalize the invoice, set `SENT`,\n`PARTIALLY_PAID`, or `PAID` — `issueDate` is then required. Lifecycle statuses\n(DECLINED, OVERDUE) cannot be set at creation.\n"},"issueDate":{"type":"string","format":"date-time","description":"Issue date (ISO 8601). Optional. Applied only when `status` is SENT/PARTIALLY_PAID/PAID\n(required for those); ignored for DRAFT invoices.\n"},"dueDate":{"type":"string","format":"date-time","description":"Due date (ISO 8601 datetime string)"},"description":{"type":["string","null"],"description":"Invoice description"},"internalMemo":{"type":["string","null"],"description":"Internal-only memo, never shown to customers or on the PDF or portal. Rich text (HTML, like the app's editor stores). On update, send null or \"\" to clear it; responses return null when empty. Invoices and bills created in the app from a quote or purchase order inherit its memo."}},"required":["recordId","calculationMethod"],"description":"When `calculationMethod` is `LINE_ITEMS`, provide `lineItems`, `sections`, or both (ungrouped items + named sections). A `catalogItemId` may appear at most once across the flattened set.\nWhen `calculationMethod` is `PERCENTAGE`, `sections` and `lineItems` must be omitted.\n","title":"InvoiceCreate"},"InvoicesPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"InvoicesPostResponsesContentApplicationJsonSchemaCode"},"CreateInvoiceRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateInvoiceRequestBadRequestError"},"CreateInvoiceRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateInvoiceRequestUnauthorizedError"},"InvoiceUpdateStatus":{"type":"string","enum":["DRAFT","SENT","DECLINED","PAID","PARTIALLY_PAID","OVERDUE"],"description":"Invoice status","title":"InvoiceUpdateStatus"},"InvoiceUpdate":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/InvoiceUpdateStatus","description":"Invoice status"},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineItemCreate"},"description":"Flat array of line items (LINE_ITEMS only). May be combined with `sections` (a catalogItemId may appear only once across both)."},"sections":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceSection"},"description":"Grouped line items with named sections (LINE_ITEMS only). May be combined with `lineItems` (ungrouped items)."},"percentage":{"type":"number","format":"double","minimum":0,"description":"Percentage (PERCENTAGE invoices only). Cannot be combined with `lineItems` or `sections`."},"issueDate":{"type":"string","format":"date-time","description":"Issue date (ISO 8601 datetime string)"},"dueDate":{"type":"string","format":"date-time","description":"Due date (ISO 8601 datetime string)"},"description":{"type":["string","null"],"description":"Invoice description"},"internalMemo":{"type":["string","null"],"description":"Internal-only memo, never shown to customers or on the PDF or portal. Rich text (HTML, like the app's editor stores). On update, send null or \"\" to clear it; responses return null when empty. Invoices and bills created in the app from a quote or purchase order inherit its memo."},"isActive":{"type":"boolean","description":"Set to `false` to archive the invoice, or `true` to unarchive it. Applied independently of any other fields present in the same request."}},"description":"All fields are optional. When updating line items, provide `lineItems`, `sections`, or both. A `catalogItemId` may appear at most once across the flattened set.\n`calculationMethod` cannot be changed after creation and is not accepted on update. `percentage` (PERCENTAGE invoices) cannot be combined with `lineItems` or `sections` (LINE_ITEMS invoices).\n","title":"InvoiceUpdate"},"InvoicesInvoiceIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"InvoicesInvoiceIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateInvoiceRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateInvoiceRequestBadRequestError"},"UpdateInvoiceRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateInvoiceRequestUnauthorizedError"},"UpdateInvoiceRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateInvoiceRequestNotFoundError"},"InvoicesInvoiceIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"InvoicesInvoiceIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteInvoiceRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteInvoiceRequestUnauthorizedError"},"DeleteInvoiceRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteInvoiceRequestNotFoundError"},"PaymentMethod":{"type":"string","enum":["CASH","ACH","CREDIT_CARD","KLARNA","AFFIRM","CHECK"],"description":"Payment method","title":"PaymentMethod"},"PaymentCreatedBy":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]}},"title":"PaymentCreatedBy"},"Payment":{"type":"object","properties":{"id":{"type":"integer","description":"Payment record identifier"},"invoiceNumber":{"type":["integer","null"],"description":"Payment display number (when present)"},"amount":{"type":"number","format":"double","description":"Payment amount in dollars"},"status":{"type":"string","description":"Payment status"},"paymentMethod":{"$ref":"#/components/schemas/PaymentMethod"},"paymentDate":{"type":["string","null"],"format":"date-time","description":"When the payment was recorded (ISO 8601); null if absent from upstream"},"paymentReference":{"type":["string","null"]},"notes":{"type":["string","null"]},"isExternal":{"type":["boolean","null"],"description":"Whether the payment originated from an external processor (e.g. Stripe)"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/PaymentCreatedBy"},{"type":"null"}]}},"required":["id","amount","status","paymentMethod"],"title":"Payment"},"PaymentListResponse":{"type":"array","items":{"$ref":"#/components/schemas/Payment"},"title":"PaymentListResponse"},"InvoicesInvoiceIdPaymentsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"InvoicesInvoiceIdPaymentsGetResponsesContentApplicationJsonSchemaCode"},"ListInvoicePaymentsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListInvoicePaymentsRequestBadRequestError"},"ListInvoicePaymentsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListInvoicePaymentsRequestUnauthorizedError"},"ListInvoicePaymentsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListInvoicePaymentsRequestNotFoundError"},"InvoicesInvoiceIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"InvoicesInvoiceIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"},"GetInvoicePaymentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetInvoicePaymentRequestBadRequestError"},"GetInvoicePaymentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetInvoicePaymentRequestUnauthorizedError"},"GetInvoicePaymentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetInvoicePaymentRequestNotFoundError"},"BillPaymentCreatedBy":{"type":"object","properties":{"id":{"type":"integer"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]}},"title":"BillPaymentCreatedBy"},"BillPayment":{"type":"object","properties":{"id":{"type":"integer","description":"Payment record identifier"},"billNumber":{"type":["integer","null"],"description":"Payment display number (when present)"},"amount":{"type":"number","format":"double","description":"Payment amount in dollars"},"status":{"type":"string","description":"Payment status"},"paymentMethod":{"$ref":"#/components/schemas/PaymentMethod"},"paymentDate":{"type":["string","null"],"format":"date-time","description":"When the payment was recorded (ISO 8601); null if absent from upstream"},"paymentReference":{"type":["string","null"]},"notes":{"type":["string","null"]},"isExternal":{"type":["boolean","null"],"description":"Whether the payment originated from an external processor (e.g. Stripe)"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/BillPaymentCreatedBy"},{"type":"null"}]}},"required":["id","amount","status","paymentMethod"],"title":"BillPayment"},"BillPaymentListResponse":{"type":"array","items":{"$ref":"#/components/schemas/BillPayment"},"title":"BillPaymentListResponse"},"BillsBillIdPaymentsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"BillsBillIdPaymentsGetResponsesContentApplicationJsonSchemaCode"},"ListBillPaymentsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListBillPaymentsRequestBadRequestError"},"ListBillPaymentsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListBillPaymentsRequestUnauthorizedError"},"ListBillPaymentsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListBillPaymentsRequestNotFoundError"},"BillsBillIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"BillsBillIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"},"GetBillPaymentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetBillPaymentRequestBadRequestError"},"GetBillPaymentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetBillPaymentRequestUnauthorizedError"},"GetBillPaymentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsPaymentIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetBillPaymentRequestNotFoundError"},"PaymentCreate":{"type":"object","properties":{"amount":{"type":"number","format":"double","exclusiveMinimum":0,"description":"Payment amount in dollars"},"paymentMethod":{"$ref":"#/components/schemas/PaymentMethod"},"paymentDate":{"type":"string","format":"date-time"},"notes":{"type":"string","description":"Optional notes about the payment"},"paymentReference":{"type":["string","null"]}},"required":["amount","paymentMethod","paymentDate"],"title":"PaymentCreate"},"InvoicesInvoiceIdPaymentsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"InvoicesInvoiceIdPaymentsPostResponsesContentApplicationJsonSchemaCode"},"CreateInvoicePaymentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateInvoicePaymentRequestBadRequestError"},"CreateInvoicePaymentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateInvoicePaymentRequestUnauthorizedError"},"CreateInvoicePaymentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/InvoicesInvoiceIdPaymentsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateInvoicePaymentRequestNotFoundError"},"BillsBillIdPaymentsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"BillsBillIdPaymentsPostResponsesContentApplicationJsonSchemaCode"},"CreateBillPaymentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateBillPaymentRequestBadRequestError"},"CreateBillPaymentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateBillPaymentRequestUnauthorizedError"},"CreateBillPaymentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPaymentsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateBillPaymentRequestNotFoundError"},"PaymentUpdate":{"type":"object","properties":{"amount":{"type":"number","format":"double","exclusiveMinimum":0,"description":"Payment amount in dollars"},"paymentMethod":{"$ref":"#/components/schemas/PaymentMethod"},"paymentDate":{"type":"string","format":"date-time"},"notes":{"type":"string","description":"Optional notes about the payment"},"paymentReference":{"type":["string","null"]}},"description":"All fields are optional; at least one must be supplied. If the payment is external\n(processed by Stripe), only `notes` may be updated.\n","title":"PaymentUpdate"},"Payments_updatePayment_Response_200":{"oneOf":[{"$ref":"#/components/schemas/Payment"},{"$ref":"#/components/schemas/BillPayment"}],"title":"Payments_updatePayment_Response_200"},"PaymentsPaymentIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"PaymentsPaymentIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdatePaymentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PaymentsPaymentIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdatePaymentRequestBadRequestError"},"UpdatePaymentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PaymentsPaymentIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdatePaymentRequestUnauthorizedError"},"UpdatePaymentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PaymentsPaymentIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdatePaymentRequestNotFoundError"},"PaymentsPaymentIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"PaymentsPaymentIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeletePaymentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PaymentsPaymentIdDeleteResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"DeletePaymentRequestBadRequestError"},"DeletePaymentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PaymentsPaymentIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeletePaymentRequestUnauthorizedError"},"DeletePaymentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/PaymentsPaymentIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeletePaymentRequestNotFoundError"},"BillsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"BillsGetParametersOrderBy"},"BillsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"BillsGetParametersUpdatedAfter"},"BillsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"BillsGetParametersUpdatedBefore"},"BillStatus":{"type":"string","enum":["DRAFT","SENT","DECLINED","PAID","PARTIALLY_PAID","OVERDUE"],"description":"Bill status","title":"BillStatus"},"BillAccount":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"}},"title":"BillAccount"},"BillRecord":{"type":"object","properties":{"id":{"type":"integer"},"uid":{"type":"integer"},"title":{"type":"string"}},"title":"BillRecord"},"BillLineItemCatalogItemType":{"type":"string","enum":["PRODUCT","SERVICE"],"title":"BillLineItemCatalogItemType"},"BillLineItemCatalogItem":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"manufacturer":{"type":["string","null"]},"sku":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/BillLineItemCatalogItemType"}},"title":"BillLineItemCatalogItem"},"BillLineItem":{"type":"object","properties":{"id":{"type":"integer","description":"Line item identifier"},"catalogItemId":{"type":"integer","description":"Catalog item identifier"},"quantity":{"type":"integer","description":"Quantity"},"unitCost":{"type":"number","format":"double","description":"Cost per unit (must be greater than 0 for bills)"},"unitPrice":{"type":"number","format":"double","description":"Price per unit (may be negative for discounts)"},"description":{"type":["string","null"],"description":"Line item description"},"catalogItem":{"oneOf":[{"$ref":"#/components/schemas/BillLineItemCatalogItem"},{"type":"null"}]}},"required":["id","catalogItemId","quantity","unitCost","unitPrice"],"title":"BillLineItem"},"Bill":{"type":"object","properties":{"id":{"type":"integer","description":"Bill identifier"},"billNumber":{"type":"integer","description":"Unique bill number"},"description":{"type":["string","null"],"description":"Bill description"},"internalMemo":{"type":["string","null"],"description":"Internal-only memo, never shown to customers or on the PDF or portal. Rich text (HTML, like the app's editor stores). On update, send null or \"\" to clear it; responses return null when empty. Invoices and bills created in the app from a quote or purchase order inherit its memo."},"status":{"$ref":"#/components/schemas/BillStatus","description":"Bill status"},"basedOnId":{"type":["integer","null"],"description":"ID of the record this bill is based on"},"basedOnUid":{"type":["integer","null"],"description":"UID of the record this bill is based on"},"dueDate":{"type":"string","format":"date-time","description":"Due date"},"issueDate":{"type":["string","null"],"format":"date-time","description":"Issue date"},"amount":{"type":"number","format":"double","description":"Total bill amount"},"amountPaid":{"type":"number","format":"double","description":"Amount paid"},"isArchived":{"type":"boolean","description":"Whether the bill is archived"},"calculationMethod":{"type":"string","description":"Calculation method (LINE_ITEMS or PERCENTAGE)"},"percentage":{"type":["number","null"],"format":"double","description":"Percentage if calculationMethod is PERCENTAGE"},"baseAmount":{"type":["number","null"],"format":"double","description":"Base amount if calculationMethod is PERCENTAGE"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"account":{"oneOf":[{"$ref":"#/components/schemas/BillAccount"},{"type":"null"}]},"record":{"oneOf":[{"$ref":"#/components/schemas/BillRecord"},{"type":"null"}]},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/BillLineItem"}}},"required":["id","billNumber","status","amount","amountPaid","calculationMethod","createdAt","updatedAt"],"title":"Bill"},"BillListResponse":{"type":"array","items":{"$ref":"#/components/schemas/Bill"},"title":"BillListResponse"},"BillsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"BillsGetResponsesContentApplicationJsonSchemaCode"},"ListBillsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListBillsRequestBadRequestError"},"ListBillsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListBillsRequestUnauthorizedError"},"BillsBillIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"BillsBillIdGetResponsesContentApplicationJsonSchemaCode"},"GetBillRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetBillRequestUnauthorizedError"},"GetBillRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetBillRequestNotFoundError"},"ProjectsProjectIdBillsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ProjectsProjectIdBillsGetParametersOrderBy"},"ProjectsProjectIdBillsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdBillsGetParametersUpdatedAfter"},"ProjectsProjectIdBillsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdBillsGetParametersUpdatedBefore"},"ProjectsProjectIdBillsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"ProjectsProjectIdBillsGetResponsesContentApplicationJsonSchemaCode"},"GetProjectBillsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdBillsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetProjectBillsRequestBadRequestError"},"GetProjectBillsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdBillsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectBillsRequestUnauthorizedError"},"GetProjectBillsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdBillsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectBillsRequestNotFoundError"},"BillCreateCalculationMethod":{"type":"string","enum":["LINE_ITEMS","PERCENTAGE"],"description":"Calculation method. Cannot be changed after creation.\n- `LINE_ITEMS`: requires `lineItems` or `sections`; allows `issueDate` and `status`\n- `PERCENTAGE`: requires `percentage`; `issueDate`, `status`, `lineItems`, and `sections` are not allowed\n","title":"BillCreateCalculationMethod"},"BillLineItemCreate":{"type":"object","properties":{"id":{"type":"integer","default":0,"description":"Line item ID (0 for new items)"},"catalogItemId":{"type":"integer","description":"Catalog item identifier"},"quantity":{"type":"integer","minimum":1,"description":"Quantity"},"unitCost":{"type":"number","format":"double","exclusiveMinimum":0,"description":"Cost per unit — must be greater than 0 for bills"},"unitPrice":{"type":"number","format":"double","description":"Price per unit — may be negative for discounts"},"description":{"type":["string","null"],"description":"Line item description"}},"required":["catalogItemId","quantity","unitCost","unitPrice"],"title":"BillLineItemCreate"},"BillSection":{"type":"object","properties":{"id":{"type":"integer","description":"Existing section ID (omit for new sections)"},"name":{"type":["string","null"],"minLength":1,"maxLength":500,"description":"Section name (1–500 chars). Omit or pass null for an unnamed section."},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/BillLineItemCreate"},"description":"Line items within this section (at least one required). `unitCost` must be greater than 0."}},"required":["lineItems"],"description":"A named section grouping one or more bill line items.","title":"BillSection"},"BillCreateStatus":{"type":"string","enum":["SENT","PARTIALLY_PAID","PAID"],"description":"Bill status. LINE_ITEMS bills only, and only when `issueDate` is also provided.\nOmit to default to `DRAFT`.\n","title":"BillCreateStatus"},"BillCreate":{"type":"object","properties":{"recordId":{"type":"integer","minimum":1,"description":"Project ID the bill belongs to"},"calculationMethod":{"$ref":"#/components/schemas/BillCreateCalculationMethod","description":"Calculation method. Cannot be changed after creation.\n- `LINE_ITEMS`: requires `lineItems` or `sections`; allows `issueDate` and `status`\n- `PERCENTAGE`: requires `percentage`; `issueDate`, `status`, `lineItems`, and `sections` are not allowed\n"},"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/BillLineItemCreate"},"description":"Required when `calculationMethod` is `LINE_ITEMS` and `sections` is not provided.\n`unitCost` must be greater than 0. `unitPrice` may be negative for discounts.\nMay be combined with `sections` (a catalogItemId may appear only once across both).\n"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/BillSection"},"description":"Required when `calculationMethod` is `LINE_ITEMS` and `lineItems` is not provided.\nGrouped line items with named sections. May be combined with `lineItems` (ungrouped items).\n"},"percentage":{"type":"number","format":"double","minimum":0,"maximum":100,"description":"Required when `calculationMethod` is `PERCENTAGE`. Must be between 0 and 100."},"dueDate":{"type":"string","format":"date-time","description":"Due date (ISO 8601 datetime string)"},"issueDate":{"type":"string","format":"date-time","description":"Issue date (ISO 8601 datetime string). LINE_ITEMS bills only.\nWhen provided, `status` must also be provided and must not be `DRAFT`.\n"},"status":{"$ref":"#/components/schemas/BillCreateStatus","description":"Bill status. LINE_ITEMS bills only, and only when `issueDate` is also provided.\nOmit to default to `DRAFT`.\n"},"description":{"type":["string","null"],"description":"Bill description"},"internalMemo":{"type":["string","null"],"description":"Internal-only memo, never shown to customers or on the PDF or portal. Rich text (HTML, like the app's editor stores). On update, send null or \"\" to clear it; responses return null when empty. Invoices and bills created in the app from a quote or purchase order inherit its memo."}},"required":["recordId","calculationMethod"],"description":"When `calculationMethod` is `LINE_ITEMS`, provide `lineItems`, `sections`, or both (ungrouped items + named sections). A `catalogItemId` may appear at most once across the flattened set.\nWhen `calculationMethod` is `PERCENTAGE`, `sections` and `lineItems` must be omitted.\n","title":"BillCreate"},"BillsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"BillsPostResponsesContentApplicationJsonSchemaCode"},"CreateBillRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateBillRequestBadRequestError"},"CreateBillRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateBillRequestUnauthorizedError"},"BillUpdateStatus":{"type":"string","enum":["SENT","PARTIALLY_PAID","PAID"],"description":"Bill status (LINE_ITEMS bills only). Only valid when `issueDate` is also provided.\n","title":"BillUpdateStatus"},"BillUpdate":{"type":"object","properties":{"lineItems":{"type":"array","items":{"$ref":"#/components/schemas/BillLineItemCreate"},"description":"Flat array of line items (LINE_ITEMS bills only). May be combined with `sections` (a catalogItemId may appear only once across both)."},"sections":{"type":"array","items":{"$ref":"#/components/schemas/BillSection"},"description":"Grouped line items with named sections (LINE_ITEMS bills only). May be combined with `lineItems` (ungrouped items)."},"percentage":{"type":"number","format":"double","minimum":0,"maximum":100,"description":"Percentage value (PERCENTAGE bills only)"},"dueDate":{"type":"string","format":"date-time","description":"Due date (ISO 8601 datetime string)"},"issueDate":{"type":"string","format":"date-time","description":"Issue date (LINE_ITEMS bills only). When provided, `status` must also be provided and must not be `DRAFT`.\n"},"status":{"$ref":"#/components/schemas/BillUpdateStatus","description":"Bill status (LINE_ITEMS bills only). Only valid when `issueDate` is also provided.\n"},"description":{"type":["string","null"],"description":"Bill description"},"internalMemo":{"type":["string","null"],"description":"Internal-only memo, never shown to customers or on the PDF or portal. Rich text (HTML, like the app's editor stores). On update, send null or \"\" to clear it; responses return null when empty. Invoices and bills created in the app from a quote or purchase order inherit its memo."}},"description":"All fields are optional. `calculationMethod` cannot be changed after creation.\n\n**PERCENTAGE bills** — only `description`, `dueDate`, and `percentage` may be updated.\n\n**LINE_ITEMS bills** — `lineItems`, `sections`, or both may be updated (a `catalogItemId` may appear at most once across the flattened set). `issueDate` and `status` must be provided together; when `issueDate` is provided, `status` must be `SENT`, `PARTIALLY_PAID`, or `PAID`.\n","title":"BillUpdate"},"BillsBillIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"BillsBillIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateBillRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateBillRequestBadRequestError"},"UpdateBillRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateBillRequestUnauthorizedError"},"UpdateBillRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateBillRequestNotFoundError"},"BillsBillIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"BillsBillIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteBillRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteBillRequestUnauthorizedError"},"DeleteBillRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/BillsBillIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteBillRequestNotFoundError"},"TimesheetsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"TimesheetsGetParametersOrderBy"},"TimesheetsGetParametersType":{"type":"string","enum":["WORKING","TRAVEL"],"title":"TimesheetsGetParametersType"},"TimesheetsGetParametersStatus":{"type":"string","enum":["PROCESSING","PROCESSED","FAILED"],"title":"TimesheetsGetParametersStatus"},"TimesheetsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"TimesheetsGetParametersUpdatedAfter"},"TimesheetsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"TimesheetsGetParametersUpdatedBefore"},"TimesheetType":{"type":"string","enum":["WORKING","TRAVEL"],"description":"Time entry type.","title":"TimesheetType"},"TimesheetStatus":{"type":"string","enum":["PROCESSING","PROCESSED","FAILED"],"description":"Processing status of the time entry.","title":"TimesheetStatus"},"Timesheet":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier."},"type":{"oneOf":[{"$ref":"#/components/schemas/TimesheetType"},{"type":"null"}],"description":"Time entry type."},"status":{"oneOf":[{"$ref":"#/components/schemas/TimesheetStatus"},{"type":"null"}],"description":"Processing status of the time entry."},"startDate":{"type":["string","null"],"format":"date-time"},"endDate":{"type":["string","null"],"format":"date-time"},"distance":{"type":["number","null"],"format":"double","description":"Distance traveled, for TRAVEL entries."},"note":{"type":["string","null"]},"isArchived":{"type":["boolean","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"projectId":{"type":["integer","null"],"description":"Set when the linked record is a Project. Null when it is an Account (see accountId) or Opportunity (see opportunityId)."},"accountId":{"type":["integer","null"],"description":"Set when the linked record is an Account. Null otherwise."},"opportunityId":{"type":["integer","null"],"description":"Set when the linked record is an Opportunity. Null otherwise."},"workOrderId":{"type":["integer","null"]},"targetUserId":{"type":["integer","null"],"description":"The worker the time entry is logged for."},"createdBy":{"type":["integer","null"]},"updatedBy":{"type":["integer","null"]},"laborHourlyRate":{"type":["number","null"],"format":"double","description":"Labor cost ($/hr). Only visible with the appropriate financial privilege."},"laborTotalCost":{"type":["number","null"],"format":"double","description":"Only visible with the appropriate financial privilege."}},"description":"A timesheet (time entry) logged by a worker against a project and, optionally, a work order.","title":"Timesheet"},"TimesheetsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"TimesheetsGetResponsesContentApplicationJsonSchemaCode"},"List-timesheetsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"List-timesheetsRequestBadRequestError"},"List-timesheetsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsGetResponsesContentApplicationJsonSchemaCode"}},"title":"List-timesheetsRequestUnauthorizedError"},"List-timesheetsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsGetResponsesContentApplicationJsonSchemaCode"}},"title":"List-timesheetsRequestBadGatewayError"},"TimesheetsTimesheetIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"TimesheetsTimesheetIdGetResponsesContentApplicationJsonSchemaCode"},"GetTimesheetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetTimesheetRequestUnauthorizedError"},"GetTimesheetRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetTimesheetRequestNotFoundError"},"GetTimesheetRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetTimesheetRequestBadGatewayError"},"TimesheetCreateType":{"type":"string","enum":["WORKING","TRAVEL"],"title":"TimesheetCreateType"},"TimesheetCreate":{"type":"object","properties":{"projectId":{"type":"integer","description":"Project this time entry belongs to. Exactly one of projectId, accountId, or opportunityId is required."},"accountId":{"type":"integer","description":"Account this time entry belongs to. Exactly one of projectId, accountId, or opportunityId is required."},"opportunityId":{"type":"integer","description":"Opportunity this time entry belongs to. Exactly one of projectId, accountId, or opportunityId is required."},"workOrderId":{"type":["integer","null"],"description":"Work order this time entry is logged against, if any."},"targetUserId":{"type":"integer","description":"Worker the time entry is logged for."},"type":{"$ref":"#/components/schemas/TimesheetCreateType"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time","description":"Must be after startDate."},"distance":{"type":["number","null"],"format":"double"},"laborHourlyRate":{"type":["number","null"],"format":"double"},"note":{"type":["string","null"]}},"required":["targetUserId","type","startDate","endDate"],"description":"Exactly one of `projectId`, `accountId`, or `opportunityId` is required.","title":"TimesheetCreate"},"TimesheetsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"TimesheetsPostResponsesContentApplicationJsonSchemaCode"},"CreateTimesheetRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateTimesheetRequestBadRequestError"},"CreateTimesheetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateTimesheetRequestUnauthorizedError"},"CreateTimesheetRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateTimesheetRequestBadGatewayError"},"TimesheetUpdate":{"type":"object","properties":{"projectId":{"type":"integer","description":"Reassign to a different project. At most one of projectId, accountId, or opportunityId may be provided."},"accountId":{"type":"integer","description":"Reassign to a different account. At most one of projectId, accountId, or opportunityId may be provided."},"opportunityId":{"type":"integer","description":"Reassign to a different opportunity. At most one of projectId, accountId, or opportunityId may be provided."},"workOrderId":{"type":["integer","null"]},"targetUserId":{"type":"integer"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"},"distance":{"type":["number","null"],"format":"double"},"laborHourlyRate":{"type":["number","null"],"format":"double"},"note":{"type":["string","null"]},"isArchived":{"type":"boolean","description":"Set true to archive, false to unarchive. Handled independently of the other fields."}},"description":"At most one of `projectId`, `accountId`, or `opportunityId` may be provided, to reassign the timesheet's parent record.","title":"TimesheetUpdate"},"TimesheetsTimesheetIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["BAD_GATEWAY"],"title":"TimesheetsTimesheetIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateTimesheetRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateTimesheetRequestBadRequestError"},"UpdateTimesheetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateTimesheetRequestUnauthorizedError"},"UpdateTimesheetRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateTimesheetRequestNotFoundError"},"UpdateTimesheetRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateTimesheetRequestBadGatewayError"},"TimesheetsTimesheetIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"TimesheetsTimesheetIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteTimesheetRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteTimesheetRequestUnauthorizedError"},"DeleteTimesheetRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TimesheetsTimesheetIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteTimesheetRequestNotFoundError"},"ProjectsProjectIdRemindersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"ProjectsProjectIdRemindersGetParametersOrderBy"},"ProjectsProjectIdRemindersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdRemindersGetParametersUpdatedAfter"},"ProjectsProjectIdRemindersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"ProjectsProjectIdRemindersGetParametersUpdatedBefore"},"ReminderType":{"type":"string","enum":["CALL","EMAIL","IN_PERSON","VIRTUAL","DEADLINE","OTHER"],"title":"ReminderType"},"Reminder":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"},"description":{"type":["string","null"]},"type":{"oneOf":[{"$ref":"#/components/schemas/ReminderType"},{"type":"null"}]},"dueDate":{"type":["string","null"],"format":"date-time"},"isCompleted":{"type":"boolean"},"completedAt":{"type":["string","null"],"format":"date-time"},"assigneeId":{"type":["integer","null"]},"projectId":{"type":["integer","null"],"description":"Present when the reminder belongs to a project."},"opportunityId":{"type":["integer","null"],"description":"Present when the reminder belongs to an opportunity."},"accountId":{"type":["integer","null"],"description":"Present when the reminder belongs to an account."},"createdBy":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Exactly one of `projectId`, `opportunityId`, or `accountId` will be\npresent, depending on which parent resource the reminder belongs to.\n","title":"Reminder"},"ReminderListResponse":{"type":"object","properties":{"reminders":{"type":"array","items":{"$ref":"#/components/schemas/Reminder"}},"totalCount":{"type":"integer"}},"required":["reminders","totalCount"],"title":"ReminderListResponse"},"ProjectsProjectIdRemindersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsProjectIdRemindersGetResponsesContentApplicationJsonSchemaCode"},"GetProjectRemindersRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetProjectRemindersRequestBadRequestError"},"GetProjectRemindersRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetProjectRemindersRequestUnauthorizedError"},"OpportunitiesOpportunityIdRemindersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"OpportunitiesOpportunityIdRemindersGetParametersOrderBy"},"OpportunitiesOpportunityIdRemindersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdRemindersGetParametersUpdatedAfter"},"OpportunitiesOpportunityIdRemindersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdRemindersGetParametersUpdatedBefore"},"OpportunitiesOpportunityIdRemindersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdRemindersGetResponsesContentApplicationJsonSchemaCode"},"GetOpportunityRemindersRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetOpportunityRemindersRequestBadRequestError"},"GetOpportunityRemindersRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityRemindersRequestUnauthorizedError"},"AccountsAccountIdRemindersGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"AccountsAccountIdRemindersGetParametersOrderBy"},"AccountsAccountIdRemindersGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsAccountIdRemindersGetParametersUpdatedAfter"},"AccountsAccountIdRemindersGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"AccountsAccountIdRemindersGetParametersUpdatedBefore"},"AccountsAccountIdRemindersGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsAccountIdRemindersGetResponsesContentApplicationJsonSchemaCode"},"GetAccountRemindersRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdRemindersGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetAccountRemindersRequestBadRequestError"},"GetAccountRemindersRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdRemindersGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAccountRemindersRequestUnauthorizedError"},"RemindersReminderIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"RemindersReminderIdGetResponsesContentApplicationJsonSchemaCode"},"GetReminderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetReminderRequestUnauthorizedError"},"GetReminderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetReminderRequestNotFoundError"},"ReminderCreateType":{"type":"string","enum":["CALL","EMAIL","IN_PERSON","VIRTUAL","DEADLINE","OTHER"],"description":"Reminder type","title":"ReminderCreateType"},"ReminderCreate":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"Reminder title"},"assigneeId":{"type":"integer","description":"ID of the user assigned to this reminder"},"description":{"type":"string","description":"Optional description"},"dueDate":{"type":"string","format":"date-time","description":"ISO 8601 due date"},"isCompleted":{"type":"boolean","description":"Whether the reminder is completed"},"type":{"$ref":"#/components/schemas/ReminderCreateType","description":"Reminder type"}},"required":["title","assigneeId"],"title":"ReminderCreate"},"ProjectsProjectIdRemindersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsProjectIdRemindersPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectReminderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectReminderRequestBadRequestError"},"CreateProjectReminderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdRemindersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectReminderRequestUnauthorizedError"},"OpportunitiesOpportunityIdRemindersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdRemindersPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityReminderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityReminderRequestBadRequestError"},"CreateOpportunityReminderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdRemindersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityReminderRequestUnauthorizedError"},"AccountsAccountIdRemindersPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsAccountIdRemindersPostResponsesContentApplicationJsonSchemaCode"},"CreateAccountReminderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdRemindersPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateAccountReminderRequestBadRequestError"},"CreateAccountReminderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdRemindersPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateAccountReminderRequestUnauthorizedError"},"ReminderUpdateType":{"type":"string","enum":["CALL","EMAIL","IN_PERSON","VIRTUAL","DEADLINE","OTHER"],"title":"ReminderUpdateType"},"ReminderUpdate":{"type":"object","properties":{"title":{"type":"string","minLength":1},"assigneeId":{"type":"integer"},"description":{"type":["string","null"]},"dueDate":{"type":["string","null"],"format":"date-time"},"isCompleted":{"type":"boolean"},"type":{"$ref":"#/components/schemas/ReminderUpdateType"}},"title":"ReminderUpdate"},"RemindersReminderIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"RemindersReminderIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateReminderRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateReminderRequestBadRequestError"},"UpdateReminderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateReminderRequestUnauthorizedError"},"UpdateReminderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateReminderRequestNotFoundError"},"RemindersReminderIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"RemindersReminderIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteReminderRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteReminderRequestUnauthorizedError"},"DeleteReminderRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/RemindersReminderIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteReminderRequestNotFoundError"},"OpportunitiesOpportunityIdAppointmentsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"asc","title":"OpportunitiesOpportunityIdAppointmentsGetParametersOrderBy"},"OpportunitiesOpportunityIdAppointmentsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdAppointmentsGetParametersUpdatedAfter"},"OpportunitiesOpportunityIdAppointmentsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"OpportunitiesOpportunityIdAppointmentsGetParametersUpdatedBefore"},"Appointment":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"},"description":{"type":["string","null"]},"dueDate":{"type":["string","null"],"format":"date-time"},"isCompleted":{"type":"boolean"},"completedAt":{"type":["string","null"],"format":"date-time"},"assigneeId":{"type":["integer","null"]},"opportunityId":{"type":["integer","null"],"description":"ID of the parent opportunity."},"createdBy":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"title":"Appointment"},"AppointmentListResponse":{"type":"object","properties":{"appointments":{"type":"array","items":{"$ref":"#/components/schemas/Appointment"}},"totalCount":{"type":"integer"}},"required":["appointments","totalCount"],"title":"AppointmentListResponse"},"OpportunitiesOpportunityIdAppointmentsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdAppointmentsGetResponsesContentApplicationJsonSchemaCode"},"GetOpportunityAppointmentsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetOpportunityAppointmentsRequestBadRequestError"},"GetOpportunityAppointmentsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetOpportunityAppointmentsRequestUnauthorizedError"},"AppointmentsAppointmentIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AppointmentsAppointmentIdGetResponsesContentApplicationJsonSchemaCode"},"GetAppointmentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAppointmentRequestUnauthorizedError"},"GetAppointmentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetAppointmentRequestNotFoundError"},"AppointmentCreate":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"Appointment title"},"assigneeId":{"type":"integer","description":"ID of the user assigned to this appointment"},"dueDate":{"type":"string","format":"date-time","description":"ISO 8601 scheduled date/time"},"description":{"type":"string","description":"Optional description"}},"required":["title","assigneeId","dueDate"],"title":"AppointmentCreate"},"OpportunitiesOpportunityIdAppointmentsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdAppointmentsPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityAppointmentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityAppointmentRequestBadRequestError"},"CreateOpportunityAppointmentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdAppointmentsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityAppointmentRequestUnauthorizedError"},"AppointmentUpdate":{"type":"object","properties":{"title":{"type":"string","minLength":1},"assigneeId":{"type":"integer"},"dueDate":{"type":["string","null"],"format":"date-time"},"description":{"type":["string","null"]},"isCompleted":{"type":"boolean"}},"title":"AppointmentUpdate"},"AppointmentsAppointmentIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AppointmentsAppointmentIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateAppointmentRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateAppointmentRequestBadRequestError"},"UpdateAppointmentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAppointmentRequestUnauthorizedError"},"UpdateAppointmentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateAppointmentRequestNotFoundError"},"AppointmentsAppointmentIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"AppointmentsAppointmentIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteAppointmentRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteAppointmentRequestUnauthorizedError"},"DeleteAppointmentRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AppointmentsAppointmentIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteAppointmentRequestNotFoundError"},"CallsGetParametersUpdatedAfter":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"CallsGetParametersUpdatedAfter"},"CallsGetParametersUpdatedBefore":{"oneOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"title":"CallsGetParametersUpdatedBefore"},"CallsGetParametersOrderBy":{"type":"string","enum":["asc","desc"],"default":"desc","title":"CallsGetParametersOrderBy"},"CallsGetParametersOutcome":{"type":"string","enum":["ANSWERED","MISSED","VOICEMAIL"],"title":"CallsGetParametersOutcome"},"CallListItemOutcome":{"type":"string","enum":["ANSWERED","MISSED","VOICEMAIL"],"description":"Call outcome","title":"CallListItemOutcome"},"CallListItemResolution":{"type":"string","enum":["RESOLVED","ESCALATED","UNRESOLVED"],"description":"For calls handled by a Coperniq AI agent, whether the caller's issue was resolved.","title":"CallListItemResolution"},"CallListItem":{"type":"object","properties":{"id":{"type":"integer","description":"Call identifier"},"fromNumber":{"type":"string","description":"Phone number that initiated the call"},"toNumber":{"type":"string","description":"Phone number that received the call"},"isInbound":{"type":"boolean","description":"Whether the call was inbound (true) or outbound (false)"},"outcome":{"oneOf":[{"$ref":"#/components/schemas/CallListItemOutcome"},{"type":"null"}],"description":"Call outcome"},"startTime":{"type":["string","null"],"format":"date-time","description":"When the call started"},"endTime":{"type":["string","null"],"format":"date-time","description":"When the call ended"},"reason":{"type":["string","null"],"maxLength":255,"description":"Why the call happened. Company-defined: the value is the name of one of the company's\ncall reasons (see `GET /calls/classification-options?type=REASON`), so it can be any\nstring up to 255 characters. Default reasons are Product, Process, Service, Accounting,\nRevenue opportunity, Feedback and Other. Calls logged before custom reasons existed\nhold the legacy uppercase value (e.g. `SERVICE`).\n"},"disposition":{"type":["string","null"],"maxLength":255,"description":"How the call ended up. Company-defined: the value is the name of one of the company's\ncall dispositions (see `GET /calls/classification-options?type=DISPOSITION`), so it can\nbe any string up to 255 characters. Default dispositions are Info provided, Visit\nscheduled, Issue resolved, Follow up, Escalation, No action, Unresponsive and Other.\nCalls logged before custom dispositions existed hold the legacy uppercase value\n(e.g. `INFO_PROVIDED`).\n"},"note":{"type":["string","null"],"description":"Human-editable note about the call. May contain HTML."},"summary":{"type":["string","null"],"description":"AI-generated summary of the call. `null` when the call has no AI transcript."},"transcriptText":{"type":["string","null"],"description":"AI transcript of the call as plain text, one sentence per line in spoken order. `null` when the call has no AI transcript."},"recordingUrl":{"type":["string","null"],"description":"URL to the call recording"},"transcriptUrl":{"type":["string","null"],"description":"URL to an externally hosted call transcript, if one was provided when the call was logged. For Coperniq phone calls use `transcriptText`."},"missedCount":{"type":["integer","null"],"description":"Number of times the call was missed"},"classificationNote":{"type":["string","null"],"description":"For calls classified by Coperniq AI, the AI's explanation of why it chose the reason and disposition."},"resolution":{"oneOf":[{"$ref":"#/components/schemas/CallListItemResolution"},{"type":"null"}],"description":"For calls handled by a Coperniq AI agent, whether the caller's issue was resolved."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"projectId":{"type":["integer","null"],"description":"The project this call is logged on, if it's on a project"},"opportunityId":{"type":["integer","null"],"description":"The opportunity this call is logged on, if it's on an opportunity"},"accountId":{"type":["integer","null"],"description":"The account this call is logged on, if it's on an account"}},"required":["id","fromNumber","toNumber","isInbound","createdAt","updatedAt"],"title":"CallListItem"},"CallsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CallsGetResponsesContentApplicationJsonSchemaCode"},"ListCallsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CallsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListCallsRequestBadRequestError"},"ListCallsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCallsRequestUnauthorizedError"},"ListCallsRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCallsRequestInternalServerError"},"ListCallsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CallsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListCallsRequestBadGatewayError"},"CallsClassificationOptionsGetParametersType":{"type":"string","enum":["REASON","DISPOSITION"],"title":"CallsClassificationOptionsGetParametersType"},"CallClassificationOptionType":{"type":"string","enum":["REASON","DISPOSITION"],"description":"Whether this option is a call reason or a call disposition","title":"CallClassificationOptionType"},"CallClassificationOption":{"type":"object","properties":{"id":{"type":"integer","description":"Option identifier"},"type":{"$ref":"#/components/schemas/CallClassificationOptionType","description":"Whether this option is a call reason or a call disposition"},"name":{"type":"string","description":"The value stored on a call's `reason` or `disposition`"},"description":{"type":["string","null"],"description":"Guidance on when to use this option. Coperniq AI also uses it when classifying calls."},"position":{"type":"integer","description":"Sort order within its type"}},"required":["id","type","name","position"],"title":"CallClassificationOption"},"CallsClassificationOptionsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CallsClassificationOptionsGetResponsesContentApplicationJsonSchemaCode"},"ListCallClassificationOptionsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CallsClassificationOptionsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListCallClassificationOptionsRequestBadRequestError"},"ListCallClassificationOptionsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CallsClassificationOptionsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCallClassificationOptionsRequestUnauthorizedError"},"ListCallClassificationOptionsRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CallsClassificationOptionsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCallClassificationOptionsRequestInternalServerError"},"ListCallClassificationOptionsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CallsClassificationOptionsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListCallClassificationOptionsRequestBadGatewayError"},"CallOutcome":{"type":"string","enum":["ANSWERED","MISSED","VOICEMAIL"],"description":"Call outcome","title":"CallOutcome"},"CallResolution":{"type":"string","enum":["RESOLVED","ESCALATED","UNRESOLVED"],"description":"For calls handled by a Coperniq AI agent, whether the caller's issue was resolved.","title":"CallResolution"},"Call":{"type":"object","properties":{"id":{"type":"integer","description":"Call identifier"},"fromNumber":{"type":"string","description":"Phone number that initiated the call"},"toNumber":{"type":"string","description":"Phone number that received the call"},"isInbound":{"type":"boolean","description":"Whether the call was inbound (true) or outbound (false)"},"outcome":{"oneOf":[{"$ref":"#/components/schemas/CallOutcome"},{"type":"null"}],"description":"Call outcome"},"startTime":{"type":["string","null"],"format":"date-time","description":"When the call started"},"endTime":{"type":["string","null"],"format":"date-time","description":"When the call ended"},"reason":{"type":["string","null"],"maxLength":255,"description":"Why the call happened. Company-defined: the value is the name of one of the company's\ncall reasons (see `GET /calls/classification-options?type=REASON`), so it can be any\nstring up to 255 characters. Default reasons are Product, Process, Service, Accounting,\nRevenue opportunity, Feedback and Other. Calls logged before custom reasons existed\nhold the legacy uppercase value (e.g. `SERVICE`).\n"},"disposition":{"type":["string","null"],"maxLength":255,"description":"How the call ended up. Company-defined: the value is the name of one of the company's\ncall dispositions (see `GET /calls/classification-options?type=DISPOSITION`), so it can\nbe any string up to 255 characters. Default dispositions are Info provided, Visit\nscheduled, Issue resolved, Follow up, Escalation, No action, Unresponsive and Other.\nCalls logged before custom dispositions existed hold the legacy uppercase value\n(e.g. `INFO_PROVIDED`).\n"},"note":{"type":["string","null"],"description":"Human-editable note about the call. May contain HTML."},"summary":{"type":["string","null"],"description":"AI-generated summary of the call. `null` when the call has no AI transcript."},"transcriptText":{"type":["string","null"],"description":"AI transcript of the call as plain text, one sentence per line in spoken order. `null` when the call has no AI transcript."},"recordingUrl":{"type":["string","null"],"description":"URL to the call recording"},"transcriptUrl":{"type":["string","null"],"description":"URL to an externally hosted call transcript, if one was provided when the call was logged. For Coperniq phone calls use `transcriptText`."},"missedCount":{"type":["integer","null"],"description":"Number of times the call was missed"},"classificationNote":{"type":["string","null"],"description":"For calls classified by Coperniq AI, the AI's explanation of why it chose the reason and disposition."},"resolution":{"oneOf":[{"$ref":"#/components/schemas/CallResolution"},{"type":"null"}],"description":"For calls handled by a Coperniq AI agent, whether the caller's issue was resolved."},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"}},"required":["id","fromNumber","toNumber","isInbound","createdAt","updatedAt"],"title":"Call"},"ProjectsProjectIdCallsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"ProjectsProjectIdCallsGetResponsesContentApplicationJsonSchemaCode"},"ListProjectCallsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectCallsRequestUnauthorizedError"},"ListProjectCallsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListProjectCallsRequestNotFoundError"},"ListProjectCallsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListProjectCallsRequestBadGatewayError"},"OpportunitiesOpportunityIdCallsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"OpportunitiesOpportunityIdCallsGetResponsesContentApplicationJsonSchemaCode"},"ListOpportunityCallsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListOpportunityCallsRequestUnauthorizedError"},"ListOpportunityCallsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListOpportunityCallsRequestNotFoundError"},"ListOpportunityCallsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListOpportunityCallsRequestBadGatewayError"},"AccountsAccountIdCallsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"AccountsAccountIdCallsGetResponsesContentApplicationJsonSchemaCode"},"ListAccountCallsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListAccountCallsRequestUnauthorizedError"},"ListAccountCallsRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListAccountCallsRequestNotFoundError"},"ListAccountCallsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/AccountsAccountIdCallsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListAccountCallsRequestBadGatewayError"},"CallCreateOutcome":{"type":"string","enum":["ANSWERED","MISSED","VOICEMAIL"],"description":"Call outcome","title":"CallCreateOutcome"},"CallCreate":{"type":"object","properties":{"fromNumber":{"type":"string","description":"Phone number that initiated the call"},"toNumber":{"type":"string","description":"Phone number that received the call"},"isInbound":{"type":"boolean","default":false,"description":"Whether the call was inbound (true) or outbound (false)"},"outcome":{"$ref":"#/components/schemas/CallCreateOutcome","description":"Call outcome"},"startTime":{"type":"string","format":"date-time","description":"When the call started"},"endTime":{"type":"string","format":"date-time","description":"When the call ended"},"reason":{"type":"string","minLength":1,"maxLength":255,"description":"Why the call happened. Company-defined: the value is the name of one of the company's\ncall reasons (see `GET /calls/classification-options?type=REASON`), so it can be any\nstring up to 255 characters. Default reasons are Product, Process, Service, Accounting,\nRevenue opportunity, Feedback and Other. Calls logged before custom reasons existed\nhold the legacy uppercase value (e.g. `SERVICE`).\nAny string is accepted; use a name from the company's list so the call groups with others in Coperniq.\n"},"disposition":{"type":"string","minLength":1,"maxLength":255,"description":"How the call ended up. Company-defined: the value is the name of one of the company's\ncall dispositions (see `GET /calls/classification-options?type=DISPOSITION`), so it can\nbe any string up to 255 characters. Default dispositions are Info provided, Visit\nscheduled, Issue resolved, Follow up, Escalation, No action, Unresponsive and Other.\nCalls logged before custom dispositions existed hold the legacy uppercase value\n(e.g. `INFO_PROVIDED`).\nAny string is accepted; use a name from the company's list so the call groups with others in Coperniq.\n"},"note":{"type":"string","description":"Human-editable note about the call. May contain HTML."},"recordingUrl":{"type":"string","description":"URL to the call recording"},"transcriptUrl":{"type":"string","description":"URL to an externally hosted call transcript"},"missedCount":{"type":"integer","description":"Number of times the call was missed"}},"required":["fromNumber","toNumber","isInbound","startTime","endTime","reason","disposition"],"title":"CallCreate"},"ProjectsProjectIdCallsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"ProjectsProjectIdCallsPostResponsesContentApplicationJsonSchemaCode"},"CreateProjectCallRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdCallsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateProjectCallRequestBadRequestError"},"CreateProjectCallRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/ProjectsProjectIdCallsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateProjectCallRequestUnauthorizedError"},"OpportunitiesOpportunityIdCallsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"OpportunitiesOpportunityIdCallsPostResponsesContentApplicationJsonSchemaCode"},"CreateOpportunityCallRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdCallsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateOpportunityCallRequestBadRequestError"},"CreateOpportunityCallRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/OpportunitiesOpportunityIdCallsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateOpportunityCallRequestUnauthorizedError"},"AccountsAccountIdCallsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"AccountsAccountIdCallsPostResponsesContentApplicationJsonSchemaCode"},"CreateAccountCallRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdCallsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateAccountCallRequestBadRequestError"},"CreateAccountCallRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/AccountsAccountIdCallsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateAccountCallRequestUnauthorizedError"},"CatalogItemsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CatalogItemsGetResponsesContentApplicationJsonSchemaCode"},"ListCatalogItemsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCatalogItemsRequestUnauthorizedError"},"ListCatalogItemsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CatalogItemsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListCatalogItemsRequestBadGatewayError"},"CategoryOptionType":{"type":"string","enum":["PRODUCT","SERVICE"],"description":"Whether this category applies to PRODUCT or SERVICE catalog items","title":"CategoryOptionType"},"CategoryOption":{"type":"object","properties":{"code":{"type":"string","description":"The category code (a ProductCategory or ServiceCategory value)"},"description":{"type":["string","null"],"description":"Human-readable description of the category, if available"},"type":{"$ref":"#/components/schemas/CategoryOptionType","description":"Whether this category applies to PRODUCT or SERVICE catalog items"}},"required":["code","type"],"title":"CategoryOption"},"CatalogCategoriesResponse":{"type":"object","properties":{"productCategories":{"type":"array","items":{"$ref":"#/components/schemas/CategoryOption"}},"serviceCategories":{"type":"array","items":{"$ref":"#/components/schemas/CategoryOption"}},"tradeGroups":{"type":"array","items":{"$ref":"#/components/schemas/TradeGroup"}}},"required":["productCategories","serviceCategories","tradeGroups"],"title":"CatalogCategoriesResponse"},"CatalogCategoriesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UNAUTHORIZED"],"title":"CatalogCategoriesGetResponsesContentApplicationJsonSchemaCode"},"ListCatalogCategoriesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogCategoriesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCatalogCategoriesRequestUnauthorizedError"},"CatalogUnitsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CatalogUnitsGetResponsesContentApplicationJsonSchemaCode"},"ListCatalogUnitsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogUnitsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListCatalogUnitsRequestBadRequestError"},"ListCatalogUnitsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogUnitsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListCatalogUnitsRequestUnauthorizedError"},"ListCatalogUnitsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CatalogUnitsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListCatalogUnitsRequestBadGatewayError"},"CatalogItemsCatalogItemIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CatalogItemsCatalogItemIdGetResponsesContentApplicationJsonSchemaCode"},"GetCatalogItemRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetCatalogItemRequestBadRequestError"},"GetCatalogItemRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetCatalogItemRequestUnauthorizedError"},"GetCatalogItemRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetCatalogItemRequestNotFoundError"},"GetCatalogItemRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"GetCatalogItemRequestBadGatewayError"},"CatalogUnitsCatalogUnitIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CatalogUnitsCatalogUnitIdGetResponsesContentApplicationJsonSchemaCode"},"GetCatalogUnitRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogUnitsCatalogUnitIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetCatalogUnitRequestBadRequestError"},"GetCatalogUnitRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogUnitsCatalogUnitIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetCatalogUnitRequestUnauthorizedError"},"GetCatalogUnitRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogUnitsCatalogUnitIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetCatalogUnitRequestNotFoundError"},"GetCatalogUnitRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CatalogUnitsCatalogUnitIdGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"GetCatalogUnitRequestBadGatewayError"},"CatalogItemCreateType":{"type":"string","enum":["PRODUCT","SERVICE"],"description":"Catalog item type","title":"CatalogItemCreateType"},"CatalogItemCreateWasteFactorMode":{"type":"string","enum":["STATIC"],"description":"Waste factor mode. Must be set together with wasteFactorValue — both, or neither.","title":"CatalogItemCreateWasteFactorMode"},"CatalogItemCreate":{"type":"object","properties":{"name":{"type":"string","description":"Catalog item name"},"type":{"$ref":"#/components/schemas/CatalogItemCreateType","description":"Catalog item type"},"category":{"$ref":"#/components/schemas/CatalogCategoryCode","description":"Catalog item category code. Must be a valid ProductCategory when type is PRODUCT or ServiceCategory when type is SERVICE."},"cost":{"type":"number","format":"double","minimum":0,"description":"Catalog item cost"},"price":{"type":"number","format":"double","minimum":0,"description":"Catalog item price"},"tradeGroup":{"$ref":"#/components/schemas/TradeGroup","description":"High-level trade group for this item. If omitted, it is derived from the category — a product category resolves to the trade group it belongs to (for example ROOF_COVERING resolves to ENVELOPE), and services or category OTHER resolve to OTHER. When provided, it must be consistent with the category (for products, the category must belong to this trade group; category OTHER is allowed under any trade group)."},"manufacturer":{"type":["string","null"],"description":"Catalog item manufacturer"},"sku":{"type":["string","null"],"description":"Catalog item SKU"},"code":{"type":["string","null"],"description":"Catalog item code"},"description":{"type":["string","null"],"description":"Catalog item description"},"preferredVendorId":{"type":["integer","null"],"description":"ID of the preferred vendor (must be an existing active vendor for this company)"},"unitId":{"type":["integer","null"],"description":"ID of the unit this item is sold/measured in. Must reference a unit belonging to your company (see GET /catalog-units)."},"measurementIds":{"type":"array","items":{"type":"integer"},"description":"IDs of measurements (and/or a single sub-measurement) to link to this item, driving its quantity calculation. At most one linked measurement may be a sub-measurement (type SUB_CALCULATION), and it must be the only one linked. Multiple plain measurement links must share the same unit (or be unitless) — their values are summed."},"coverage":{"type":["number","null"],"format":"double","exclusiveMinimum":0,"description":"Measurement units covered per item unit. Must be greater than zero. Not compatible with a linked sub-calculation, which derives quantity from its own formula."},"wasteFactorMode":{"oneOf":[{"$ref":"#/components/schemas/CatalogItemCreateWasteFactorMode"},{"type":"null"}],"description":"Waste factor mode. Must be set together with wasteFactorValue — both, or neither."},"wasteFactorValue":{"type":["number","null"],"format":"double","minimum":0,"maximum":100,"description":"Waste factor percentage (0-100). Must be set together with wasteFactorMode."}},"required":["name","type","category","cost","price"],"title":"CatalogItemCreate"},"CatalogItemsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UPSTREAM_ERROR"],"title":"CatalogItemsPostResponsesContentApplicationJsonSchemaCode"},"CreateCatalogItemRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateCatalogItemRequestBadRequestError"},"CreateCatalogItemRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateCatalogItemRequestUnauthorizedError"},"CreateCatalogItemRequestBadGatewayError":{"type":"object","properties":{"code":{"$ref":"#/components/schemas/CatalogItemsPostResponsesContentApplicationJsonSchemaCode"},"message":{"type":"string"},"id":{"type":"integer","description":"The id of the catalog item that was created."}},"title":"CreateCatalogItemRequestBadGatewayError"},"CatalogItemUpdateType":{"type":"string","enum":["PRODUCT","SERVICE"],"description":"Catalog item type","title":"CatalogItemUpdateType"},"CatalogItemUpdateWasteFactorMode":{"type":"string","enum":["STATIC"],"description":"Waste factor mode. Must be set together with wasteFactorValue — both, or neither.","title":"CatalogItemUpdateWasteFactorMode"},"CatalogItemUpdate":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/CatalogItemUpdateType","description":"Catalog item type"},"name":{"type":"string","description":"Catalog item name"},"category":{"$ref":"#/components/schemas/CatalogCategoryCode","description":"Catalog item category code. Must be a valid ProductCategory or ServiceCategory value."},"code":{"type":"string","description":"Catalog item code"},"description":{"type":["string","null"],"description":"Catalog item description"},"cost":{"type":"number","format":"double","minimum":0,"description":"Catalog item cost"},"price":{"type":"number","format":"double","minimum":0,"description":"Catalog item price"},"tradeGroup":{"$ref":"#/components/schemas/TradeGroup","description":"High-level trade group for this item."},"manufacturer":{"type":["string","null"],"description":"Catalog item manufacturer. PRODUCT items only."},"sku":{"type":["string","null"],"description":"Catalog item SKU. PRODUCT items only — sending an SKU while the item is, or is becoming, a SERVICE returns 400. Converting a PRODUCT that has an SKU into a SERVICE is allowed and does not require clearing it first: services have no SKU, so it is dropped as part of the conversion. Pass null to clear a PRODUCT SKU or during that conversion; an already-SERVICE item with a legacy SKU cannot change or clear it through this API and returns 400.\n"},"isArchived":{"type":"boolean","description":"Set true to archive the item, or false to restore an archived one. Archiving via this field is equivalent to DELETE /catalog-items/{catalog_item_id}.\n"},"preferredVendorId":{"type":["integer","null"],"description":"ID of the preferred vendor. Pass null to clear the preferred vendor."},"unitId":{"type":["integer","null"],"description":"ID of the unit this item is sold/measured in. Pass null to clear it."},"measurementIds":{"type":"array","items":{"type":"integer"},"description":"Replaces the full set of measurement/sub-calculation links driving this item's quantity. Omit this field to leave existing links unchanged; pass an empty array to clear all links. This is NOT a merge/append — any previously linked measurement not included here is unlinked. At most one linked measurement may be a sub-measurement (type SUB_CALCULATION), and it must be the only one linked.\n"},"coverage":{"type":["number","null"],"format":"double","exclusiveMinimum":0,"description":"Measurement units covered per item unit. Must be greater than zero."},"wasteFactorMode":{"oneOf":[{"$ref":"#/components/schemas/CatalogItemUpdateWasteFactorMode"},{"type":"null"}],"description":"Waste factor mode. Must be set together with wasteFactorValue — both, or neither."},"wasteFactorValue":{"type":["number","null"],"format":"double","minimum":0,"maximum":100,"description":"Waste factor percentage (0-100). Must be set together with wasteFactorMode."}},"title":"CatalogItemUpdate"},"CatalogItemsCatalogItemIdPatchResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["UPSTREAM_ERROR"],"title":"CatalogItemsCatalogItemIdPatchResponsesContentApplicationJsonSchemaCode"},"UpdateCatalogItemRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdPatchResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"UpdateCatalogItemRequestBadRequestError"},"UpdateCatalogItemRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateCatalogItemRequestUnauthorizedError"},"UpdateCatalogItemRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdPatchResponsesContentApplicationJsonSchemaCode"}},"title":"UpdateCatalogItemRequestNotFoundError"},"UpdateCatalogItemRequestBadGatewayError":{"type":"object","properties":{"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdPatchResponsesContentApplicationJsonSchemaCode"},"message":{"type":"string"},"id":{"type":"integer","description":"The id of the catalog item that was updated."}},"title":"UpdateCatalogItemRequestBadGatewayError"},"CatalogItemsCatalogItemIdDeleteResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"CatalogItemsCatalogItemIdDeleteResponsesContentApplicationJsonSchemaCode"},"DeleteCatalogItemRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdDeleteResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"DeleteCatalogItemRequestBadRequestError"},"DeleteCatalogItemRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteCatalogItemRequestUnauthorizedError"},"DeleteCatalogItemRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdDeleteResponsesContentApplicationJsonSchemaCode"}},"title":"DeleteCatalogItemRequestNotFoundError"},"DeleteCatalogItemRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/CatalogItemsCatalogItemIdDeleteResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"DeleteCatalogItemRequestBadGatewayError"},"MeasurementsGetParametersType":{"type":"string","enum":["MEASUREMENT","SUB_CALCULATION"],"title":"MeasurementsGetParametersType"},"MeasurementsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"MeasurementsGetResponsesContentApplicationJsonSchemaCode"},"ListMeasurementsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/MeasurementsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListMeasurementsRequestBadRequestError"},"ListMeasurementsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/MeasurementsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListMeasurementsRequestUnauthorizedError"},"ListMeasurementsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/MeasurementsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListMeasurementsRequestBadGatewayError"},"MeasurementsMeasurementIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"MeasurementsMeasurementIdGetResponsesContentApplicationJsonSchemaCode"},"GetMeasurementRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/MeasurementsMeasurementIdGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"GetMeasurementRequestBadRequestError"},"GetMeasurementRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/MeasurementsMeasurementIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetMeasurementRequestUnauthorizedError"},"GetMeasurementRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/MeasurementsMeasurementIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetMeasurementRequestNotFoundError"},"GetMeasurementRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/MeasurementsMeasurementIdGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"GetMeasurementRequestBadGatewayError"},"LabelsGetParametersType":{"type":"string","enum":["WORK","ASSET"],"title":"LabelsGetParametersType"},"LabelType":{"type":"string","enum":["WORK","ASSET"],"description":"Label type — WORK for work-order labels, ASSET for asset labels","title":"LabelType"},"Label":{"type":"object","properties":{"id":{"type":"integer","description":"Label identifier"},"name":{"type":"string","description":"Label display name"},"color":{"type":["string","null"],"description":"Label color as a hex code (e.g. \"#FF5733\"), or null if unset"},"type":{"$ref":"#/components/schemas/LabelType","description":"Label type — WORK for work-order labels, ASSET for asset labels"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","color","type","createdAt","updatedAt"],"description":"A label that can be applied to work orders or assets.","title":"Label"},"LabelsGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"LabelsGetResponsesContentApplicationJsonSchemaCode"},"ListLabelsRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListLabelsRequestBadRequestError"},"ListLabelsRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListLabelsRequestUnauthorizedError"},"ListLabelsRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListLabelsRequestInternalServerError"},"ListLabelsRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListLabelsRequestBadGatewayError"},"LabelsLabelIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"LabelsLabelIdGetResponsesContentApplicationJsonSchemaCode"},"GetLabelRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsLabelIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetLabelRequestUnauthorizedError"},"GetLabelRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsLabelIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetLabelRequestNotFoundError"},"GetLabelRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsLabelIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetLabelRequestInternalServerError"},"GetLabelRequestBadGatewayError":{"type":"object","properties":{"code":{"$ref":"#/components/schemas/LabelsLabelIdGetResponsesContentApplicationJsonSchemaCode"},"message":{"type":"string"}},"required":["code","message"],"title":"GetLabelRequestBadGatewayError"},"CreateLabelRequestType":{"type":"string","enum":["WORK","ASSET"],"description":"Label type — WORK for work-order labels, ASSET for asset labels","title":"CreateLabelRequestType"},"CreateLabelRequest":{"type":"object","properties":{"name":{"type":"string","description":"Label name"},"color":{"type":["string","null"],"description":"Label color as a hex code (e.g. \"#FF5733\")"},"type":{"$ref":"#/components/schemas/CreateLabelRequestType","description":"Label type — WORK for work-order labels, ASSET for asset labels"}},"required":["name","type"],"title":"CreateLabelRequest"},"LabelsPostResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"title":"LabelsPostResponsesContentApplicationJsonSchemaCode"},"CreateLabelRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsPostResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"CreateLabelRequestBadRequestError"},"CreateLabelRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateLabelRequestUnauthorizedError"},"CreateLabelRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/LabelsPostResponsesContentApplicationJsonSchemaCode"}},"title":"CreateLabelRequestInternalServerError"},"CompanyTax":{"type":"object","properties":{"id":{"type":"integer","description":"Tax identifier (use as `taxId` on quotes and invoices where supported)"},"name":{"type":"string","description":"Display name of the tax"},"rate":{"type":"string","description":"Tax rate as a percentage decimal string (e.g. \"7.2500\" for 7.25%)"},"isArchived":{"type":"boolean","description":"Whether this tax is archived and hidden from default listings"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","rate","isArchived","createdAt","updatedAt"],"description":"A tax rate configured for the company.","title":"CompanyTax"},"TaxesGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["GRAPHQL_ERROR"],"title":"TaxesGetResponsesContentApplicationJsonSchemaCode"},"ListTaxesRequestBadRequestError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TaxesGetResponsesContentApplicationJsonSchemaCode"},"field":{"type":"string","description":"Field that caused the validation error (if applicable)"}},"title":"ListTaxesRequestBadRequestError"},"ListTaxesRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TaxesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListTaxesRequestUnauthorizedError"},"ListTaxesRequestInternalServerError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/TaxesGetResponsesContentApplicationJsonSchemaCode"}},"title":"ListTaxesRequestInternalServerError"},"ListTaxesRequestBadGatewayError":{"type":"object","properties":{"message":{"type":"string","description":"Summary of the downstream service failure"},"code":{"$ref":"#/components/schemas/TaxesGetResponsesContentApplicationJsonSchemaCode"}},"required":["message","code"],"title":"ListTaxesRequestBadGatewayError"},"UserRole":{"type":"object","properties":{"id":{"type":"string","description":"Role identifier"},"name":{"type":"string","description":"Role name"}},"title":"UserRole"},"User":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"firstName":{"type":"string","description":"First name"},"lastName":{"type":"string","description":"Last name"},"email":{"type":"string","format":"email","description":"Email address"},"phone":{"type":"string","description":"Phone number"},"role":{"$ref":"#/components/schemas/UserRole"}},"required":["id","firstName","lastName","email","role"],"title":"User"},"Role":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier"},"name":{"type":"string","description":"Role name"},"active":{"type":"boolean","description":"Whether the role is active"}},"required":["id","name","active"],"title":"Role"},"TeamMemberRole":{"type":"object","properties":{"id":{"type":"string","description":"Role identifier"},"name":{"type":"string","description":"Role name"}},"title":"TeamMemberRole"},"TeamMember":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier"},"firstName":{"type":"string","description":"First name"},"lastName":{"type":"string","description":"Last name"},"email":{"type":"string","format":"email","description":"Email address"},"phone":{"type":"string","description":"Phone number"},"role":{"$ref":"#/components/schemas/TeamMemberRole"},"isTeamLead":{"type":"boolean","description":"Indicates whether this user is the lead for the team."}},"required":["id","firstName","lastName","email","role"],"title":"TeamMember"},"Team":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"workers":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}},"title":"Team"},"UserInvite":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address of user to invite"},"firstName":{"type":"string","description":"User's first name"},"lastName":{"type":"string","description":"User's last name"},"roleIds":{"type":"array","items":{"type":"integer"},"description":"Role IDs to assign to the user"},"phone":{"type":"string","description":"User's phone number"}},"required":["email","firstName","lastName","roleIds"],"title":"UserInvite"},"Users_inviteUser_Response_201":{"type":"object","properties":{"email":{"type":"string","format":"email"},"status":{"type":"string"}},"title":"Users_inviteUser_Response_201"},"PropertiesGetParametersRecordType":{"type":"string","enum":["account","opportunity","project","vendor","ahj","utility"],"title":"PropertiesGetParametersRecordType"},"Property":{"type":"object","properties":{"name":{"type":"string","description":"Property name"},"type":{"type":"string","description":"Property type"},"keyName":{"type":"string","description":"For built-in (isCustom: false) properties, this is the public field name used on the record's create/update/read endpoints (e.g. `address`, `isActive`, `createdAt`). For custom (isCustom: true) properties, this is the key used under the `custom` object.\n"},"isMultiple":{"type":"boolean","description":"Whether the property is a multiple value property"},"options":{"type":"array","items":{"type":"string"},"description":"Property options"},"defaultValue":{"type":"array","items":{"description":"Any type"},"description":"Default value"},"isCustom":{"type":"boolean","description":"True for customer-defined custom columns, false for built-in standard properties."},"readOnly":{"type":"boolean","description":"True if this property cannot be sent on create/update — it is a system or derived field. Custom properties are always readOnly: false.\n"}},"title":"Property"},"Properties_listProperties_Response_200":{"type":"object","properties":{"account":{"type":"array","items":{"$ref":"#/components/schemas/Property"}},"opportunity":{"type":"array","items":{"$ref":"#/components/schemas/Property"}},"project":{"type":"array","items":{"$ref":"#/components/schemas/Property"}},"vendor":{"type":"array","items":{"$ref":"#/components/schemas/Property"}},"ahj":{"type":"array","items":{"$ref":"#/components/schemas/Property"},"description":"Customer-defined custom AHJ properties only (`isCustom: true`). Standard built-in AHJ fields are not included."},"client":{"type":"array","items":{"$ref":"#/components/schemas/Property"},"description":"Deprecated alias for `account`. Contains identical data.","deprecated":true},"request":{"type":"array","items":{"$ref":"#/components/schemas/Property"},"description":"Deprecated alias for `opportunity`. Contains identical data.","deprecated":true}},"title":"Properties_listProperties_Response_200"},"WorkflowType":{"type":"string","enum":["PROJECT"],"description":"Workflow type","title":"WorkflowType"},"WorkflowCreatedBy":{"type":"object","properties":{"id":{"type":"integer","description":"User identifier"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"avatarUrl":{"type":["string","null"],"description":"URL to user avatar image"}},"title":"WorkflowCreatedBy"},"WorkflowPhasesItems":{"type":"object","properties":{"id":{"type":"integer","description":"Phase identifier"},"name":{"type":"string","description":"Phase name"},"type":{"type":"string","description":"Phase type"},"description":{"type":["string","null"],"description":"Phase description"},"redSla":{"type":["integer","null"],"description":"Red SLA (Service Level Agreement) in days"},"yellowSla":{"type":["integer","null"],"description":"Yellow SLA (Service Level Agreement) in days"}},"title":"WorkflowPhasesItems"},"Workflow":{"type":"object","properties":{"id":{"type":"integer","description":"Workflow identifier"},"name":{"type":"string","description":"Workflow name"},"description":{"type":["string","null"],"description":"Workflow description"},"type":{"$ref":"#/components/schemas/WorkflowType","description":"Workflow type"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"createdBy":{"oneOf":[{"$ref":"#/components/schemas/WorkflowCreatedBy"},{"type":"null"}]},"phases":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowPhasesItems"}}},"title":"Workflow"},"WorkflowsWorkflowIdGetResponsesContentApplicationJsonSchemaCode":{"type":"string","enum":["NOT_FOUND"],"title":"WorkflowsWorkflowIdGetResponsesContentApplicationJsonSchemaCode"},"GetWorkflowRequestUnauthorizedError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkflowsWorkflowIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetWorkflowRequestUnauthorizedError"},"GetWorkflowRequestNotFoundError":{"type":"object","properties":{"message":{"type":"string"},"code":{"$ref":"#/components/schemas/WorkflowsWorkflowIdGetResponsesContentApplicationJsonSchemaCode"}},"title":"GetWorkflowRequestNotFoundError"}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}}}