# NextX Developers > Public REST API, webhooks and MCP server for NextX. REST base URL: https://api.nextx.vn. MCP server (OAuth): https://mcp.nextx.vn/mcp. Auth: OAuth 2.0 (client credentials / authorization code) or API key. Tooling: Node.js/Python SDK, `nextx` CLI. ## REST endpoints ### crm - `GET /api/v1/crm/contacts` (scope `crm.contacts.view`): Search/list contacts. - `q` (query): Search keyword - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `GET /api/v1/crm/contacts/{id}` (scope `crm.contacts.view`): Details of one contact. - `id` (path, required): Contact id - `POST /api/v1/crm/contacts` (scope `crm.contacts.create`): Create a new contact. - `contactType` (body, required): INDIVIDUAL or BUSINESS; cannot be changed after creation - `fullName` (body, required): - `email` (body): - `phone` (body): - `companyName` (body): - `jobTitle` (body): - `customFields` (body): Keys are custom field codes - `GET /api/v1/crm/opportunities` (scope `crm.opportunities.view`): Opportunity/deal pipeline. - `q` (query): Keyword by opportunity name/code - `status` (query): Opportunity status - `stageId` (query): Filter by pipeline stage - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `GET /api/v1/crm/opportunities/{id}` (scope `crm.opportunities.view`): Deal details. - `id` (path, required): - `PATCH /api/v1/crm/opportunities/{id}/stage` (scope `crm.opportunities.manage`): Change a deal's stage. Not allowed once the deal is Won or Lost. - `id` (path, required): - `pipelineStageId` (body, required): Target stage id in the pipeline - `GET /api/v1/crm/opportunities/stats` (scope `crm.opportunities.view`): Opportunity overview: open/won/lost totals, expected revenue, forecast, win rate, new in the last N days, breakdown by stage. - `periodDays` (query): Most recent days, 1 to 365; default 30 - `GET /api/v1/crm/activities` (scope `crm.reports.view`): Recent activity across the workspace, newest first. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): 1–100; default 20 - `activityType` (query): Filter by activity type - `fromDate` (query): ISO-8601 - `toDate` (query): ISO-8601 - `contactId` (query): - `POST /api/v1/crm/tasks` (scope `crm.tasks.manage`): Create a task. It can be linked to only ONE of: contact, opportunity or ticket; otherwise 422 TASK_SINGLE_LINK_VIOLATION. - `title` (body, required): Up to 500 characters - `status` (body, required): TODO, IN_PROGRESS or DONE - `priority` (body, required): LOW, MEDIUM or HIGH - `description` (body): - `dueDate` (body): YYYY-MM-DD - `assigneeId` (body): - `contactId` (body): Only one of contactId / opportunityId / ticketId - `opportunityId` (body): - `ticketId` (body): ### comm - `POST /api/v1/comm/conversations/{id}/messages` (scope `comm.conversations.handle`): Send a message into an existing conversation. Not allowed when the conversation is Resolved or handled by a bot. - `id` (path, required): Conversation id - `type` (body, required): Text, Image, File, Audio, Video, Sticker, Location, Product or Contact - `content` (body): Content (when type = Text) - `clientId` (body): Deduplication key (idempotency) ### sales - `GET /api/v1/sales/orders` (scope `sales.orders.view`): List orders. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `GET /api/v1/sales/orders/{id}` (scope `sales.orders.view`): Details of one order. - `id` (path, required): - `GET /api/v1/sales/products` (scope `sales.products.view`): List/search products. - `search` (query): - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `GET /api/v1/sales/products/{id}` (scope `sales.products.view`): Product details. - `id` (path, required): - `GET /api/v1/sales/products/{id}/stock` (scope `sales.products.view`): Stock of one product. - `id` (path, required): - `GET /api/v1/sales/customers` (scope `sales.customers.view`): List customers. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) ### office - `POST /api/v1/office/tables/{id}/records/list` (scope `office.base.record.view`): List records in a table. - `id` (path, required): Table id - `page` (body): - `pageSize` (body): Rows per page - `GET /api/v1/office/tables/{id}/records/{recordId}` (scope `office.base.record.view`): Details of one record. - `id` (path, required): Table id - `recordId` (path, required): - `POST /api/v1/office/tables/{id}/records` (scope `office.base.record.manage`): Create a record. - `id` (path, required): Table id - `data` (body, required): Field values keyed by field_id - `PUT /api/v1/office/tables/{id}/records/{recordId}` (scope `office.base.record.manage`): Update a record. - `id` (path, required): Table id - `recordId` (path, required): - `data` (body, required): - `replace` (body): true = overwrite everything - `DELETE /api/v1/office/tables/{id}/records/{recordId}` (scope `office.base.record.manage`): Delete a record. - `id` (path, required): Table id - `recordId` (path, required): - `GET /api/v1/office/approvals/instances` (scope `office.approval.instance.view`): List approval requests. - `role` (query): Request scope; default mine (requests submitted by the caller) - `page` (query): - `pageSize` (query): Rows per page - `GET /api/v1/office/approvals/instances/{id}` (scope `office.approval.instance.view`): Approval request details. - `id` (path, required): - `POST /api/v1/office/approvals/instances` (scope `office.approval.instance.manage`): Create an approval request from a template. - `definitionCode` (body, required): Approval template code - `formValue` (body): Form values (JSON string) - `POST /api/v1/office/approvals/tasks/{taskId}/approve` (scope `office.approval.instance.manage`): Approve one approval task. - `taskId` (path, required): - `comment` (body): - `POST /api/v1/office/approvals/tasks/{taskId}/reject` (scope `office.approval.instance.manage`): Reject one approval task. - `taskId` (path, required): - `comment` (body): ### hrm - `GET /api/v1/hrm/attendance/devices` (scope `hrm.attendance_devices.view`): List attendance devices. - `GET /api/v1/hrm/attendance/raw-punches` (scope `hrm.attendance_raw_punches.view`): List raw attendance punches. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `employeeId` (query): - `from` (query): YYYY-MM-DD - `to` (query): YYYY-MM-DD - `GET /api/v1/hrm/attendance/clock-history/daily` (scope `hrm.attendance_raw_punches.view`): Daily attendance summary. - `from` (query, required): YYYY-MM-DD - `to` (query, required): YYYY-MM-DD - `employeeId` (query): - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `GET /api/v1/hrm/attendance/clock-history/timeline/{employeeId}` (scope `hrm.attendance_raw_punches.view`): Attendance timeline of one employee. - `employeeId` (path, required): - `from` (query, required): YYYY-MM-DD - `to` (query, required): YYYY-MM-DD - `GET /api/v1/hrm/employees/{employeeId}/credentials` (scope `hrm.attendance_devices.view`): List fingerprints/faces/cards of one employee. - `employeeId` (path, required): ### dms - `GET /api/v1/dms/catalog/products` (scope `dms.catalog.view`): List catalog products. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `GET /api/v1/dms/tracking/check-ins` (scope `dms.checkins.view`): List store visit check-ins. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `employeeId` (query): - `dateFrom` (query): - `dateTo` (query): - `GET /api/v1/dms/daily-plans` (scope `dms.daily_plans.view`): List daily visit plans. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `employeeId` (query): - `planDate` (query): YYYY-MM-DD - `status` (query): - `GET /api/v1/dms/daily-plans/{id}` (scope `dms.daily_plans.view`): Details of one visit plan. - `id` (path, required): - `GET /api/v1/dms/outlets` (scope `dms.outlets.view`): List outlets/points of sale. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `q` (query): Keyword - `GET /api/v1/dms/orders` (scope `dms.orders.view`): List DMS orders. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `outletId` (query): - `status` (query): - `GET /api/v1/dms/routes` (scope `dms.routes.view`): List sales routes. - `page` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `status` (query): ### call - `GET /api/v1/call/agents` (scope `call.agents.view`): List call center agents. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `status` (query): - `search` (query): - `GET /api/v1/call/campaigns` (scope `call.campaigns.view`): List call campaigns. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `status` (query): - `search` (query): - `GET /api/v1/call/call-flows` (scope `call.call_flows.view`): List call flows. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `status` (query): - `search` (query): - `GET /api/v1/call/ivr-flows` (scope `call.ivr_flows.view`): List IVR flows. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `status` (query): - `search` (query): - `GET /api/v1/call/phone-numbers` (scope `call.phone_numbers.view`): List hotline numbers. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `isActive` (query): - `search` (query): - `GET /api/v1/call/calls` (scope `call.calls.view`): List call history. Note: call.calls.view is a sensitive permission, so OAuth apps cannot request it. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `direction` (query): - `status` (query): - `agentId` (query): - `GET /api/v1/call/queues` (scope `call.queues.view`): List call queues. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page (default 20 for CRM and Sales orders/customers; 50 for Sales products) - `isActive` (query): - `search` (query): ### marketing - `GET /api/v1/marketing/email-campaigns` (scope `marketing.email_campaigns.view`): List email campaigns. - `page` (query): - `size` (query): - `status` (query): - `q` (query): - `GET /api/v1/marketing/email-campaigns/{id}` (scope `marketing.email_campaigns.view`): Details of one email campaign. - `id` (path, required): - `GET /api/v1/marketing/email-templates` (scope `marketing.email_templates.view`): List email templates. - `page` (query): - `size` (query): - `category` (query): - `q` (query): - `GET /api/v1/marketing/google-integrations` (scope `marketing.integrations.view`): List Google integrations (Analytics/Ads/Search Console). - `GET /api/v1/marketing/reports/overview` (scope `marketing.reports.view`): Marketing report overview for a date range. - `from` (query): YYYY-MM-DD - `to` (query): YYYY-MM-DD - `GET /api/v1/marketing/settings/sender-info` (scope `marketing.sender_profiles.view`): List sender profiles (sender info). ### payment - `GET /api/v1/payment/intents/{id}` (scope `payment.intents.view`): Details of one payment intent. - `id` (path, required): - `GET /api/v1/payment/refunds` (scope `payment.refunds.view`): List refunds. - `pageNumber` (query): - `pageSize` (query): - `status` (query): - `from` (query): YYYY-MM-DD - `to` (query): YYYY-MM-DD - `GET /api/v1/payment/transactions` (scope `payment.transactions.view`): List payment transactions. - `pageNumber` (query): - `pageSize` (query): - `providerCode` (query): - `fromDate` (query): YYYY-MM-DD - `toDate` (query): YYYY-MM-DD - `GET /api/v1/payment/transactions/{id}` (scope `payment.transactions.view`): Details of one payment transaction. - `id` (path, required): - `GET /api/v1/payment/subscriptions` (scope `payment.subscriptions.view`): List recurring subscriptions. - `pageNumber` (query): - `pageSize` (query): - `status` (query): - `providerCode` (query): - `GET /api/v1/payment/reports/overview` (scope `payment.reports.view`): Payment report overview for a date range. - `from` (query): YYYY-MM-DD - `to` (query): YYYY-MM-DD ### einvoice - `GET /api/v1/einvoice/invoices` (scope `einvoice.invoices.view`): List e-invoices. - `pageNumber` (query): Page (starts at 1) - `pageSize` (query): Rows per page - `status` (query): - `fromDate` (query): YYYY-MM-DD - `toDate` (query): YYYY-MM-DD - `keyword` (query): - `GET /api/v1/einvoice/invoices/{id}` (scope `einvoice.invoices.view`): Details of one e-invoice (with line items). - `id` (path, required): - `GET /api/v1/einvoice/series` (scope `einvoice.series.view`): List invoice series/symbols. - `providerCode` (query): - `GET /api/v1/einvoice/reports/summary` (scope `einvoice.reports.view`): E-invoice report summary for a date range. - `fromDate` (query): YYYY-MM-DD - `toDate` (query): YYYY-MM-DD - `GET /api/v1/einvoice/settings` (scope `einvoice.settings.view`): E-invoice settings of the workspace. ## AI tools (MCP) Call with `{"args": {...}}`. Export and write tools only create a proposal the user confirms in the app. ### call - `call_agents_search` [read, scope `call:read`]: List call-center agents: extension, status (Available, OnCall, Paused, Acw, Offline) and assigned queues. - `status` (string): Filter by agent status - `search` (string): Name or extension - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `call_call_flows_search` [read, scope `call:read`]: List automated call flows, filtered by status and name. - `status` (string): Flow status - `search` (string): Flow name - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `call_calls_search` [read, scope `call:read`]: Call history within the caller's visible scope: filter by direction (Inbound, Outbound), status, agent, date range and phone number. - `direction` (string): Inbound or Outbound - `status` (string): Ringing, Answered, Completed, Missed, Abandoned, Voicemail or Failed - `agentId` (string): Agent id - `dateFrom` (string): From date (yyyy-MM-dd) - `dateTo` (string): To date (yyyy-MM-dd) - `search` (string): Phone number - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `call_campaigns_search` [read, scope `call:read`]: List calling campaigns (Draft, Active, Paused, Completed, Cancelled), searchable by name. - `status` (string): Campaign status - `search` (string): Campaign name - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `call_ivr_flows_search` [read, scope `call:read`]: List IVR (auto-attendant) scripts, filtered by status and name. - `status` (string): Script status - `search` (string): Script name - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `call_phone_numbers_search` [read, scope `call:read`]: List the call center's phone numbers, active or disabled, searchable. - `isActive` (boolean): true = active numbers only - `search` (string): Phone number - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `call_queues_search` [read, scope `call:read`]: List call queues, active or disabled, searchable. - `isActive` (boolean): true = active queues only - `search` (string): Queue name - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 ### comm - `ads_catalog` [read, scope `comm:read`]: Meta (Facebook/Instagram) Ads operations available to the connected ad account, with each operation's description and parameters. - `ads_read` [read, scope `comm:read`]: Run one read operation of Meta Ads (name from ads_catalog): campaigns, spend, results, ad sets. - `tool` (string, required): Read operation name from ads_catalog - `arguments` (object): Arguments per the operation's schema - `comm_add_ai_bot_qa` [proposal, scope `comm:write`]: Add question–answer pairs to an existing customer-reply assistant's knowledge (max 50 pairs per call). Creates a proposal; it only runs after the user taps Confirm in the app. - `botName` (string, required): Assistant name - `pairs` (object[], required): List of Q&A pairs - `comm_ads_change` [proposal, scope `comm:write`]: Change the Meta ad account (pause/resume campaigns, change budget, create or edit ads) using one write operation from ads_catalog. Creates a proposal; it only runs after the user taps Confirm in the app. - `tool` (string, required): Write operation name from ads_catalog - `arguments` (object): Arguments per the operation's schema - `summary` (string, required): One sentence describing the change - `comm_agents_performance` [read, scope `comm:read`]: Inbox agent metrics: conversations resolved in a period, or current workload. - `metric` (string): resolved = resolved in period; workload = currently assigned - `period` (string): Period: today (default) or week - `comm_assign_to_me` [proposal, scope `comm:write`]: Assign an open inbox conversation to the current user. Creates a proposal; it only runs after the user taps Confirm in the app. - `customer_query` (string, required): Customer name or phone to find the conversation - `conversation_ref` (string): Conversation code (HT-…) if known - `comm_bot_stats` [read, scope `comm:read`]: Inbox auto-reply assistant metrics per period: conversations handled, handed over to agents, and self-resolution rate; optionally by channel. - `period` (string): Period: today (default) or week - `groupBy` (string): channel = per channel; empty = total - `comm_channels_status` [read, scope `comm:read`]: Connected chat channels and their health: channel type, page/account name, status (Active, Error, PendingReconnect, Disconnected), webhook verification. - `channelType` (string): Filter by channel type; empty = all - `activeOnly` (boolean): true = active channels only - `comm_close_conversation` [proposal, scope `comm:write`]: Close an open inbox conversation. Creates a proposal; it only runs after the user taps Confirm in the app. - `customer_query` (string, required): Customer name or phone to find the conversation - `conversation_ref` (string): Conversation code (HT-…) if known - `comm_conversations_search` [read, scope `comm:read`]: Search omnichannel inbox conversations by customer name, channel, status, assignee, unread, priority, customer sentiment, SLA breach, waiting time, sales stage and date range; cursor pagination. - `q` (string): Customer name - `channelType` (string): Facebook, Instagram, ZaloOa, ZaloPersonal, Telegram, Widget, Shopee, Lazada or TikTokShop - `status` (string): Open, WaitingAgent, BotHandling or Resolved - `assignedTo` (string): me = mine; unassigned = nobody - `unreadOnly` (boolean): true = unread only - `priority` (string): Priority - `sentiment` (string): Customer sentiment (e.g. Angry, Negative) - `slaBreached` (boolean): true = SLA breached only - `awaitingOverHours` (integer): Customer waiting at least N hours - `salesStage` (string): Conversation sales stage - `resolvedInDays` (integer): Only conversations closed in the last N days - `createdFrom` (string): Created from (YYYY-MM-DD) - `createdTo` (string): Created to (YYYY-MM-DD) - `limit` (integer): Conversations per call, max 30 - `cursor` (string): Next page cursor (nextCursor from the previous call) - `comm_create_ai_bot` [proposal, scope `comm:write`]: Create a customer-reply assistant on Facebook, Zalo or website widget from a description: name, industry, tone, reply mode, fallback message, channels, business hours and initial Q&A. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string, required): Assistant name - `industry` (string, required): Industry (e.g. Education, Spa) - `tone` (string): Friendly or Professional… - `mode` (string): Auto, Hybrid… - `fallbackMessage` (string): Reply when unsure - `personaPrompt` (string): Form of address and persona - `channelTypes` (string[], required): Facebook, ZaloOa, ZaloPersonal, Widget - `maxEscalateAttempts` (integer): Unsure attempts before handing to an agent - `businessHours` (object): Business hours (Vietnam time) - `qaPairs` (object[]): Initial Q&A - `comm_inbox_breakdown` [read, scope `comm:read`]: Count the inbox by channel: open conversations, all conversations, unread, new contacts or returning customers. - `metric` (string): Metric, default conversations_open - `days` (integer): Recent days (for new_contacts) - `period` (string): Period (for returning_customers) - `comm_messages_get` [read, scope `comm:read`]: Most recent messages of a conversation in time order: direction, sender, type, content, delivery status, internal notes. - `conversationId` (string, required): Conversation id (from comm_conversations_search) - `limit` (integer): Messages to read, max 50 - `comm_messages_volume` [read, scope `comm:read`]: Inbox message volume for a period, split into inbound and outbound; or distribution by hour of day. - `period` (string): Period: today (default) or week - `groupBy` (string): hour = hourly distribution for today - `comm_sales_pipeline` [read, scope `comm:read`]: Sales funnel of chat conversations by agent-assigned stage: New, Consulting, Quoted, Won, Lost. - `period` (string): Period: today (default) or week - `comm_update_ai_bot` [proposal, scope `comm:write`]: Update an existing customer-reply assistant: name, industry, tone, reply mode, fallback message, persona, channels, escalation attempts, business hours. Creates a proposal; it only runs after the user taps Confirm in the app. - `botName` (string, required): Assistant to update - `name` (string): New name (if renaming) - `industry` (string): Industry - `tone` (string): Tone - `mode` (string): Reply mode - `fallbackMessage` (string): Fallback message - `personaPrompt` (string): Persona - `channelTypes` (string[]): Channels - `maxEscalateAttempts` (integer): Attempts before escalation - `businessHours` (object): Business hours ### crm - `crm_add_note` [proposal, scope `crm:write`]: Add a note to a customer profile. Creates a proposal; it only runs after the user taps Confirm in the app. - `phone` (string): Customer phone - `email` (string): Customer email - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `note` (string, required): Note text - `crm_add_tag` [proposal, scope `crm:write`]: Add an existing catalog tag to a customer. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `tag` (string, required): Tag name from the catalog - `crm_appointments_query` [read, scope `crm:read`]: Query appointments: count, list, group by status or type; filter on any Appointments field. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `groupBy` (string): Group by - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `crm_assign_owner` [proposal, scope `crm:write`]: Assign the owner of a customer. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `assignee` (string, required): Full name, email, staff code or "me" - `crm_contacts_activity` [read, scope `crm:read`]: Most recent interaction history of one customer. - `contact` (string, required): Customer phone, email or name - `limit` (integer): Max rows (≤ 50, default 10) - `crm_contacts_care` [read, scope `crm:read`]: Customers needing care: upcoming birthdays, long without contact, or leads never called. - `criteria` (string, required): birthday, inactive = no recent contact, uncontacted_lead = lead never called - `range` (string): today or week = next 7 days (for birthday) - `days` (integer): Days without activity (for inactive, default 90) - `crm_contacts_export` [export, scope `crm:export`]: Export customers or leads to Excel by filter or id list; returns an export proposal and confirmation link. - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `ids` (string[]): Record ids from a previous result - `crm_contacts_query` [read, scope `crm:read`]: Query customers, leads and contacts: count, list, group; filter on any Customers field. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `groupBy` (string): Group by - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `nhom` (string, required): Group as on screen: khach_hang (customers), lead… - `crm_contracts_search` [read, scope `crm:read`]: Look up CRM contracts by code, customer, status (drafts included); count or list. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `crm_create_appointment` [proposal, scope `crm:write`]: Create an appointment with a customer. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `title` (string, required): Title - `startTime` (string, required): Start (ISO-8601 with offset) - `endTime` (string): End (ISO-8601 with offset) - `appointmentType` (string): Appointment type - `location` (string): Location - `locationType` (string): Location type (in person, online…) - `assignee` (string): Full name, email, staff code or "me" - `crm_create_contract_from_quotation` [proposal, scope `crm:write`]: Create a draft contract from a sent or accepted quotation. Creates a proposal; it only runs after the user taps Confirm in the app. - `quotationCode` (string): Quotation code - `crm_create_lead` [proposal, scope `crm:write`]: Create a new lead. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string, required): Customer / lead name - `phone` (string): Customer phone - `email` (string): Customer email - `note` (string): Note text - `crm_create_opportunity` [proposal, scope `crm:write`]: Create a sales opportunity for a customer. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `name` (string, required): Customer / lead name - `estimatedValue` (string): Estimated value (VND) - `expectedCloseDate` (string): Expected close date (yyyy-MM-dd) - `pipeline` (string): Sales pipeline name - `stage` (string): Stage name - `assignee` (string): Full name, email, staff code or "me" - `crm_create_quotation` [proposal, scope `crm:write`]: Create a draft quotation for a customer, optionally from fill and print templates. Creates a proposal; it only runs after the user taps Confirm in the app. - `fillTemplate` (string): Quotation fill template name or id - `printTemplate` (string): PDF print template name or id - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `contactQuery` (string) - `title` (string): Title - `items` (object[]): Quotation line items - `discountType` (string): Discount type - `discountValue` (number): Discount value - `taxRate` (number): Tax rate (%) - `validUntil` (string): Valid until (yyyy-MM-dd) - `notes` (string): Notes - `modelDescription` (string): Opportunity description - `sections` (object[]): Sections to read - `paymentTerms` (string): Payment terms - `warrantyTerms` (string): Warranty terms - `crm_create_task` [proposal, scope `crm:write`]: Create a to-do task linked to a customer. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `title` (string, required): Title - `dueDate` (string): Due date (yyyy-MM-dd) - `priority` (string): Priority - `assignee` (string): Full name, email, staff code or "me" - `crm_move_opportunity_stage` [proposal, scope `crm:write`]: Move an open opportunity to another stage in the same pipeline. Creates a proposal; it only runs after the user taps Confirm in the app. - `opportunityCode` (string): Opportunity code (e.g. OPP00012) - `stage` (string, required): Stage name - `crm_opportunities_export` [export, scope `crm:export`]: Export opportunities to Excel by filter or id list; returns an export proposal and confirmation link. - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `ids` (string[]): Record ids from a previous result - `crm_opportunities_query` [read, scope `crm:read`]: Query opportunities and pipeline: count, list, group by stage, customer, owner. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `groupBy` (string): Group by - `sumFields` (string[]): Totals over the whole set, returned in totals - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `crm_products_search` [read, scope `crm:read`]: Look up products by SKU or name for quotations: price, unit, variants. - `q` (string, required): Quick accent-insensitive search - `crm_quotation_templates_list` [read, scope `crm:read`]: Quotation fill templates and PDF print templates. - `quotationCode` (string): Quotation code - `name` (string): Customer / lead name - `kind` (string): Kind (e.g. fill or print) - `requirements` (string): Customer requirements to pick a template - `crm_quotations_search` [read, scope `crm:read`]: Look up quotations by code, customer, status (drafts included); count or list. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `crm_remove_tag` [proposal, scope `crm:write`]: Remove a tag from a customer. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `tag` (string, required): Tag name from the catalog - `crm_reports_ads_export` [export, scope `crm:export`]: Export the CRM "Ads" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `kind` (string): Kind (e.g. fill or print) - `windowDays` (integer): Window in days - `key` (string): Stage key - `jobId` (string): Export job id to check status - `crm_reports_ads_query` [read, scope `crm:read`]: CRM "Ads" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `kind` (string): Kind (e.g. fill or print) - `windowDays` (integer): Window in days - `key` (string): Stage key - `crm_reports_analytics_query` [read, scope `crm:read`]: CRM "Analytics" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_call_outcome_export` [export, scope `crm:export`]: Export the CRM "Calls and outcomes" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `outboundOnly` (boolean): true = outbound calls only (telesales) - `windowDays` (integer): Window in days - `jobId` (string): Export job id to check status - `crm_reports_call_outcome_query` [read, scope `crm:read`]: CRM "Calls and outcomes" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `outboundOnly` (boolean): true = outbound calls only (telesales) - `windowDays` (integer): Window in days - `crm_reports_campaign_query` [read, scope `crm:read`]: CRM "Email campaigns" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_care_dashboard_query` [read, scope `crm:read`]: CRM "Care dashboard" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_care_tasks_export` [export, scope `crm:export`]: Export the CRM "Customer care" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_care_tasks_query` [read, scope `crm:read`]: CRM "Customer care" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_contact_query` [read, scope `crm:read`]: CRM "Contacts" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_contracts_export` [export, scope `crm:export`]: Export the CRM "Contracts" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_contracts_query` [read, scope `crm:read`]: CRM "Contracts" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_conversations_export` [export, scope `crm:export`]: Export the CRM "Conversations" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `kind` (string): Kind (e.g. fill or print) - `windowDays` (integer): Window in days - `key` (string): Stage key - `jobId` (string): Export job id to check status - `crm_reports_conversations_query` [read, scope `crm:read`]: CRM "Conversations" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `kind` (string): Kind (e.g. fill or print) - `windowDays` (integer): Window in days - `key` (string): Stage key - `crm_reports_customers_export` [export, scope `crm:export`]: Export the CRM "Customers" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `jobId` (string): Export job id to check status - `crm_reports_customers_query` [read, scope `crm:read`]: CRM "Customers" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `crm_reports_export` [export, scope `crm:export`]: Export the CRM "Revenue" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `kind` (string): Kind (e.g. fill or print) - `granularity` (string): Time granularity - `splitBySource` (boolean): true = split by source - `top` (integer): Top N rows - `jobId` (string): Export job id to check status - `crm_reports_forecast_query` [read, scope `crm:read`]: CRM "Forecast" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `rotDays` (integer): Opportunities idle over N days (default 30) - `crm_reports_journey_export` [export, scope `crm:export`]: Export the CRM "Customer journey" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_journey_query` [read, scope `crm:read`]: CRM "Customer journey" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_kpi_query` [read, scope `crm:read`]: CRM "KPI" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_lead_query` [read, scope `crm:read`]: CRM "Leads" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_lead_source_export` [export, scope `crm:export`]: Export the CRM "Lead sources" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_lead_source_query` [read, scope `crm:read`]: CRM "Lead sources" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_lead_speed_export` [export, scope `crm:export`]: Export the CRM "Lead response speed" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `jobId` (string): Export job id to check status - `crm_reports_lead_speed_query` [read, scope `crm:read`]: CRM "Lead response speed" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `crm_reports_multi_module_export` [export, scope `crm:export`]: Export the CRM "Multi-module customers" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_multi_module_query` [read, scope `crm:read`]: CRM "Multi-module customers" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_opportunity_query` [read, scope `crm:read`]: CRM "Opportunities" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `periodDays` (integer): Recent days - `crm_reports_pipeline_campaign_query` [read, scope `crm:read`]: CRM "Pipelines and campaigns" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `crm_reports_pipeline_export` [export, scope `crm:export`]: Export the CRM "Pipeline" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_pipeline_query` [read, scope `crm:read`]: CRM "Pipeline" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_query` [read, scope `crm:read`]: CRM "Revenue" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `kind` (string): Kind (e.g. fill or print) - `granularity` (string): Time granularity - `splitBySource` (boolean): true = split by source - `top` (integer): Top N rows - `crm_reports_quotations_export` [export, scope `crm:export`]: Export the CRM "Quotations" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_quotations_query` [read, scope `crm:read`]: CRM "Quotations" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_reconciliation_export` [export, scope `crm:export`]: Export the CRM "Reconciliation" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `metric` (string): Metric - `jobId` (string): Export job id to check status - `crm_reports_reconciliation_query` [read, scope `crm:read`]: CRM "Reconciliation" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `metric` (string): Metric - `crm_reports_retention_export` [export, scope `crm:export`]: Export the CRM "Repeat purchase and cooling customers" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_retention_query` [read, scope `crm:read`]: CRM "Repeat purchase and cooling customers" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_satisfaction_export` [export, scope `crm:export`]: Export the CRM "Satisfaction" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_satisfaction_query` [read, scope `crm:read`]: CRM "Satisfaction" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_support_export` [export, scope `crm:export`]: Export the CRM "Support" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `jobId` (string): Export job id to check status - `crm_reports_support_query` [read, scope `crm:read`]: CRM "Support" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `crm_reports_survey_query` [read, scope `crm:read`]: CRM "Surveys" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_team_activity_export` [export, scope `crm:export`]: Export the CRM "Team activity" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `jobId` (string): Export job id to check status - `crm_reports_team_activity_query` [read, scope `crm:read`]: CRM "Team activity" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `crm_reports_win_loss_export` [export, scope `crm:export`]: Export the CRM "Win / loss" report to Excel by period, comparison and branch, staff, source filters; returns an export proposal and confirmation link. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `jobId` (string): Export job id to check status - `crm_reports_win_loss_query` [read, scope `crm:read`]: CRM "Win / loss" report by period, with prior-period or year-over-year comparison, filtered by branch, staff, source. - `code` (string, required): Report code - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `compare` (string): Comparison: prev, yoy or none - `branchIds` (string[]): Filter by branches - `staffIds` (string[]): Filter by staff - `sources` (string[]): Filter by lead sources - `by` (string): Breakdown dimension (e.g. staff, campaign) - `crm_sales_process_alerts` [read, scope `crm:read`]: Sales process 'Needs attention' inbox: overdue calls, silent too long, overdue payments, unassigned. - `take` (integer): Max rows (≤ 50) - `crm_sales_process_case` [read, scope `crm:read`]: One customer's sales process case by opportunity code: stage, deadlines, alerts, payment requests. - `opportunityCode` (string, required): Opportunity code (e.g. OPP00012) - `crm_sales_process_case_action` [proposal, scope `crm:write`]: Perform an action on a sales process case (payment reminder, postpone decision…). Creates a proposal; it only runs after the user taps Confirm in the app. - `opportunityCode` (string, required): Opportunity code (e.g. OPP00012) - `actionKey` (string, required): Action key (e.g. remind_payment, delay_decision) - `input` (object): Extra input for the action (e.g. appointment date, call outcome) - `note` (string): Note text - `crm_sales_process_create` [proposal, scope `crm:write`]: Create a draft sales process from a template or blank. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string): Customer / lead name - `templateRef` (string): Template from crm_sales_process_templates - `blank` (boolean): true = create blank, no template - `team` (string): Sales team name - `baseVersion` (integer): Version you read - `ops` (object[]): Ordered list of changes (max 20) - `crm_sales_process_disable` [proposal, scope `crm:write`]: Pause a running sales process. Creates a proposal; it only runs after the user taps Confirm in the app. - `processRef` (string): Process ref (from crm_sales_process_list) - `keepReminders` (boolean): true = keep reminders for customers in progress - `crm_sales_process_enable` [proposal, scope `crm:write`]: Enable a sales process so the team starts receiving customers. Creates a proposal; it only runs after the user taps Confirm in the app. - `processRef` (string): Process ref (from crm_sales_process_list) - `crm_sales_process_get` [read, scope `crm:read`]: Details of a sales process: stages, transitions, conditions, deadlines and settings. - `processRef` (string): Process ref (from crm_sales_process_list) - `crm_sales_process_list` [read, scope `crm:read`]: The company's sales processes and their status. - `state` (string): State - `take` (integer): Max rows (≤ 50) - `crm_sales_process_patch` [proposal, scope `crm:write`]: Edit a sales process: add, change or remove stages, transitions, settings — in one call. Creates a proposal; it only runs after the user taps Confirm in the app. - `processRef` (string): Process ref (from crm_sales_process_list) - `baseVersion` (integer): Version you read - `ops` (object[]): Ordered list of changes (max 20) - `crm_sales_process_payments` [read, scope `crm:read`]: Pending payment requests in the sales process: case, amount, due date, overdue. - `take` (integer): Max rows (≤ 50) - `crm_sales_process_runs` [read, scope `crm:read`]: Reminder runs of a case: active sequences, skipped, waiting or failed steps. - `opportunityCode` (string, required): Opportunity code (e.g. OPP00012) - `crm_sales_process_simulate` [read, scope `crm:read`]: Dry-run a sales process with a sample customer; sends nothing, creates no tasks. - `processRef` (string): Process ref (from crm_sales_process_list) - `draft` (object): Unsaved changes to validate - `crm_sales_process_templates` [read, scope `crm:read`]: Available sales process templates. - `crm_sales_process_today` [read, scope `crm:read`]: Today's sales process work: who to call, cases due or overdue. - `scope` (string): mine or team - `take` (integer): Max rows (≤ 50) - `crm_sales_process_validate` [read, scope `crm:read`]: Validate a sales process: blocking issues, warnings, whether it can be enabled. Writes nothing. - `processRef` (string): Process ref (from crm_sales_process_list) - `draft` (object): Unsaved changes to validate - `crm_sales_process_workspace` [read, scope `crm:read`]: Readiness for sales processes: usable messaging channels, call center, staff count. - `crm_select_quotation_print_template` [proposal, scope `crm:write`]: Select or change the print template of a draft quotation. Creates a proposal; it only runs after the user taps Confirm in the app. - `quotationCode` (string): Quotation code - `printTemplate` (string, required): PDF print template name or id - `crm_send_quotation_email` [proposal, scope `crm:write`]: Email a draft quotation to the customer, with the PDF attached. Creates a proposal; the mail leaves only after the user taps Confirm in the app. - `quotationCode` (string, required): Quotation code - `recipientEmail` (string, required): Recipient email - `subject` (string): Mail subject - `body` (string): Mail text - `crm_set_lifecycle` [proposal, scope `crm:write`]: Move a customer or lead to a higher lifecycle stage. Creates a proposal; it only runs after the user taps Confirm in the app. - `contactCode` (string): Customer code shown in CRM (e.g. CT08027) - `stage` (string, required): Stage name - `crm_tasks_query` [read, scope `crm:read`]: Query tasks: count, list, group by status or assignee. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `groupBy` (string): Group by - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `crm_tickets_query` [read, scope `crm:read`]: Query support tickets: count, list, group by status or priority. - `op` (string, required): count, list (default) or group by groupBy - `filter` (object[]): Filters [{field, op, value}] on screen fields - `match` (string): all = every condition (default), any = any - `groupBy` (string): Group by - `sort` (string): Sort " asc|desc" - `q` (string): Quick accent-insensitive search - `limit` (integer): Max rows (≤ 50, default 10) - `page` (integer): Page, starting at 1 - `fields` (string[]): Fields to return - `ids` (string[]): Record ids from a previous result - `crm_workspace_summary` [read, scope `crm:read`]: Workspace-wide CRM totals: contacts, customers, leads, opportunities and conversion rate. - `period` (string): Period for conversion rate (default month) ### dms - `dms_catalog_products_search` [read, scope `dms:read`]: Distribution product catalog: code, name, unit, price; paginated. - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `dms_checkins_search` [read, scope `dms:read`]: Outlet visit check-ins by employee and date range, within the caller's visible scope. - `employeeId` (string): Employee id - `dateFrom` (string): From date (yyyy-MM-dd) - `dateTo` (string): To date (yyyy-MM-dd) - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `dms_daily_plans_get` [read, scope `dms:read`]: Details of one daily route plan: stops and the status of each stop. - `id` (string, required): Plan id (from dms_daily_plans_search) - `dms_daily_plans_search` [read, scope `dms:read`]: Daily route plans by date, employee and status, within the caller's visible scope. - `planDate` (string): Plan date (yyyy-MM-dd) - `employeeId` (string): Employee id - `status` (string): Plan status - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `dms_orders_search` [read, scope `dms:read`]: Distribution orders by outlet, status, date range or keyword, within the caller's visible scope. - `q` (string): Order code or customer name - `outletId` (string): Outlet id - `status` (string): Order status - `dateFrom` (string): From date (yyyy-MM-dd) - `dateTo` (string): To date (yyyy-MM-dd) - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `dms_outlets_search` [read, scope `dms:read`]: Search outlets by name, code or phone: address, channel, status, route and assigned employee. - `q` (string): Outlet name, code or phone - `status` (string): Outlet status - `routeId` (string): Route id (from dms_routes_search) - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `dms_routes_search` [read, scope `dms:read`]: List sales routes: name, code, run days, outlet count and employee; filter by status, employee, keyword. - `q` (string): Route name or code - `status` (string): Route status - `employeeId` (string): Employee id - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `dms_van_inventory_get` [read, scope `dms:read`]: Current on-van stock for the given SKUs across unclosed shifts: loaded, sold, returned, adjusted and remaining, with van, date and shift status. - `productSkus` (string[], required): List of SKUs - `dms_van_inventory_low_stock` [read, scope `dms:read`]: SKUs on vans (unclosed shifts) with stock at or below a threshold, lowest first. - `threshold` (integer, required): Stock threshold - `dms_van_load_history` [read, scope `dms:read`]: Van loading slip history by date range: slip code, created time, driver, status, line count and lines issued differently from the request; paginated with total. - `dateFrom` (string): From date (YYYY-MM-DD) - `dateTo` (string): To date (YYYY-MM-DD) - `status` (string): Slip status - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 ### einvoice - `einvoice_invoices_get` [read, scope `einvoice:read`]: Details of one e-invoice: buyer, line items, tax and issuance status. - `id` (string, required): Invoice id (from einvoice_invoices_search) - `einvoice_invoices_search` [read, scope `einvoice:read`]: Paginated e-invoice list, filtered by status (DRAFT, PENDING, ISSUED, ADJUSTED, CANCELLED, ERROR), date range, keyword and source. - `status` (string): Invoice status - `fromDate` (string): From date (yyyy-MM-dd) - `toDate` (string): To date (yyyy-MM-dd) - `keyword` (string): Invoice number or buyer name - `source` (string): Source: sales_order, gym_contract or manual - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `einvoice_reports_summary` [read, scope `einvoice:read`]: Invoice count and total value by status for a date range; all time when dates are omitted. - `fromDate` (string): From date (yyyy-MM-dd) - `toDate` (string): To date (yyyy-MM-dd) - `einvoice_series_list` [read, scope `einvoice:read`]: The company's invoice series, active and disabled, filtered by e-invoice provider. - `providerCode` (string): Provider: Misa, Vnpt, Viettel, Fpt, Bkav or WinInvoice - `einvoice_settings_list` [read, scope `einvoice:read`]: Connected e-invoice provider accounts: provider, test mode, auto-issue and seller info. Never returns keys or passwords. ### hrm - `hrm_attendance_devices_list` [read, scope `hrm:read`]: List attendance devices: name, serial, brand, protocol, IP, in/out role, status. Never returns device passwords. - `includeInactive` (boolean): true = include disabled devices - `hrm_clock_history_daily` [read, scope `hrm:read`]: Daily clock-in/out per employee over a date range (max 62 days), filtered by employee or department. - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `employeeId` (string): Employee id - `orgUnitId` (string): Department id - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `hrm_clock_history_timeline` [read, scope `hrm:read`]: All clock events of one employee over a date range (max 62 days), in time order. - `employeeId` (string, required): Employee id - `from` (string, required): From date (yyyy-MM-dd) - `to` (string, required): To date (yyyy-MM-dd) - `hrm_contracts_expiring` [read, scope `hrm:read`]: Labor contracts expiring within N days, within the user's visible scope. - `days` (integer): Days ahead, default 30, max 90 - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm_employee_credentials_list` [read, scope `hrm:read`]: Faces, fingerprints, cards and QR registered for one employee per device, with sync status. Never returns card numbers. - `employeeId` (string, required): Employee id - `hrm_employees_get` [read, scope `hrm:read`]: One employee profile: department, title, start date, probation end. Never returns ID documents, bank accounts or address. - `employeeId` (string, required): Employee id - `hrm_employees_search` [read, scope `hrm:read`]: Search employees by name or code: department, title, probation end. Never returns phone, email or ID documents. - `search` (string): Employee name or code - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm_inbox_list` [read, scope `hrm:read`]: Requests waiting for the user's own approval (leave, corrections, overtime…). - `status` (string): Status, default PENDING - `kind` (string): Request kind - `search` (string): Keyword - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm_insurance_summary` [read, scope `hrm:read`]: Monthly social insurance summary, within the user's access. - `year` (integer, required): Year - `month` (integer, required): Month (1–12) - `hrm_me_clock_today` [read, scope `hrm:read`]: The user's own shift and clock events today. - `hrm_me_contracts` [read, scope `hrm:read`]: The user's own labor contracts, including end date if any. - `hrm_me_payslips` [read, scope `hrm:read`]: The user's own finalized payslips; with payslipId returns one payslip in detail. - `year` (integer): Year - `payslipId` (string): Payslip id for details - `hrm_me_requests` [read, scope `hrm:read`]: The user's own leave, correction and overtime requests by status. - `status` (string): pending (default), approved, rejected or cancelled - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm_me_summary` [read, scope `hrm:read`]: The user's own overview: remaining annual leave, pending requests, monthly attendance. - `hrm_onboarding_list` [read, scope `hrm:read`]: Onboarding checklists within the user's visible scope. - `employeeId` (string): Employee id - `status` (string): Status - `hrm_org_units` [read, scope `hrm:read`]: Departments visible to the user: name, headcount, manager. - `search` (string): Department name - `hrm_performance_meetings` [read, scope `hrm:read`]: The user's upcoming 1-on-1 meetings. - `hrm_raw_punches_search` [read, scope `hrm:read`]: Raw device punches, filtered by employee, processing status, type (FACE, FINGERPRINT, CARD, QR), device serial and date range. - `employeeId` (string): Employee id - `status` (string): PENDING, PROCESSED, UNMATCHED, DUPLICATE or FAILED - `credentialType` (string): FACE, FINGERPRINT, CARD or QR - `deviceSerial` (string): Device serial - `search` (string): Keyword - `from` (string): From date (yyyy-MM-dd) - `to` (string): To date (yyyy-MM-dd) - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `hrm_recruitment_list` [read, scope `hrm:read`]: Candidates visible to the user: name, source, notes. Never returns phone numbers. - `search` (string): Candidate name - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm_report_attendance` [read, scope `hrm:read`]: Monthly attendance sheet by symbol, within the user's visible scope. - `year` (integer, required): Year - `month` (integer, required): Month (1–12) - `orgUnitId` (string): Department id - `hrm_report_overtime` [read, scope `hrm:read`]: Monthly overtime summary, within the user's visible scope. - `year` (integer, required): Year - `month` (integer, required): Month (1–12) - `orgUnitId` (string): Department id - `hrm_training_courses` [read, scope `hrm:read`]: List open training courses. - `search` (string): Course name - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm_training_learner` [read, scope `hrm:read`]: Courses one employee is enrolled in. - `employeeId` (string, required): Employee id (from hrm_employees_search) - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page - `hrm.correction.submit` [proposal, scope `hrm:write`]: Submit a clock-in/out correction request for the user's own day. Creates a proposal; it only runs after the user taps Confirm in the app. - `date` (string, required): Date (yyyy-MM-dd) - `clockIn` (string): Correct clock-in (ISO) - `clockOut` (string): Correct clock-out (ISO) - `reason` (string, required): Reason - `hrm.inbox.approve` [proposal, scope `hrm:write`]: Approve a request waiting in the user's own approval inbox. Creates a proposal; it only runs after the user taps Confirm in the app. - `itemId` (string, required): Request id (from hrm_inbox_list) - `kind` (string, required): Request kind (from hrm_inbox_list) - `comment` (string): Comment - `hrm.inbox.reject` [proposal, scope `hrm:write`]: Reject a request in the user's own approval inbox; a reason is required. Creates a proposal; it only runs after the user taps Confirm in the app. - `itemId` (string, required): Request id - `kind` (string, required): Request kind - `reason` (string, required): Rejection reason - `hrm.leave.submit` [proposal, scope `hrm:write`]: Submit the user's own leave request into the HR approval flow. Creates a proposal; it only runs after the user taps Confirm in the app. - `fromDate` (string, required): From date (yyyy-MM-dd) - `toDate` (string, required): To date (yyyy-MM-dd) - `reason` (string, required): Reason - `leaveType` (string): FULL_DAY or HALF_DAY; empty = full day - `hrm.onboarding.tick` [proposal, scope `hrm:write`]: Mark an onboarding checklist item as done or pending. Creates a proposal; it only runs after the user taps Confirm in the app. - `checklistId` (string, required): Checklist id - `taskId` (string, required): Item id - `status` (string, required): done or pending - `notes` (string): Notes - `hrm.overtime.submit` [proposal, scope `hrm:write`]: Submit the user's own overtime request. Creates a proposal; it only runs after the user taps Confirm in the app. - `workDate` (string, required): Work date (yyyy-MM-dd) - `startTime` (string, required): Start (HH:mm) - `endTime` (string, required): End (HH:mm) - `reason` (string, required): Reason - `breakMinutes` (integer): Break minutes - `hrm.training.complete` [proposal, scope `hrm:write`]: Record one learner as having completed a training course. Creates a proposal; it only runs after the user taps Confirm in the app. - `enrollmentId` (string, required): Enrollment id - `note` (string): Note ### marketing - `marketing_activate_workflow` [proposal, scope `marketing:write`]: Activate a marketing automation workflow so it starts running and messaging customers; same checks as the Activate button. Creates a proposal; it only runs after the user taps Confirm in the app. - `workflowName` (string): Workflow name (empty if the workflow is open on screen) - `marketing_automation_catalog` [read, scope `marketing:read`]: Building blocks for marketing automation workflows: trigger types, action types (ZNS, email, tagging…) with config fields, and wait/branch steps. - `marketing_check_graph` [read, scope `marketing:read`]: Validate an unsaved marketing workflow graph with the same checks as the Activate button: orphan steps, loops, missing config, unready channels. Writes nothing. - `graph` (object): Compact workflow graph - `marketing_create_web_form` [proposal, scope `marketing:write`]: Create a lead-capture web form (embeddable on a website) from a description: name, type, fields, theme, post-submit action. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string, required): Form name - `formType` (string): LeadCapture (default), Survey, Registration… - `fields` (object[], required): Fields in display order - `theme` (object): Theme - `submitAction` (object): Post-submit action - `publish` (boolean): true = publish immediately - `marketing_create_workflow_from_graph` [proposal, scope `marketing:write`]: Create a new marketing automation workflow (ZNS/email, waits, branches…) from a compact graph. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string, required): Workflow name - `goalType` (string): Workflow goal, default Lead - `graph` (object): Compact workflow graph - `marketing_delete_landing` [proposal, scope `marketing:write`]: Delete a landing page. Creates a proposal; it only runs after the user taps Confirm in the app. - `pageId` (string, required): Id of the page to delete - `marketing_email_campaigns_get` [read, scope `marketing:read`]: Details of one email campaign. - `id` (string, required): Campaign id (from marketing_email_campaigns_search) - `marketing_email_campaigns_search` [read, scope `marketing:read`]: List email campaigns: subject, status, sent, opened, clicked; filter by status, keyword and recent days; paginated. - `status` (string): Campaign status - `q` (string): Keyword - `days` (integer): Recent days - `page` (integer): Page, starting at 1 - `size` (integer): Rows per page, max 50 - `marketing_email_templates_search` [read, scope `marketing:read`]: List email templates filtered by category and keyword; paginated. - `category` (string): Template category - `q` (string): Keyword - `page` (integer): Page, starting at 1 - `size` (integer): Rows per page, max 50 - `marketing_get_workflow_stats` [read, scope `marketing:read`]: Run metrics of one workflow over the last N days versus the previous N days: entries, in-flow, messages sent, skipped, failed, conversions, revenue. - `workflowName` (string): Workflow name (empty if open on screen) - `days` (integer): Recent days, default 30 - `marketing_integrations_list` [read, scope `marketing:read`]: Connected Google integrations: type, status, account, token expiry. Never returns tokens. - `marketing_list_landing_pages` [read, scope `marketing:read`]: List the workspace's landing pages: name, path, and whether each is a draft or published. Takes no parameters and writes nothing. - `marketing_list_web_forms` [read, scope `marketing:read`]: List lead-capture web forms: name, status, field count, views, submissions and fields. - `search` (string): Part of the form name - `marketing_list_workflows` [read, scope `marketing:read`]: List marketing automation workflows: name, status (draft, active, paused), trigger type, step count. - `search` (string): Part of the workflow name - `status` (string): Draft, Active or Paused - `includeGraph` (boolean): true = include the graph when exactly one result - `marketing_pause_workflow` [proposal, scope `marketing:write`]: Pause a running workflow: stop new entries and stop sending. Creates a proposal; it only runs after the user taps Confirm in the app. - `workflowName` (string): Workflow name (empty if the workflow is open on screen) - `marketing_publish_landing` [proposal, scope `marketing:write`]: Publish a draft landing page so outside visitors can open it by link. Creates a proposal; it only runs after the user taps Confirm in the app. - `pageId` (string, required): Id of the page to publish - `marketing_reports_overview` [read, scope `marketing:read`]: Marketing performance overview (sent, opened, clicked, conversions by channel) for a date range. - `from` (string): From date (yyyy-MM-dd) - `to` (string): To date (yyyy-MM-dd) - `marketing_save_landing_draft` [proposal, scope `marketing:write`]: Save a landing page draft (hero, text, pricing and form blocks) without publishing. Creates a proposal; it only runs after the user taps Confirm in the app. - `pageId` (string): Page id (empty to create a new page) - `name` (string, required): Page name - `slug` (string): Page path - `title` (string, required): Title visitors see - `blocksJson` (string, required): The page's blocks as a JSON array - `marketing_sender_profiles_list` [read, scope `marketing:read`]: List email sender profiles: name, address and verification status. - `marketing_unpublish_landing` [proposal, scope `marketing:write`]: Unpublish a landing page so its link no longer shows content. Creates a proposal; it only runs after the user taps Confirm in the app. - `pageId` (string, required): Id of the page to unpublish - `marketing_update_web_form` [proposal, scope `marketing:write`]: Edit a web form: add, remove or update fields, rename, theme, thank-you message — all changes in one call. Creates a proposal; it only runs after the user taps Confirm in the app. - `formName` (string, required): Form to edit - `name` (string): New name (if renaming) - `addFields` (object[]): Fields to add - `removeFields` (string[]): Fields to remove - `updateFields` (object[]): Fields to update - `theme` (object): Theme - `submitAction` (object): Post-submit action - `marketing_update_workflow_graph` [proposal, scope `marketing:write`]: Edit an existing workflow by sending the full updated graph plus the version you read; running workflows must be paused first. Creates a proposal; it only runs after the user taps Confirm in the app. - `workflowName` (string): Workflow name (empty if open on screen) - `baseVersion` (integer): Graph version you read - `graph` (object): Updated compact graph ### office - `get_my_recent_mail` [read, scope `office:read`]: Recent emails in the user's own mailbox: sender, subject, read status. - `limit` (integer): Number of emails, default 10, max 30 - `office_activate_automation` [proposal, scope `office:write`]: Activate an Office automation rule so it runs on events; same checks as the Activate button. Creates a proposal; it only runs after the user taps Confirm in the app. - `automationName` (string): Rule name (empty if the rule is open on screen) - `office_add_checklist_item` [proposal, scope `office:write`]: Add one checklist item to a task. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string): Task id - `title` (string): Task title when no taskId - `itemTitle` (string, required): Checklist item text - `office_add_task_comment` [proposal, scope `office:write`]: Add a comment to an Office task. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string): Task id (from office_list_tasks) - `title` (string): Exact task title when no taskId - `content` (string): Comment text - `office_approve_approval_task` [proposal, scope `office:write`]: Approve a pending approval step assigned to the user. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string, required): Approval step id (from office_get_approval_instance) - `comment` (string): Approval comment - `office_approve_task` [proposal, scope `office:write`]: Approve an Office task awaiting approval and mark it Done. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string): Task id (from office_list_tasks) - `title` (string): Exact task title when no taskId - `office_automation_catalog` [read, scope `office:read`]: Building blocks for Office automation rules: trigger types and action types (assign task, internal email, update record…) with config fields. - `office_cancel_event` [proposal, scope `office:write`]: Cancel a meeting organized by the signed-in person. Creates a proposal; it only runs after the user taps Confirm in the app. - `eventId` (string, required): Meeting to cancel - `office_check_graph` [read, scope `office:read`]: Validate an unsaved Office rule graph like the Activate button: steps, trigger, source module. Writes nothing. - `graph` (object): Compact rule graph - `office_create_approval_instance` [proposal, scope `office:write`]: Submit a new approval request for a workflow, with its form content. Creates a proposal; it only runs after the user taps Confirm in the app. - `definitionCode` (string, required): Approval workflow code - `formValue` (object): Form content: field code → value - `office_create_automation_from_graph` [proposal, scope `office:write`]: Create a new Office automation rule (on an event: assign tasks, send internal email, update records…) from a compact graph. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string, required): Rule name - `graph` (object): Compact rule graph - `office_create_event` [proposal, scope `office:write`]: Create a meeting on the user's calendar with attendees, location and notes. Creates a proposal; it only runs after the user taps Confirm in the app. - `title` (string, required): Meeting title - `startAt` (string, required): Start: yyyy-MM-dd (all day), yyyy-MM-ddTHH:mm Vietnam time or ISO with offset - `endAt` (string): End, same format; empty = 1 hour - `attendeeNames` (string): Attendee full names in the company, comma-separated - `location` (string): Location - `office_create_record` [proposal, scope `office:write`]: Add a row to an Office data table. Creates a proposal; it only runs after the user taps Confirm in the app. - `tableId` (string, required): Table id - `data` (object, required): Values by column code - `office_create_task` [proposal, scope `office:write`]: Create an Office task: title, assignee, due date, priority, project. Creates a proposal; it only runs after the user taps Confirm in the app. - `title` (string, required): Task title - `assigneeName` (string): Assignee full name in the company - `dueAt` (string): Due: yyyy-MM-dd (17:00 Vietnam time) or ISO with offset - `priority` (string): Low, Medium or High (Vietnamese labels) - `listName` (string): Project name; empty = none - `office_create_task_from_chat` [proposal, scope `office:write`]: Create one task for one topic in an Office group chat thread (problem, cause, fix request) and post the task card to the group. Creates a proposal; it only runs after the user taps Confirm in the app. - `messageId` (string, required): A source message id in the thread (from office_read_group_chat) - `problem` (string, required): Problem - `cause` (string, required): Cause - `fixRequest` (string, required): Fix request; also the task title - `assigneeName` (string): Assignee - `dueAt` (string): Due date (yyyy-MM-dd) - `office_create_task_list` [proposal, scope `office:write`]: Create a task list, which is also a project on the Tasks screen. Creates a proposal; it only runs after the user taps Confirm in the app. - `name` (string, required): List name - `office_delete_record` [proposal, scope `office:write`]: Move a row of an Office data table to the trash. Creates a proposal; it only runs after the user taps Confirm in the app. - `tableId` (string, required): Table id - `recordId` (string, required): Row id (from office_list_records) - `office_delete_task` [proposal, scope `office:write`]: Move an Office task (with subtasks) to the trash, kept 30 days. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string): Task id (from office_list_tasks) - `title` (string): Exact task title when no taskId - `office_get_approval_instance` [read, scope `office:read`]: Details of one approval request: content, approval steps and timeline. - `instanceId` (string, required): Request id (from office_list_approval_instances) - `office_get_record` [read, scope `office:read`]: Read one row of an Office data table; rows outside the user's access return not found. - `tableId` (string, required): Table id - `recordId` (string, required): Row id (from office_list_records) - `office_list_approval_instances` [read, scope `office:read`]: The user's approval requests: submitted, awaiting their approval, or already acted on. - `role` (string): mine = submitted by me (default), todo = awaiting me, acted = acted on - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, 1–100, default 20 - `office_list_automations` [read, scope `office:read`]: List Office automation rules: name, status (draft, active, paused), trigger type, step count. - `search` (string): Part of the name - `status` (string): Draft, Active or Paused - `includeGraph` (boolean): true = include graph when exactly one result - `office_list_my_calendar` [read, scope `office:read`]: Meetings of the signed-in person between two dates. Empty means the next 7 days, at most 31 days. Does not return attendees or email. - `from` (string): From date (yyyy-MM-dd) - `to` (string): To date (yyyy-MM-dd) - `office_list_records` [read, scope `office:read`]: List rows of one Office data table; only rows and columns visible to the user. - `tableId` (string, required): Table id - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, 1–100, default 20 - `office_list_stuck_tasks` [read, scope `office:read`]: The user's stuck tasks — overdue, awaiting approval, unassigned — with the reason for each. - `office_list_tasks` [read, scope `office:read`]: List Office tasks: by default the user's open tasks; filter by overdue, assignee, scope, status, title, priority, unassigned. - `overdue` (boolean): true = overdue only - `assigneeName` (string): Assignee full name - `scope` (string): assigned-to-me, created-by-me, watching… - `status` (string): Status; empty = open - `search` (string): Part of the title - `priority` (string): Low, Medium or High (Vietnamese labels) - `unassigned` (boolean): true = unassigned only - `office_pause_automation` [proposal, scope `office:write`]: Pause an active Office automation rule. Creates a proposal; it only runs after the user taps Confirm in the app. - `automationName` (string): Rule name (empty if the rule is open on screen) - `office_read_group_chat` [read, scope `office:read`]: Read up to 30 recent messages of one Office group chat. - `channelName` (string): Group chat name - `channelId` (string): Group id when exactly one match - `take` (integer): Messages, 1–30, default 20 - `fromMessageId` (string): First message of the selected range - `toMessageId` (string): Last message of the selected range - `office_reject_approval_task` [proposal, scope `office:write`]: Reject a pending approval step assigned to the user, with a reason. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string, required): Approval step id (from office_get_approval_instance) - `comment` (string): Rejection reason - `office_restore_task` [proposal, scope `office:write`]: Restore a task from the trash within 30 days. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string, required): Id of the trashed task - `office_return_task` [proposal, scope `office:write`]: Return a task with a reason the user stated. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string): Task id - `title` (string): Task title when no taskId - `reason` (string, required): Reason for returning the task - `office_simulate_automation` [read, scope `office:read`]: Dry-run a saved Office automation rule on sample event data without writing anything: returns each step run or skipped and the end reason. - `automationName` (string): Rule name (empty if the rule is open on screen) - `triggerData` (string): Sample event data (JSON) - `office_transfer_approval_task` [proposal, scope `office:write`]: Transfer a pending approval step to another person in the company. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string, required): Approval step id (from office_get_approval_instance) - `receiverName` (string, required): Receiver full name - `comment` (string): Note - `office_update_automation_graph` [proposal, scope `office:write`]: Edit an Office rule by sending the full updated graph plus the version you read; active rules must be paused first. Creates a proposal; it only runs after the user taps Confirm in the app. - `automationName` (string): Rule name (empty if the rule is open on screen) - `baseVersion` (integer): Graph version you read - `graph` (object): Updated compact graph - `office_update_event` [proposal, scope `office:write`]: Edit a meeting organized by the signed-in person. Send only the fields to change. Creates a proposal; it only runs after the user taps Confirm in the app. - `eventId` (string, required): Meeting to edit - `title` (string): New title - `startAt` (string): New start - `endAt` (string): New end - `office_update_record` [proposal, scope `office:write`]: Update a row of an Office data table: only changed columns, or overwrite the whole row. Creates a proposal; it only runs after the user taps Confirm in the app. - `tableId` (string, required): Table id - `recordId` (string, required): Row id - `data` (object, required): Values by column code - `replace` (boolean): true = overwrite the whole row - `office_update_task` [proposal, scope `office:write`]: Update an Office task: status, assignee, due date, priority, title, project. Creates a proposal; it only runs after the user taps Confirm in the app. - `taskId` (string): Task id (from office_list_tasks) - `title` (string): Exact task title when no taskId - `status` (string): To do, In progress, Done, Awaiting approval or Cancelled (Vietnamese labels) - `assigneeName` (string): New assignee full name - `dueAt` (string): New due date (yyyy-MM-dd or ISO) - `priority` (string): Low, Medium or High (Vietnamese labels) - `newTitle` (string): New title - `listName` (string): Project name ### payment - `payment_intents_get` [read, scope `payment:read`]: Details of one payment request: amount, payment channel, status and reference document. - `id` (string, required): Payment request id - `payment_refunds_search` [read, scope `payment:read`]: List refunds filtered by status, date range and keyword; paginated. - `status` (string): Refund status - `from` (string): From date (yyyy-MM-dd) - `to` (string): To date (yyyy-MM-dd) - `search` (string): Keyword - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `payment_reports_overview` [read, scope `payment:read`]: Payment overview for a date range: transaction count and amount by channel and by status. Defaults to the last month. - `from` (string): From date (yyyy-MM-dd) - `to` (string): To date (yyyy-MM-dd) - `payment_subscriptions_search` [read, scope `payment:read`]: List recurring payment subscriptions filtered by status, document type and channel; paginated. - `status` (string): Subscription status - `referenceType` (string): Source document type - `providerCode` (string): Payment channel code - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `payment_transactions_get` [read, scope `payment:read`]: Details of one payment transaction. - `id` (string, required): Transaction id (from payment_transactions_search) - `payment_transactions_search` [read, scope `payment:read`]: List payment transactions filtered by channel, document type, date range and keyword; paginated. - `providerCode` (string): Payment channel code (e.g. VIETQR, VNPAY) - `referenceType` (string): Source document type (e.g. sales order, contract) - `fromDate` (string): From date (yyyy-MM-dd) - `toDate` (string): To date (yyyy-MM-dd) - `search` (string): Keyword - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 ### sales - `sales_customers_search` [read, scope `sales:read`]: Search buyers by name, customer code or phone, with order count, revenue (net of returns), outstanding debt, last purchase and owner. - `q` (string): Name, customer code or phone - `status` (string): Customer status - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `sales_orders_get` [read, scope `sales:read`]: Summary of orders by id list: code, type, status, customer, total, paid, outstanding, order date. - `orderIds` (string[], required): Order ids (max 100) - `sales_orders_search` [read, scope `sales:read`]: Search orders by code, customer name or product name, filtered by order type, status, date range and unpaid orders; returns the total match count and one page. - `q` (string): Order code, customer name or product name - `status` (string): Order status, comma-separated for several - `orderType` (string): Order type, e.g. SALES_ORDER, PRE_ORDER - `dateFrom` (string): Order date from (YYYY-MM-DD) - `dateTo` (string): Order date to (YYYY-MM-DD) - `hasDebt` (boolean): true = unpaid orders only - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `sales_products_search` [read, scope `sales:read`]: Search products by name, SKU or barcode, filtered by status and stock range; each row has price, current stock and minimum stock level. - `q` (string): Name, SKU or barcode - `status` (string): ACTIVE or INACTIVE - `stockFrom` (number): Stock from (>=) - `stockTo` (number): Stock to (<=); 0 for out-of-stock items - `page` (integer): Page, starting at 1 - `pageSize` (integer): Rows per page, max 50 - `sales_products_stock` [read, scope `sales:read`]: Stock of one product broken down by branch. - `productId` (string, required): Product id (from sales_products_search) ## Webhook events - `contact.identified` (COMM, plan PRO): A customer just sent a phone number in chat, with the conversation source (ad / UTM) and the assigned staff member - `conversation.attribution_resolved` (COMM, plan PRO): The conversation's ad tree (ad set, campaign) was just fetched from Meta, usually a few minutes after the event above; same conversationId — an overwrite, not a new record - `contact.created` (CRM, plan PRO): A new contact was created in the CRM — manually, by file import, or automatically from chat / web forms - `contact.deleted` (CRM, plan PRO): A contact was deleted from the CRM - `contact.updated` (CRM, plan PRO): A contact was edited; the payload is the state AFTER the edit, not a diff - `deal.won` (CRM, plan PRO): An opportunity moved to won (does not fire for lost or cancelled opportunities) - `invoice.cancelled` (EINVOICE, plan PRO): An e-invoice was cancelled — on NextX or detected as cancelled at the provider during sync. Payload includes the cancellation reason. - `invoice.failed` (EINVOICE, plan PRO): Issuing an e-invoice failed. Payload includes the source document and the error message returned by the e-invoice provider. - `invoice.issued` (EINVOICE, plan PRO): An e-invoice was issued successfully. Payload includes the source document (referenceType / referenceId / referenceCode), invoice number, tax authority code (if any) and issue time. - `employee.created` (HRM, plan PRO): A new employee was created in HRM. Payload includes code, full name, employee type, start date, department, job title and the first contract type. - `employee.terminated` (HRM, plan PRO): An employee was terminated. Payload includes code, full name, last working date and decision number; the reason is not included. - `employee.updated` (HRM, plan PRO): An employee profile was edited. The payload is the state AFTER the edit (code, full name, email, department, job title). - `labor_contract.evaluated` (HRM, plan PRO): A labor contract was evaluated. Payload includes contract type, decision, total / average score and the next contract if any. - `leave.approved` (HRM, plan PRO): A leave request was approved at the final step. Payload includes employee, leave type, code and date range; approval notes are not included. - `leave.rejected` (HRM, plan PRO): A leave request was rejected. Payload includes employee, leave type and date range; the rejection reason is not included. - `payroll.locked` (HRM, plan PRO): A monthly payroll was locked. Payload includes year, month, lock time and who locked it; no amounts. - `payslip.acknowledged` (HRM, plan PRO): An employee signed to acknowledge a payslip. Payload includes payslip, employee, month / year and signing time. - `recruitment.hired` (HRM, plan PRO): A candidate was hired. Payload includes application, candidate, job posting, hire date and the created employee (if any). - `branch.created` (IAM, plan PRO): A new branch was created - `branch.updated` (IAM, plan PRO): A branch was edited - `user.created` (IAM, plan PRO): A new user was added to the workspace - `workspace.created` (IAM, plan PRO): A new workspace was created - `approval.instance.status_changed` (OFFICE, plan PRO): An approval request changed status (pending / approved / rejected / withdrawn) - `approval.task.completed` (OFFICE, plan PRO): An approver finished their approval step - `approval.task.created` (OFFICE, plan PRO): An approval step was assigned to an approver - `payment.completed` (PAYMENT, plan PRO): A buyer paid successfully through an online gateway (QR, card, wallet, pay-later…) or a manual collection was confirmed. Payload includes transaction code, source document (referenceType / referenceId — sales order, gym contract…), gateway, amount and paid time. - `payment.failed` (PAYMENT, plan PRO): An online payment attempt failed (gateway declined, buyer cancelled, expired). Payload includes source document, gateway and the reason returned by the gateway. - `payment.recurring_charged` (PAYMENT, plan PRO): The gateway successfully charged one period of a recurring payment agreement. Payload has the agreement number and period number (periodNum) — the gateway may report the same period more than once, so deduplicate on this pair. - `payment.recurring_failed` (PAYMENT, plan PRO): The gateway tried to charge one recurring period but failed. Payload includes agreement number, period number, the charge order code and the reason. - `payment.refunded` (PAYMENT, plan PRO): A refund was completed. Payload includes refund code, original transaction, source document, amount and refund method. - `order.cancelled` (SALES, plan PRO): An order was cancelled - `order.completed` (SALES, plan PRO): An order was completed — delivered and fully paid - `order.status_changed` (SALES, plan PRO): An order changed status; fires on EVERY change, including to completed or cancelled