Update project
well_update_projectChange a project of the current workspace: its name, kind, status, dates, amount and currency, the project it nests under, for a project how its work is priced (billing_method), for a campaign its channel (google_ads, linkedin_ads, reddit_ads, chatgpt_ads, meta_ads, tiktok_ads, pinterest_ads), objective (awareness, traffic, engagement, leads, sales), included and excluded audiences, for a flow its trigger audience, for a pipeline its paid stage, for a pipeline stage its win chance (probability), and for a deal its stage, owner, counterparty, win probability and position.
Use this tool when the user asks to rename a project, move it to another status (for example mark a deal won or lost), move a deal to another stage, change its dates, amount, owner, counterparty or chance, set how a project is billed, set a stage's win chance, name the stage of a pipeline that means paid, or nest it under another project. Find the project_id first with a one-row well_query_records lookup.
REQUIRED: project_id. OPTIONAL (only the fields the user wants changed): hidden, name, kind, status, start_date, end_date (YYYY-MM-DD), amount (a decimal string; the resulting project needs a currency), currency, parent_project_id, stage_project_id, owner_person_id, counterparty_company_id, counterparty_person_id, probability (a percentage from 0 through 100, at most two decimals; on a deal its own chance, on a pipeline stage the chance its open deals count at), position (a whole number from 0), billing_method (a project only: project_rate, service_rate, person_rate, fixed_fee, non_billable), channel and objective (a campaign only), included_audience_project_id and excluded_audience_project_id (a campaign or an ad set), trigger_audience_project_id (a flow only), paid_stage_project_id (a pipeline only: one of its own stages). Audience ids must name live audiences of this workspace. The ids are ids of this workspace. Use one-row well_query_records lookups to resolve them. Pass null to clear an optional field; an explicit null is a complete change.
Each kind takes its own parent, statuses and fields: deal: no parent; status draft, active, paused, won, lost, archived; takes owner_person_id, counterparty_company_id, counterparty_person_id, stage_project_id, probability, position, end_date, amount, currency. pipeline: no parent; status active, archived; takes paid_stage_project_id. pipeline_stage: nests under a pipeline; status active, archived; takes position, probability. cost_center: may nest under a cost_center; status active, archived; takes no other field. property: no parent; status active, archived; takes no other field. project: may nest under a project; status draft, active, paused, completed, archived; takes counterparty_company_id, counterparty_person_id, start_date, end_date, amount, currency, billing_method. campaign: no parent; status draft, active, paused, completed, archived; takes start_date, end_date, channel, objective, included_audience_project_id, excluded_audience_project_id. audience: no parent; status draft, active, paused, completed, archived; takes start_date, end_date. flow: no parent; status draft, active, paused, completed, archived; takes start_date, end_date, trigger_audience_project_id. ad_set: nests under a campaign; status draft, active, paused, completed, archived; takes start_date, end_date, included_audience_project_id, excluded_audience_project_id. ad: may nest under a campaign or ad_set; status draft, active, paused, completed, archived; takes start_date, end_date. experiment: no parent; status draft, active, paused, completed, archived; takes start_date, end_date, experiment_outcome. Only an experiment takes experiment_outcome (keep, revert, iterate); an ad set may include or exclude live audiences. Pass null to clear either optional field. A status moves along the kind's own path: a deal opens from draft, closes won or lost from active or paused, and a closed deal reopens to active before anything else; an archived project reopens to active. A field the kind does not take, or a move it does not allow, fails and nothing is written.
A pipeline's paid stage is where Well moves a deal of that pipeline on its own, once the bank settles an invoice of the deal's counterparty company, or of a company its counterparty contact works for: an invoice that reads paid with a confirmed bank payment, never one only marked paid. Well tries the move right after such a payment saves, and right after a change names the paid stage or a deal's counterparty. That try can miss a deal: when many payments save at once, past the first 200 deals one try reads, after a restart, for a deal created with a counterparty already settled, or for a deal a person moves onto a stage before the paid stage. A deal the try misses moves only once Well's hourly catch-up is armed. Well moves each deal once, never moves a deal to an earlier stage, never moves a lost or archived deal, and the deal's history shows Well made the move. To take a deal Well moved off the paid stage, move it with stage_project_id: Well leaves it where the person put it. A deal Well never moved, for example one a person put on the paid stage by hand, goes onto the paid stage at Well's next try while its invoice reads settled.
A pipeline stage's win chance is a workspace-wide setting: only an owner or an admin of the workspace can set or clear it, and it changes for the whole workspace. On WhatsApp, a complete typed order from an owner or an admin that names the stage and the new percent saves at once, and the reply says "Saved: now counts at % for the whole workspace." Any other stage order asks for one confirm first, and the confirm card names the workspace, the stage and the old and new percent.
A project a connected tool synced in (synced: true) keeps name, kind, parent_project_id, amount, currency, end_date, stage_project_id, owner_person_id, counterparty_company_id, counterparty_person_id, channel, objective, included_audience_project_id, excluded_audience_project_id, trigger_audience_project_id from that tool: a change that names any of them fails, even beside others, and the user changes them in that tool. status, probability, position, start_date, billing_method, experiment_outcome, paid_stage_project_id, hidden change in Well on a synced project too. A patch is complete when it names the fields to change; do not ask for fields it leaves alone. On WhatsApp, the person's complete typed change approves and writes at once, except a stage's win chance, which saves at once only in the complete typed order above. Other surfaces still use their normal approval.
hidden: true hides the project from Well's lists and figures and keeps it; hidden: false shows it again. It works on a synced project too, since no sync writes it. When the person asks to delete a synced project, well_delete_project refuses and offers this hide: ask the person, then call this tool with only project_id and hidden: true.
Returns { success: true, project } on success, or { success: false, error } on failure.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | What the project is: deal, pipeline, pipeline_stage, cost_center, property, project, campaign, audience, flow, ad_set, ad, experiment. Ask the user when it is not clear. | |
| name | No | ||
| amount | No | ||
| hidden | No | true hides the row from Well's lists and figures and keeps it, with every value a connected tool wrote; false shows it again. Omit to leave it as it is. | |
| status | No | Where the project stands: draft, active, paused, won, lost, archived, completed. A kind holds only some of them. Ask the user when it is not clear. | |
| channel | No | The ad platform a campaign runs on: google_ads, linkedin_ads, reddit_ads, chatgpt_ads, meta_ads, tiktok_ads, pinterest_ads. Only a campaign takes it; null clears it. | |
| currency | No | ||
| end_date | No | ||
| position | No | ||
| objective | No | The campaign objective: awareness, traffic, engagement, leads, sales. Only a campaign takes it; null clears it. | |
| project_id | Yes | The project to change, from a one-row well_query_records lookup. | |
| start_date | No | ||
| probability | No | ||
| workspace_id | No | Target workspace. Omit when the token authorizes one workspace. Required when it authorizes several — a write lands in exactly one workspace and this call would not say which. | |
| billing_method | No | How the work of a project is priced: project_rate, service_rate, person_rate, fixed_fee, non_billable. Only a project takes it; null clears it. | |
| conversation_id | No | The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation. | |
| idempotency_key | No | Optional client-supplied key. A retried write with the same key returns the original result instead of re-applying the operation. | |
| owner_person_id | No | ||
| workspace_scope | No | Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace. | |
| stage_project_id | No | ||
| parent_project_id | No | ||
| experiment_outcome | No | The experiment result: keep, revert, iterate. Only an experiment takes it; null clears it. | |
| paid_stage_project_id | No | On a pipeline: the project_id of its own stage that means paid. A deal of the pipeline moves onto it once the bank settles the creator's invoice; null clears it. | |
| counterparty_person_id | No | ||
| counterparty_company_id | No | ||
| trigger_audience_project_id | No | ||
| excluded_audience_project_id | No | ||
| included_audience_project_id | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | ||
| error | No | ||
| project | No | ||
| success | Yes | ||
| previous | No | ||
| reply_lines | No | ||
| conversation_id | No | The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation. | |
| near_candidates | No | ||
| newly_connected | No | Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later. | |
| conversation_id_note | No | Present only when the server opened a fresh lane, stating that no choice recorded earlier was read. | |
| conversation_id_source | No | Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened. | |
| near_candidates_truncated | No |