OpenNomosdocs
ToolsGrowth loop

log_action

Record something you (or the user) just did or observed on a growth item: what happened (one sentence is enough), the new stage only if you know it…

Record something you (or the user) just did or observed on a growth item: what happened (one sentence is enough), the new stage only if you know it changed, when to follow up, and any outcome. Pass an opportunity id or a URL (an unknown URL is tracked automatically); with neither, only the action is recorded. The server never infers a stage from the action. Do not put private message text or personal data in summaries. Use idempotency_key to make retries safe.

FieldValue
PackCore (core)
Estimated cost per call$0
Monthly pack limitnone
Projectresolved: explicit project → header → credential default → workspace default

Parameters

ParameterRequiredTypeDescription
projectnostringProject slug or id. Omit to use the credential or workspace default.
opportunity_idnostringThe opportunity this is about (id from track or get_briefing). Use this or url, not both.
urlnostring (≤ 2000 chars)Or the post/profile URL it is about; an unknown URL is tracked automatically.
titlenostring (≤ 200 chars)Title for a newly tracked URL.
actionyesobjectWhat was done or observed.
action.kindnostring (≤ 50 chars)What kind of action, e.g. 'comment', 'dm', 'post', 'email'. Default 'action'.
action.summaryyesstringOne sentence on what happened, e.g. 'Replied with a comparison table'. No private message text.
action.channelnostring (≤ 100 chars)Where, e.g. 'reddit', 'x', 'xiaohongshu'.
action.urlnostring (≤ 2000 chars)Link to what you posted, e.g. your comment URL.
action.occurred_atnoISO datetimeWhen it happened (ISO time). Default: now.
stageno"discovered" | "contacted" | "replied" | "willing_to_talk" | "converted" | "dropped"New stage, only if you know it changed: discovered, contacted, replied, willing_to_talk, converted or dropped.
next_followupnoISO datetime | {in_days} | {at} | nullWhen to follow up: {"in_days": 3}, {"at": ISO time}, or an ISO time. null clears it. Default: a stage-based suggestion.
experiment_idnostringAttach this action to an experiment (id from track).
link_codenostring (≤ 32 chars)Code of a short link used in this action (from track type=link), for click attribution.
outcomenoobjectA result of this action, if there is one.
outcome.typeyesstring (≤ 60 chars)What was achieved, e.g. 'signup', 'reply', 'call_booked'.
outcome.valuenonumberAmount, e.g. 1 or 49.9.
outcome.unitnostring (≤ 20 chars)Unit of value, e.g. 'usd', 'count'.
outcome.evidencenostringHow you know, e.g. 'Reply in thread from the author'.
notenostringExtra context, one or two sentences.
idempotency_keynostring (≤ 100 chars)Any unique string; repeating the call with the same key does not record it twice.

Example call

{
  "project": "acme-crm",
  "url": "https://www.reddit.com/r/SaaS/comments/1abc23/looking_for_a_lightweight_crm",
  "action": {
    "kind": "comment",
    "summary": "Replied with a comparison table",
    "channel": "reddit"
  },
  "stage": "contacted",
  "experiment_id": "exp_7Hn2LpWc0",
  "idempotency_key": "2026-10-16-comment-1abc23"
}

REST: POST https://service.opennomos.com/v1/tools/log_action with that JSON as the body. MCP: tools/call with name: "log_action" and that JSON as arguments.

Example result

Values are illustrative; the shape comes from the service code.

{
  "project": {
    "id": "prj_k3Vd9aQx2",
    "slug": "acme-crm"
  },
  "action_id": "act_Lw03pKd8",
  "opportunity": {
    "id": "opp_Qm4x9TnB1",
    "stage": "contacted",
    "next_followup_at": "2026-10-19T09:30:00.000Z",
    "events": 3
  },
  "experiment_progress": {
    "id": "exp_7Hn2LpWc0",
    "metric": "willing_to_talk",
    "current": 1,
    "target": 3,
    "deadline_at": "2026-10-30T09:00:00.000Z"
  },
  "hints": []
}

Notes

  • The write-back half of the loop. OpenNomos never posts, replies or messages anyone: you (or the user) do that elsewhere, then record it here.
  • Pass opportunity_id or url (an unknown URL is tracked automatically). With neither, only the action is recorded.
  • Defaults: the server never infers a stage. If stage is omitted the stage stays. If next_followup is omitted the follow-up time stays unless the stage actually changed, in which case it is set from the new stage: contacted +3 days, replied +2, willing_to_talk +2, converted and dropped clear it. next_followup: null clears it. Details in log_action defaults.
  • outcome records a result (type, optional value, unit, evidence). It is counted as attributed (direct) only when it is tied to an opportunity or a short link; otherwise it is unknown. See Attribution.
  • idempotency_key makes retries safe: repeating a call with the same key replays the first result (with duplicate: true) instead of recording twice. experiment_progress appears when the action is attached to an experiment.
  • hints can contain a one-line warning, for example when outcome.type is willing_to_talk but the stage was not changed.
  • Do not put private message text or personal data in summary or note.

Errors

Rejected calls (bad input, unknown ids, rate limits) return message and code; over MCP the result has isError: true. See Errors.

On this page