service:help:spec
Machine-readable API catalog for the Service agent.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}Generated from live external Agent API catalog metadata for SERVICE. Last generated at 2026-06-05T21:17:33+00:00.
service:help:specMachine-readable API catalog for the Service agent.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}service:help:openapiOpenAPI 3 YAML fragment for the Service agent.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}service:help:markdownMarkdown summary for the Service agent API.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}service:help:guidelinesBest practices and workflows for external Service agents, including goals/coach usage and pipeline health/score semantics.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}service:records:readRead CRM entities for the tenant. entity=companies includes Host, employee_count, originating_user_id, originating_date_added when columns exist, pipeline stage, current_pipeline_value, companies_extra[] unless include_companies_extra=0. Optional originating_user_id and originating_date_from/to on entity=companies. entity=contacts supports email= (case-insensitive substring).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&entity=companies|contacts|notes|tasks&companies_id=optional&limit=500entity: companies|contacts|notes|taskscompanies_id: optional filter when entity=notesoriginating_user_id: optional when entity=companiesoriginating_date_from: optional when entity=companiesoriginating_date_to: optional when entity=companiesemail: optional when entity=contacts (case-insensitive search)limit: optionalinclude_companies_extra: optional 0 when entity=companies to omit custom fieldshints: optional 0|false|off|no omits agent_hints on this and other GET JSON responsesservice:companies:updateUpdate core company fields for the tenant (same fields as sales:companies:update), including employee_count. Requires view_company menu access for the acting user.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)companies_id: int, requiredcompanies_name: optional stringcompanies_website: optional stringcompanies_main_phone: optional stringcompanies_status: optional stringcompanies_type: optional stringcompanies_pipeline_stage: optional int (companies_stage_options_id)companies_temperature: optional Hot|Warm|Coldemployee_count: optional int >= 1service:hashtags:searchSearch CRM records by note hashtag token (same hashtag behavior humans use in companies_list hashtag links). Accepts hashtag=tag or hashtag=#tag and returns grouped companies/contacts/quotes/notes for the tenant.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&hashtag={tag}&entity=all|companies|contacts|quotes|notes&limit=50&offset=0hashtag: required string hashtag token, with or without leading #entity: optional all|companies|contacts|quotes|notes (default all)limit: optional int, default 50, max 200offset: optional int, default 0hints: optional 0|false|off|no omits agent_hintsservice:notes:listAlias for service:records:read&entity=notes (resource=notes&action=list).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&companies_id=optional&limit=500companies_id: optional intlimit: optionalservice:notes_tasks:createCreate a note (and optional recurring task) on a company or contact.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)companies_id: intcontacts_id: intuser_note: stringnote_view: internal|externalnotes_table: companies|contactsis_recurring: optional boolrecurrence_type: optional stringfirst_occurrence: optional stringend_date: optional stringoccurrence_limit: optional intinclude_ai: optional 0|1 (subscriber Gmail/email knowledge when 1; default 0)service:notes:getGet one note by user_notes_id (scoped via company tenant).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&user_notes_id={id}user_notes_id: int, requiredservice:notifications:listOpen in-app notifications for the acting user plus due/overdue personal task counts. Product review request notifications can include review_request context and one_tap submit payloads.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}service:notifications:dismissMark a notification as read for the acting user.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)users_notifications_id: int, requiredservice:todos:listList personal to-dos for the acting user (My To-Do List parity).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&status=all|open|closed&limit=100status: optional open|closed|all, default alllimit: optional int, default 100, max 200hints: optional 0 to omit agent_hintsservice:todos:createAdd a personal to-do for the acting user.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)todo_text: string, requireddue_date: YYYY-MM-DD, requiredservice:todos:completeMark a personal to-do complete.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)user_notes_id: int, requiredservice:product_updates:listSubscriber-visible What's New entries.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&limit=20&since_date=YYYY-MM-DD&after_id=0limit: optional int, default 20, max 100since_date: optionalafter_id: optional intservice:product_reviews:createCapture a product review from an external Service AI principal (same payload model as Sales route).
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)rating: int 1..5, requiredreview_text: string, requiredheadline: optional stringwould_recommend: optional booleancompanies_id: optional intcontacts_id: optional intsource: optional stringreviewer_name: optional stringreviewer_email: optional stringagent_provider: optional stringagent_model: optional stringagent_run_id: optional stringagent_identity_label: optional stringservice:product_reviews:listList captured product reviews for the tenant (paginated).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&limit=50&offset=0&companies_id=optional&agent_type=optionallimit: optional int, default 50, max 200offset: optional int, default 0companies_id: optional intagent_type: optional sales|servicehints: optional 0 to omit agent_hintsservice:feature_feedback:createCapture enhancement feedback from external Service AI principals when functionality is not meeting needs.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)title: string, requireddetails: string, requiredfeedback_type: optional improvement|bug|request|ux|other (default improvement)priority: optional low|normal|high|critical (default normal)feature_key: optional stringcompanies_id: optional intcontacts_id: optional intsource: optional stringagent_provider: optional stringagent_model: optional stringagent_run_id: optional stringagent_identity_label: optional stringservice:feature_feedback:listList feature feedback captured from external agents (paginated).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&limit=50&offset=0&feedback_type=optional&priority=optionallimit: optional int, default 50, max 200offset: optional int, default 0feedback_type: optional improvement|bug|request|ux|otherpriority: optional low|normal|high|criticalhints: optional 0 to omit agent_hintsservice:goals:getGet goal settings for the acting user (or optional same-tenant for_user_id).
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&for_user_id=optionalfor_user_id: optional int in same subscriber; defaults to acting_user_idhints: optional 0 to omit agent_hintsservice:goals:updateUpdate one or more goal fields for the acting user (or optional same-tenant for_user_id).
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)for_user_id: optional int in same subscriber; defaults to acting_user_idgoals: object keyed by goal field names (recommended)total_clients_goal: optional int >= 0monthly_clients_goal: optional int >= 0total_prospects_goal: optional int >= 0monthly_prospects_goal: optional int >= 0total_quotes_goal: optional int >= 0 when column existsmonthly_quotes_goal: optional int >= 0 when column existsconsistency_goal_pct: optional number clamped 0..100 when column existsclient_retention_goal_pct: optional number clamped 0..100 when column existsavg_underwriting_time_goal: optional int >= 0 when column existsclient_stability_goal_days: optional int >= 0 when column existsservice:coach:getGet Personal Coach settings for acting user or optional same-tenant for_user_id. Requires personal_coach entitlement.
GET /agent_api_router.php?agent={agent}&resource={resource}&action={action}&for_user_id=optionalfor_user_id: optional int in same subscriber; defaults to acting_user_idhints: optional 0 to omit agent_hintsservice:coach:updateUpdate Personal Coach settings for acting user or optional same-tenant for_user_id. Requires personal_coach entitlement. External machine users are forced to enabled + bi_weekly + Monday defaults.
POST /agent_api_router.php?agent={agent}&resource={resource}&action={action} (JSON body)for_user_id: optional int in same subscriber; defaults to acting_user_idenabled: optional 0|1 (ignored for external_machine_agent; forced to 1)report_frequency: required weekly|bi_weekly|semi_monthly|monthly (forced bi_weekly for external_machine_agent)report_day_of_week: required int 0..6 (forced 1 Monday for external_machine_agent)openapi: 3.0.3
info:
title: Quote Rocket Agent API
version: 1.0.0
description: "All HTTP calls are GET or POST to this entrypoint URL with required query parameters agent, resource, and action. POST keeps those params in the URL; JSON body is only for input fields, not routing. Path keys in this file are logical groupings; call the entrypoint with matching query params."
servers:
- url: "https://quoterocket.ai/shr/agent_api_router.php"
paths:
"/service/help/spec":
get:
operationId: service_help_spec
summary: "Machine-readable API catalog for the Service agent."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "help"
- name: action
in: query
required: true
schema:
type: string
default: "spec"
responses:
'200':
description: OK
'201':
description: Created
"/service/help/openapi":
get:
operationId: service_help_openapi
summary: "OpenAPI 3 YAML fragment for the Service agent."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "help"
- name: action
in: query
required: true
schema:
type: string
default: "openapi"
responses:
'200':
description: OK
'201':
description: Created
"/service/help/markdown":
get:
operationId: service_help_markdown
summary: "Markdown summary for the Service agent API."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "help"
- name: action
in: query
required: true
schema:
type: string
default: "markdown"
responses:
'200':
description: OK
'201':
description: Created
"/service/help/guidelines":
get:
operationId: service_help_guidelines
summary: "Best practices and workflows for external Service agents, including goals\/coach usage and pipeline health\/score semantics."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "help"
- name: action
in: query
required: true
schema:
type: string
default: "guidelines"
responses:
'200':
description: OK
'201':
description: Created
"/service/records/read":
get:
operationId: service_records_read
summary: "Read CRM entities for the tenant. entity=companies includes Host, employee_count, originating_user_id, originating_date_added when columns exist, pipeline stage, current_pipeline_value, companies_extra[] unless include_companies_extra=0. Optional originating_user_id and originating_date_from\/to on entity=companies. entity=contacts supports email= (case-insensitive substring)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "records"
- name: action
in: query
required: true
schema:
type: string
default: "read"
responses:
'200':
description: OK
'201':
description: Created
"/service/companies/update":
post:
operationId: service_companies_update
summary: "Update core company fields for the tenant (same fields as sales:companies:update), including employee_count. Requires view_company menu access for the acting user."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "companies"
- name: action
in: query
required: true
schema:
type: string
default: "update"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/hashtags/search":
get:
operationId: service_hashtags_search
summary: "Search CRM records by note hashtag token (same hashtag behavior humans use in companies_list hashtag links). Accepts hashtag=tag or hashtag=#tag and returns grouped companies\/contacts\/quotes\/notes for the tenant."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "hashtags"
- name: action
in: query
required: true
schema:
type: string
default: "search"
responses:
'200':
description: OK
'201':
description: Created
"/service/notes/list":
get:
operationId: service_notes_list
summary: "Alias for service:records:read&entity=notes (resource=notes&action=list)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "notes"
- name: action
in: query
required: true
schema:
type: string
default: "list"
responses:
'200':
description: OK
'201':
description: Created
"/service/notes_tasks/create":
post:
operationId: service_notes_tasks_create
summary: "Create a note (and optional recurring task) on a company or contact."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "notes_tasks"
- name: action
in: query
required: true
schema:
type: string
default: "create"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/notes/get":
get:
operationId: service_notes_get
summary: "Get one note by user_notes_id (scoped via company tenant)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "notes"
- name: action
in: query
required: true
schema:
type: string
default: "get"
responses:
'200':
description: OK
'201':
description: Created
"/service/notifications/list":
get:
operationId: service_notifications_list
summary: "Open in-app notifications for the acting user plus due\/overdue personal task counts. Product review request notifications can include review_request context and one_tap submit payloads."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "notifications"
- name: action
in: query
required: true
schema:
type: string
default: "list"
responses:
'200':
description: OK
'201':
description: Created
"/service/notifications/dismiss":
post:
operationId: service_notifications_dismiss
summary: "Mark a notification as read for the acting user."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "notifications"
- name: action
in: query
required: true
schema:
type: string
default: "dismiss"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/todos/list":
get:
operationId: service_todos_list
summary: "List personal to-dos for the acting user (My To-Do List parity)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "todos"
- name: action
in: query
required: true
schema:
type: string
default: "list"
responses:
'200':
description: OK
'201':
description: Created
"/service/todos/create":
post:
operationId: service_todos_create
summary: "Add a personal to-do for the acting user."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "todos"
- name: action
in: query
required: true
schema:
type: string
default: "create"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/todos/complete":
post:
operationId: service_todos_complete
summary: "Mark a personal to-do complete."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "todos"
- name: action
in: query
required: true
schema:
type: string
default: "complete"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/product_updates/list":
get:
operationId: service_product_updates_list
summary: "Subscriber-visible What's New entries."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "product_updates"
- name: action
in: query
required: true
schema:
type: string
default: "list"
responses:
'200':
description: OK
'201':
description: Created
"/service/product_reviews/create":
post:
operationId: service_product_reviews_create
summary: "Capture a product review from an external Service AI principal (same payload model as Sales route)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "product_reviews"
- name: action
in: query
required: true
schema:
type: string
default: "create"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/product_reviews/list":
get:
operationId: service_product_reviews_list
summary: "List captured product reviews for the tenant (paginated)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "product_reviews"
- name: action
in: query
required: true
schema:
type: string
default: "list"
responses:
'200':
description: OK
'201':
description: Created
"/service/feature_feedback/create":
post:
operationId: service_feature_feedback_create
summary: "Capture enhancement feedback from external Service AI principals when functionality is not meeting needs."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "feature_feedback"
- name: action
in: query
required: true
schema:
type: string
default: "create"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/feature_feedback/list":
get:
operationId: service_feature_feedback_list
summary: "List feature feedback captured from external agents (paginated)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "feature_feedback"
- name: action
in: query
required: true
schema:
type: string
default: "list"
responses:
'200':
description: OK
'201':
description: Created
"/service/goals/get":
get:
operationId: service_goals_get
summary: "Get goal settings for the acting user (or optional same-tenant for_user_id)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "goals"
- name: action
in: query
required: true
schema:
type: string
default: "get"
responses:
'200':
description: OK
'201':
description: Created
"/service/goals/update":
post:
operationId: service_goals_update
summary: "Update one or more goal fields for the acting user (or optional same-tenant for_user_id)."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "goals"
- name: action
in: query
required: true
schema:
type: string
default: "update"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
"/service/coach/get":
get:
operationId: service_coach_get
summary: "Get Personal Coach settings for acting user or optional same-tenant for_user_id. Requires personal_coach entitlement."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "coach"
- name: action
in: query
required: true
schema:
type: string
default: "get"
responses:
'200':
description: OK
'201':
description: Created
"/service/coach/update":
post:
operationId: service_coach_update
summary: "Update Personal Coach settings for acting user or optional same-tenant for_user_id. Requires personal_coach entitlement. External machine users are forced to enabled + bi_weekly + Monday defaults."
parameters:
- name: agent
in: query
required: true
schema:
type: string
enum: [service]
- name: resource
in: query
required: true
schema:
type: string
default: "coach"
- name: action
in: query
required: true
schema:
type: string
default: "update"
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: OK
'201':
description: Created
# Quote Rocket Agent API (service)
**Agent Ledger:** every call is audited with a human-readable line. Use `request_id` from responses.
## Authentication
- `Authorization: Bearer <api_key>` or `X-API-Key: <api_key>`
- Principal includes `acting_user_id` for menu parity.
## Entry URL (required for every call)
**Always** append `agent`, `resource`, and `action` as query parameters on `agent_api_router.php` — including **POST**. Do not send only a JSON body to the bare entrypoint; that returns `route_not_found`.
`https://quoterocket.ai/shr/agent_api_router.php?agent=service&resource=...&action=...`
## Best practices (external agents)
- Full document: `service:help:guidelines` (GET same entry URL with `resource=help&action=guidelines`).
- When humans address you in Quote Rocket, add a **note on the company or contact** via the API so the conversation stays in CRM.
- Use **notifications:list** / **notifications:dismiss**, **todos:list** / **todos:create** / **todos:complete**, and **product_updates:list** as designed in the UI.
- Most GET JSON responses include an **agent_hints** object; pass **hints=0** to omit it.
## Routes
### `service:help:spec`
- **Method:** GET
- **Capability:** `service.help.read`
- **Description:** Machine-readable API catalog for the Service agent.
### `service:help:openapi`
- **Method:** GET
- **Capability:** `service.help.read`
- **Description:** OpenAPI 3 YAML fragment for the Service agent.
### `service:help:markdown`
- **Method:** GET
- **Capability:** `service.help.read`
- **Description:** Markdown summary for the Service agent API.
### `service:help:guidelines`
- **Method:** GET
- **Capability:** `service.help.read`
- **Description:** Best practices and workflows for external Service agents, including goals/coach usage and pipeline health/score semantics.
### `service:records:read`
- **Method:** GET
- **Capability:** `service.records.read`
- **Description:** Read CRM entities for the tenant. entity=companies includes Host, employee_count, originating_user_id, originating_date_added when columns exist, pipeline stage, current_pipeline_value, companies_extra[] unless include_companies_extra=0. Optional originating_user_id and originating_date_from/to on entity=companies. entity=contacts supports email= (case-insensitive substring).
- **Query:**
- `entity`: companies|contacts|notes|tasks
- `companies_id`: optional filter when entity=notes
- `originating_user_id`: optional when entity=companies
- `originating_date_from`: optional when entity=companies
- `originating_date_to`: optional when entity=companies
- `email`: optional when entity=contacts (case-insensitive search)
- `limit`: optional
- `include_companies_extra`: optional 0 when entity=companies to omit custom fields
- `hints`: optional 0|false|off|no omits agent_hints on this and other GET JSON responses
### `service:companies:update`
- **Method:** POST
- **Capability:** `service.companies.update`
- **Description:** Update core company fields for the tenant (same fields as sales:companies:update), including employee_count. Requires view_company menu access for the acting user.
- **JSON body:**
- `companies_id`: int, required
- `companies_name`: optional string
- `companies_website`: optional string
- `companies_main_phone`: optional string
- `companies_status`: optional string
- `companies_type`: optional string
- `companies_pipeline_stage`: optional int (companies_stage_options_id)
- `companies_temperature`: optional Hot|Warm|Cold
- `employee_count`: optional int >= 1
### `service:hashtags:search`
- **Method:** GET
- **Capability:** `service.records.read`
- **Description:** Search CRM records by note hashtag token (same hashtag behavior humans use in companies_list hashtag links). Accepts hashtag=tag or hashtag=#tag and returns grouped companies/contacts/quotes/notes for the tenant.
- **Query:**
- `hashtag`: required string hashtag token, with or without leading #
- `entity`: optional all|companies|contacts|quotes|notes (default all)
- `limit`: optional int, default 50, max 200
- `offset`: optional int, default 0
- `hints`: optional 0|false|off|no omits agent_hints
### `service:notes:list`
- **Method:** GET
- **Capability:** `service.records.read`
- **Description:** Alias for service:records:read&entity=notes (resource=notes&action=list).
- **Query:**
- `companies_id`: optional int
- `limit`: optional
### `service:notes_tasks:create`
- **Method:** POST
- **Capability:** `service.notes_tasks.create`
- **Description:** Create a note (and optional recurring task) on a company or contact.
- **JSON body:**
- `companies_id`: int
- `contacts_id`: int
- `user_note`: string
- `note_view`: internal|external
- `notes_table`: companies|contacts
- `is_recurring`: optional bool
- `recurrence_type`: optional string
- `first_occurrence`: optional string
- `end_date`: optional string
- `occurrence_limit`: optional int
- `include_ai`: optional 0|1 (subscriber Gmail/email knowledge when 1; default 0)
### `service:notes:get`
- **Method:** GET
- **Capability:** `service.notes.read`
- **Description:** Get one note by user_notes_id (scoped via company tenant).
- **Query:**
- `user_notes_id`: int, required
### `service:notifications:list`
- **Method:** GET
- **Capability:** `service.notifications.read`
- **Description:** Open in-app notifications for the acting user plus due/overdue personal task counts. Product review request notifications can include review_request context and one_tap submit payloads.
### `service:notifications:dismiss`
- **Method:** POST
- **Capability:** `service.notifications.write`
- **Description:** Mark a notification as read for the acting user.
- **JSON body:**
- `users_notifications_id`: int, required
### `service:todos:list`
- **Method:** GET
- **Capability:** `service.todos.read`
- **Description:** List personal to-dos for the acting user (My To-Do List parity).
- **Query:**
- `status`: optional open|closed|all, default all
- `limit`: optional int, default 100, max 200
- `hints`: optional 0 to omit agent_hints
### `service:todos:create`
- **Method:** POST
- **Capability:** `service.todos.write`
- **Description:** Add a personal to-do for the acting user.
- **JSON body:**
- `todo_text`: string, required
- `due_date`: YYYY-MM-DD, required
### `service:todos:complete`
- **Method:** POST
- **Capability:** `service.todos.write`
- **Description:** Mark a personal to-do complete.
- **JSON body:**
- `user_notes_id`: int, required
### `service:product_updates:list`
- **Method:** GET
- **Capability:** `service.product_updates.read`
- **Description:** Subscriber-visible What's New entries.
- **Query:**
- `limit`: optional int, default 20, max 100
- `since_date`: optional
- `after_id`: optional int
### `service:product_reviews:create`
- **Method:** POST
- **Capability:** `service.product_reviews.write`
- **Description:** Capture a product review from an external Service AI principal (same payload model as Sales route).
- **JSON body:**
- `rating`: int 1..5, required
- `review_text`: string, required
- `headline`: optional string
- `would_recommend`: optional boolean
- `companies_id`: optional int
- `contacts_id`: optional int
- `source`: optional string
- `reviewer_name`: optional string
- `reviewer_email`: optional string
- `agent_provider`: optional string
- `agent_model`: optional string
- `agent_run_id`: optional string
- `agent_identity_label`: optional string
### `service:product_reviews:list`
- **Method:** GET
- **Capability:** `service.product_reviews.read`
- **Description:** List captured product reviews for the tenant (paginated).
- **Query:**
- `limit`: optional int, default 50, max 200
- `offset`: optional int, default 0
- `companies_id`: optional int
- `agent_type`: optional sales|service
- `hints`: optional 0 to omit agent_hints
### `service:feature_feedback:create`
- **Method:** POST
- **Capability:** `service.feature_feedback.write`
- **Description:** Capture enhancement feedback from external Service AI principals when functionality is not meeting needs.
- **JSON body:**
- `title`: string, required
- `details`: string, required
- `feedback_type`: optional improvement|bug|request|ux|other (default improvement)
- `priority`: optional low|normal|high|critical (default normal)
- `feature_key`: optional string
- `companies_id`: optional int
- `contacts_id`: optional int
- `source`: optional string
- `agent_provider`: optional string
- `agent_model`: optional string
- `agent_run_id`: optional string
- `agent_identity_label`: optional string
### `service:feature_feedback:list`
- **Method:** GET
- **Capability:** `service.feature_feedback.read`
- **Description:** List feature feedback captured from external agents (paginated).
- **Query:**
- `limit`: optional int, default 50, max 200
- `offset`: optional int, default 0
- `feedback_type`: optional improvement|bug|request|ux|other
- `priority`: optional low|normal|high|critical
- `hints`: optional 0 to omit agent_hints
### `service:goals:get`
- **Method:** GET
- **Capability:** `service.goals.read`
- **Description:** Get goal settings for the acting user (or optional same-tenant for_user_id).
- **Query:**
- `for_user_id`: optional int in same subscriber; defaults to acting_user_id
- `hints`: optional 0 to omit agent_hints
### `service:goals:update`
- **Method:** POST
- **Capability:** `service.goals.write`
- **Description:** Update one or more goal fields for the acting user (or optional same-tenant for_user_id).
- **JSON body:**
- `for_user_id`: optional int in same subscriber; defaults to acting_user_id
- `goals`: object keyed by goal field names (recommended)
- `total_clients_goal`: optional int >= 0
- `monthly_clients_goal`: optional int >= 0
- `total_prospects_goal`: optional int >= 0
- `monthly_prospects_goal`: optional int >= 0
- `total_quotes_goal`: optional int >= 0 when column exists
- `monthly_quotes_goal`: optional int >= 0 when column exists
- `consistency_goal_pct`: optional number clamped 0..100 when column exists
- `client_retention_goal_pct`: optional number clamped 0..100 when column exists
- `avg_underwriting_time_goal`: optional int >= 0 when column exists
- `client_stability_goal_days`: optional int >= 0 when column exists
### `service:coach:get`
- **Method:** GET
- **Capability:** `service.coach.read`
- **Description:** Get Personal Coach settings for acting user or optional same-tenant for_user_id. Requires personal_coach entitlement.
- **Query:**
- `for_user_id`: optional int in same subscriber; defaults to acting_user_id
- `hints`: optional 0 to omit agent_hints
### `service:coach:update`
- **Method:** POST
- **Capability:** `service.coach.write`
- **Description:** Update Personal Coach settings for acting user or optional same-tenant for_user_id. Requires personal_coach entitlement. External machine users are forced to enabled + bi_weekly + Monday defaults.
- **JSON body:**
- `for_user_id`: optional int in same subscriber; defaults to acting_user_id
- `enabled`: optional 0|1 (ignored for external_machine_agent; forced to 1)
- `report_frequency`: required weekly|bi_weekly|semi_monthly|monthly (forced bi_weekly for external_machine_agent)
- `report_day_of_week`: required int 0..6 (forced 1 Monday for external_machine_agent)