Documentation
Tasks
tasks.update
REST
ShippingPOST /api/v1/tasks/updateMCP tool
Livetasks.updateExposed on: REST API · Shop MCP server · Claude connector · Dash (in-app copilot) · Zapier. Part of the Tasks domain.
Operating contract
ONE CHANGE PER CALL, selected by which parameter you provide: title, notes, priority, complete, reopen, cancel, staff_id (hand it over), unassign, due_at, remove_due_date, link_conversation or unlink_conversation. To make several changes, call this once per change. Supplying none is refused, and so is supplying two — a call that both completed a task and reassigned it would be one audit row covering two decisions, and nobody could tell afterwards which one was intended.
COMPLETE, REOPEN AND CANCEL ARE THREE DIFFERENT OUTCOMES. complete means it was done. cancel means it will not be, and the row stays so 'we were going to and decided not to' is still visible weeks later. reopen puts it back to open and CLEARS the completion stamp, so a task completed by mistake and finished properly later reports the real finish time rather than the first one's.
NOTHING HERE DELETES A TASK, and no capability anywhere in this product does. A task is a record of something a shop said it would do; cancel is the honest version of removing it.
remove_due_date and due_at are separate parameters on purpose rather than one nullable field — clearing a deadline is a decision and it should look like one in the call.
REASSIGNING PINGS THE NEW OWNER. staff_id must be somebody on tasks.assignees; anyone else is refused. Handing a task to whoever already holds it is a no-op with no second notification.
link_conversation re-files the task under a different thread and unlink_conversation detaches it entirely. Use the first when a to-do was created against the wrong thread, and the second only when it genuinely belongs to no conversation — a task with no anchor is the kind nobody can act on.
Who may call it
- Permission
inbox.accessThe caller must hold Inbox at the ACT level. A read-only dashboard grant on the same section is refused.- Plan
- Every planNo plan gate. Available on every Service VIN plan.
- Retries
naturalNaturally idempotent — running it twice leaves the same world as running it once. A retrying integration needs no key.- Rate class
writeCounted against the write budget, which is tighter than a read.
Input
| Field | Type | Description |
|---|---|---|
| task_idrequired | stringuuid | The task to change, as returned by tasks.list. |
| title | stringmax 200 chars, min 1 chars | Rewrite the one-line title. One change per call. |
| notes | stringmax 4000 chars | Replace the notes. Send an empty string to clear them. One change per call. |
| priority | string | Set how urgent it is. One change per call. One of:low, normal, high |
| complete | boolean | True to mark the task done. One change per call. |
| reopen | boolean | True to put a done or cancelled task back to open. One change per call. |
| cancel | boolean | True to cancel it — it will not be done, and the row stays. One change per call. |
| staff_id | stringuuid | Hand it to this teammate, as returned by tasks.assignees. One change per call. |
| unassign | boolean | True to take it off whoever holds it. One change per call. |
| due_at | stringmax 40 chars | ISO instant it is due, resolved against the shop's timezone. One change per call. |
| remove_due_date | boolean | True to clear the due date entirely. One change per call. |
| link_conversation | stringuuid | Re-file it under this thread, as returned by comms.list_conversations. One change per call. |
| unlink_conversation | boolean | True to detach it from its thread. One change per call. |
Output
| Field | Type | Description |
|---|---|---|
| id | string | — |
| title | string | — |
| notes | string | null | — |
| status | string | — |
| priority | string | — |
| due_at | string | null | — |
| overdue | boolean | — |
| completed_at | string | null | — |
| created_at | string | — |
| conversation | string | null | — |
| conversation_label | string | null | — |
| customer_id | string | null | — |
| job_id | string | null | — |
| message_id | string | null | — |
| assigned_to | string | null | — |
| assignee_name | string | null | — |
Examples
Built from this capability's own schema — required fields and the ones carrying a default, and nothing invented. Paste one and it validates.
export SERVICEVIN_API_KEY=svk_live_…
curl -X POST https://www.servicevin.com/api/v1/tasks/update \
-H "Authorization: Bearer $SERVICEVIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id":"9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"}'const res = await fetch("https://www.servicevin.com/api/v1/tasks/update", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SERVICEVIN_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"task_id": "9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"
}),
});
// Success and failure are both envelopes. Switch on error.code, never
// on error.message — the codes are stable, the messages are for people.
const payload = await res.json();
if (!res.ok) throw new Error(payload.error.code);
const data = payload.data;import os, requests
res = requests.post(
"https://www.servicevin.com/api/v1/tasks/update",
headers={"Authorization": f"Bearer {os.environ['SERVICEVIN_API_KEY']}"},
json={
"task_id": "9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"
},
timeout=30,
)
payload = res.json()
if not res.ok:
raise RuntimeError(payload["error"]["code"])
data = payload["data"]{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks.update",
"arguments": {
"task_id": "9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"
}
}
}Refusals
The four gates run in this order on every surface, and the order is not arbitrary — see Authentication.
| Status | Code | When |
|---|---|---|
| 404 | not_found | The id is unknown, or the feature is not enabled for this account. Deliberately the same answer for both. |
| 403 | forbidden | This login does not hold inbox.access. |
| 403 | insufficient_scope | The credential is read-only and this capability writes. |
| 422 | validation_error | An argument was wrong. The message names the field. |
| 429 | rate_limited | Too many write calls. Back off and retry. |
| 500 | internal_error | Something failed on our side. Nothing was changed. |