commitops
Docs · For agents

Your agents read the ledger before they speak, and write to it when they promise.

One tool registry, served two ways: an MCP server at https://commitops.ai/api/mcp and an HTTP API described by openapi.json. A plain text version for models is at /llms.txt.
StatusEarly access

The server and the tools below are in the code and tested. CommitOps is not open to customers yet; write to hello@commitops.ai for access. Once you can sign in, an owner issues keys under Settings, Agents and keys. Clients that only speak OAuth, such as claude.ai custom connectors, add https://commitops.ai/api/mcp with no key: the client sends you to a consent screen, and approving makes it an agent you operate, with the authority you tick.

ConnectBearer key

Add it to your client

Replace co_YOUR_KEY with your key. A key is shown once, when it is issued, and acts as one principal in one company.

Claude Code

Run once in a terminal.
claude mcp add --transport http commitops https://commitops.ai/api/mcp \
  --header "Authorization: Bearer co_YOUR_KEY"

Claude Desktop

claude_desktop_config.json. Desktop reaches a remote server through mcp-remote.
{
  "mcpServers": {
    "commitops": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://commitops.ai/api/mcp",
        "--header",
        "Authorization:${COMMITOPS_AUTH}"
      ],
      "env": {
        "COMMITOPS_AUTH": "Bearer co_YOUR_KEY"
      }
    }
  }
}

Cursor

~/.cursor/mcp.json, or .cursor/mcp.json in a project.
{
  "mcpServers": {
    "commitops": {
      "url": "https://commitops.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer co_YOUR_KEY"
      }
    }
  }
}

claude.ai custom connector

Settings, Connectors, Add custom connector. No key: claude.ai sends you to our consent screen over OAuth, and approving makes it an agent you operate.
Name:  CommitOps
URL:   https://commitops.ai/api/mcp

HTTP

Every tool is POST /api/v1/tools/<name>, JSON in and out.
curl https://commitops.ai/api/v1/tools/record_promise \
  -H "Authorization: Bearer co_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "quote": "We will ship the Okta SCIM connector by the end of next month",
    "message_text": "Hi Julia, thanks for the call. We will ship the Okta SCIM connector by the end of next month, and I will send the setup guide once it lands.",
    "account": "Acme Health",
    "strength": "firm",
    "due_phrase": "by the end of next month",
    "locator": { "conversation_id": "conv-881", "message_id": "msg-881-4", "channel": "email" }
  }'
Fact sourcecheck_claim

Ask before you claim

A small, versioned route an agent or an agent platform calls before stating a capability. It answers verified, false or unverified with the date the claim was last checked, and it fails open: a fault on our side answers unverified, never an error. The full contract.

curl https://commitops.ai/api/v1/check_claim \
  -H "Authorization: Bearer co_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "statement": "We have EU data residency", "account_id": "Northwind Freight" }'
SDKTypeScript

A client with no dependencies

packages/sdk in our repository: checkClaim, recordPromise and listAssertions over fetch, typed from the same schemas the server runs. Not on npm yet; copy the package or the calls. Setting up one product’s support or sales agent, step by step: per-product setup. How RepoOps and SalesAsCode push changes, spend and deals as agents: the sibling feed contract.

import { CommitOps } from "@commitops/sdk";

const commitops = new CommitOps({ apiKey: process.env.COMMITOPS_KEY! });

// Before stating a capability. Never throws: any failure answers unverified.
const answer = await commitops.checkClaim({ statement: "We have EU data residency" });
if (answer.result !== "verified") reply(answer.say_instead);

// When the agent commits to something, with the exact words and where they were said.
await commitops.recordPromise({
  quote: "We will ship the Okta SCIM connector by the end of next month",
  message_text: thread,
  account: "Acme Health",
  strength: "firm",
  locator: { conversation_id: "conv-881", message_id: "msg-881-4" },
});
RulesSame as people

Agents follow the rules people follow

  • Every caller is a principal

    A key belongs to one principal, a person or an agent, in one company. Whatever the key does is recorded as that principal, on the same history as everyone else.

  • No row without evidence

    A promise is filed with the exact words, the message they came from, and a locator pointing back to it. Without the words there is no row.

  • The quote must be in the message

    The quote has to appear in message_text exactly. Whitespace may differ; case, punctuation and wording may not. A quote that fails is rejected with guard_failed and nothing is written. Copy the words, never paraphrase them.

  • Agents propose, people dispose

    What an agent records is a candidate until a person keeps it. An agent can keep only under an auto_keep policy a person granted it, and never a promise it made itself. The database enforces that, not the API.

  • Ask before you claim

    Call check_claim before you state a capability. Only verified may be said as fact; otherwise use say_instead. Today it answers unverified, because the register of checked claims is not built yet. It fails open: a fault on our side answers unverified, never an error that stalls your reply.

  • Scopes

    A tool needs its authority on both the principal and the key. Read tools need only a valid key. Missing the authority answers 403; a bad, revoked or expired key, or a paused principal, answers 401.

  • Limits

    120 calls a minute per key, per server instance. Over that answers 429 with Retry-After.

Tools149 tools

Every tool

Generated from the registry the server runs, so this list is the list. Read tools need only a valid key; the rest need the authority named, on both the principal and the key.

  • whoamiany key

    The principal this key acts as, its company, what it is allowed to do, and whether it may keep anything without a person. Call it first to learn which tools you can use: a tool needing an authority you lack is refused.

  • list_assertionsany key

    List promises (and later claims and entitlements) in this company's ledger. By default it returns what a person has kept (status open, satisfied, broken or withdrawn), hides exploratory promises, and sorts by due date. Pass status ["candidate"] to see the review queue. past_due is computed from due_at against today at the moment of the call; the ledger never stores lateness. Each row carries its ref, which get_assertion takes for the full record with quotes.

  • get_assertionany key

    Everything about one assertion, by ref: every quote that mentions it with where it was said, the linked pull requests and issues, the deals waiting on it, its full history of decisions, and the latest verification with the date it ran. Quotes are the customer's or the speaker's exact words. Use this before telling a customer anything about a promise.

  • promised_not_startedany key

    Open firm and soft promises with no pull request or issue linked, ranked by the open pipeline each one blocks, then by due date. exposed_cents counts only deals the promise blocks; pipeline_cents is every open deal attached, for context. days_past_due is computed at the moment of the call.

  • shipped_not_toldany key

    Promises whose linked work has all merged or closed, where nobody has told the customer since it shipped. Oldest first. A promise with any satisfying work still open is not here, because half shipped is not shipped.

  • gapsany key

    Both lists from /gaps in one call, recomputed now. not_started: open firm and soft promises with no pull request or issue linked, ranked by the pipeline each blocks, then due date. not_told: promises whose satisfying work has all merged or closed, with nobody telling the customer since; each row carries any "looks told" proposals the told sweep was not sure enough to act on. totals count distinct open deals that a blocking promise on the list blocks, each deal once, and either_cents counts a deal behind both lists once, so it is not the sum of the two. Row money is for reading only.

  • ledger_totalsany key

    The money at the top of the ledger. exposed_cents sums distinct open deals blocked by at least one open blocking promise, each deal counted once however many promises it waits on. past_due_cents is the part behind a promise already late today. attached_cents is every open deal attached to any open promise, for context, not exposure. An inferred deal nobody confirmed counts nowhere.

  • ledger_overviewany key

    The counts and money at the top of the ledger in one call: kept promises, how many are open, past due today, blocking a deal, owned by you, and owned by nobody; candidates waiting for review; claims and entitlements on the spine; and the totals from ledger_totals (each deal counted once, only blocking promises carry money). Exploratory promises are left out of the counts, as the ledger hides them by default. Everything is computed at the moment of the call.

  • first_run_summaryany key

    What the ledger holds so far, for a first look: promises kept, how many are past due today, how many shipped without the customer being told, the open pipeline waiting on a blocking promise (each deal counted once), candidates waiting for review, the three oldest promises still owed, and where the promises came from by source. Every count is computed at the moment of the call.

  • list_candidatesany key

    The candidates waiting for a person to keep or discard, ranked by confidence times strength times account value, highest first. Each row carries the exact quote, who said it to which account, where it was said (source and locator), and the resolved due date with its precision and the phrase it came from. Exploratory remarks are hidden unless asked for. counts gives the size of every filter over the whole queue.

  • list_accountsany key

    The customers in this company's ledger, by name, with each one's id, domains, open pipeline (counted deals only: an inferred deal nobody confirmed is left out), renewal date, open promise count and the CRMs it is linked to. Use an id or an exact name wherever another tool takes an account.

  • get_accountany key

    One account in full: its domains, the CRM records it is linked to, its open promises (lateness computed at the moment of the call), its deals with whether each counts, and the revenue exposed. exposed_cents sums distinct open, counted deals that at least one open promise blocks, where both the promise and its link to the deal are marked blocking; each deal counts once. open_pipeline_cents is every open, counted deal, for a prospect. renewal_arr_cents and renewal_at are the CRM's figures for an existing customer, null when the CRM has none. currencies lists every currency the sums mix.

  • list_dealsany key

    Deals in this company's ledger: synced from the CRM, inferred from mail, or typed by hand. Each says whether it counts toward totals; an inferred deal nobody confirmed does not. Filter by account, source, status, or unconfirmed only, which is the list of deals waiting for a person's one-click confirm.

  • export_ledgerany key

    Every kept promise in this company's ledger (open, satisfied, broken, withdrawn, exploratory included), each with its evidence: the exact quote, who said it, when, the source and the locator that points back to the message, the second of the call or the page. For a backup, an audit, or leaving. days_past_due is computed at the moment of the call. Candidates and discards are not included. At most 5000 promises.

  • product_healthany key

    The two numbers that say whether CommitOps is working for this company: keeps per active week, and the ratio of keeps to discards in the review queue. An active week is a Monday-to-Sunday week (UTC) in which anyone kept or discarded a candidate. A falling keep to discard ratio means the extractor is proposing things people throw away. Returns counts only, per week, over the last `weeks` weeks (default 12), plus the kept rate over the same window.

  • spend_this_monthany key

    What this company's model calls cost this calendar month (UTC), against the monthly budget. Returns spend, budget, remaining, the warning flag at 80 percent and the stop flag at 100 percent, and a breakdown per sweep and model with calls and tokens. At or past the budget no model is called until the month turns or the budget is raised with set_budget. This is what OpenRouter charged us, never the cost of the work a promise needs.

  • get_analytics_settingany key

    Whether this company has turned product analytics off. The events never carry customer words (enums, numbers and our own ids only); turning them off stops even those counts leaving the system.

  • current_planany key

    This company's plan: the tier (which objects it can carry), the band (accounts under management, from the highest count of accounts with an open assertion in the last 90 days), the subscription status, the renewal date, any downgrade waiting for renewal, every cap against what is used now, and every feature_key the plan grants. Seats and agents are never counted or capped. Reading is never blocked by the plan.

  • plan_gridany key

    The public price list as data, read from the same table that gates every plan: each tier and band with its monthly and annual price in cents (annual is two months free; null means quoted), the objects it carries, its caps and what it includes; the account bands; and the add-ons. Flat per company. Never per seat and never per agent.

  • check_claimany key

    Ask before you state a capability to a customer, e.g. "we have EU data residency". The answer is verified, false or unverified, with the matching claim, the date it was last checked, one line of evidence, and a sentence to say instead when it is not verified. Only verified may be said as fact. It fails open: anything wrong on our side answers unverified with a reason_code, never an error. Verified needs a true check inside the claim's recheck window; false comes with the date of the check that said so. The statement is never stored; a salted hash is kept to count calls.

  • list_claimsany key

    Every kept claim (what the company says the product does today), ranked by blast radius: claims needing someone first, then those on a public page still showing, then by how many places they appear, then the stalest check. Each carries its state worked out now from the latest dated check (false, verified, expired, never_checked), where it appears, what checks it and who checked it last. Filter with needs_attention, verified, false_published (false and still on a public page), attestation_expired or never_checked. Reading is never refused by plan.

  • get_claimany key

    One claim in full, by ref (K-021): its state now, every place it appears and whether it still does, the checks configured, every dated verification newest first, the overclaims that matched it, and when it stopped being true: the date the latest run of false results began, how long it had been true before, where it was still showing then, and who repeated it to a customer afterwards, with whether that agent called check_claim. Reading is never refused by plan.

  • list_claim_candidatesany key

    Claims proposed from pages, uploaded documents or overclaims, waiting for a person to keep (keep_candidate) or discard (discard_candidate). Each with the words it came from and where.

  • list_claim_surfacesany key

    The pages this workspace asked us to read for claims, with when each was last read and what happened, and the uploaded documents.

  • list_overclaimsany key

    Capability statements one of our people or agents made to a customer that the register cannot back: matched a claim whose latest dated check is false, matched one nobody checked or whose check lapsed, or matched nothing. False ones first. Each names the speaker, the account, the claim and the date of the check the register answered from, and for an agent whether it called check_claim around then.

  • list_entitlement_driftany key

    The latest reconciliation: per account, what the contract says against what the system grants, with where it was read and a direction, led by under_granted (a customer paying for something they cannot use, the churn risk nobody reports). By default only terms that disagree; direction filters to one, or all includes matches. The KPI line comes with it: over-granted per year at the terms' prices, accounts that cannot use what they bought, the ARR behind them (each account once, from the CRM), breaches. Also lists the sources. Reading is never refused by plan.

  • get_entitlementany key

    One entitlement in full, by ref (E-031): the clause verbatim with its page and document, each parsed term, and the places it disagrees: the contract, the linked claim in the register (a pricing page line, with whether its last check passed) and every source's latest value with its locator, the code line included (src/lib/limits.ts:34). The comparison now, every dated run's direction for it, and its verification history. Reading is never refused by plan.

  • list_contract_termsany key

    The entitlement terms read from signed contracts: candidates waiting for a person, and kept terms, each with the clause verbatim, its page and document, the parsed feature_key, operator, value and unit, and any linked claim. Also lists the contracts uploaded. Filter by status (candidate, kept, all) and account. Reading is never refused by plan.

  • export_entitlement_driftany key

    The latest reconciliation as rows for finance: account, feature, what the contract says and what the system grants, where it was read, the direction, over-granted per year at the term's price with its basis (contract or price_list), the account's ARR, the contract reference and the clause. Disagreeing terms only unless all is true. Totals count each account once. These are revenue figures at a price and ARR; no cost is in them. Reading is never refused by plan.

  • agent_scoreboardany key

    Every principal in this company, people and agents on one list, with what each may do, what each promised in the window, how many of those were kept (the work merged), how many are broken (open and past due, computed now, never stored), and how many claims it made turned out false. Sorted by broken promises, then false claims. Also the check_claim counts for the last 7 days and which agents call it. On plans below Company the numbers are null and included is false; the list of principals is still returned.

  • list_auto_keptany key

    What agents kept under an auto_keep policy: each live policy with who granted it and when, counts of rows kept this way, sampled and reviewed, and the rows themselves, newest first. One machine-kept row in five, starting with each agent's first, is sampled for a person to review. Pass queue_only to see only sampled rows nobody has reviewed yet.

  • list_work_itemsany key

    List the pull requests, merge requests and issues this company's GitHub App, GitLab, Linear workspace and Jira sites have sent, newest first, with the promises each is linked to and any link waiting for a person to confirm. CommitOps mirrors the key, title, URL and state; the work itself stays in those tools. A GitLab merge request is kind pull_request. Filter by provider, state, or whether anything is linked.

  • get_promise_pageany key

    What one account's promise page shows (pass account), or the public company page (pass company: true), built by the same code the page uses, so it is exactly what a viewer reads: titles, plain statuses, and only the dates, work and owners the options allow. Never a quote or an amount. preview is the page as it reads now even when nobody can open it; live says whether a viewer can. Also the link's prefix and age (never its token), and views in the last 30 days.

  • get_digestany key

    Where and when the daily Slack digest goes, and when it last went. Null when no channel is chosen.

  • list_recordingsany key

    List the recordings a connected transcript source (Fireflies, Granola, Zoom, Gong) has listed, newest first: ids, start times, lengths, how many turns and speakers, how many turns were queued for extraction, and how many quotes were kept as evidence. Never a title or a word of the call. A recording with only our own people on it is internal and was never read.

  • get_evidence_playbackany key

    For one piece of call evidence (its evidence_id, from get_assertion), the time into the call where the quoted words begin, as milliseconds and as mm:ss, and the provider's page for the recording. When the provider gave no timing (precision note), there is no time: show none rather than 0:00. No provider documents a link that opens at a moment yet, so url_at_offset is false and the time is shown beside the link.

  • list_asksany key

    Inbound requests from customers, clustered across wordings ("sfdc sync", "push to salesforce" and "bidirectional CRM" are one ask), with mentions in the window (180 days by default). Each ask carries two dollar figures over distinct open deals: mentioned_cents (deals on accounts that asked) and alone_cents (deals where this ask is the only open blocker). Ranked on alone_cents, then mentioned_cents, then accounts; never by cost and never by volume first. roadmap.state is worked out from linked work at the moment of the call.

  • get_askany key

    One ask: its figures as on list_asks, every mention with the customer's exact words and the pointer back to where they said it, the deals behind it (with whether this ask blocks each and whether it is the only blocker), and any promise already made about it.

  • get_reviewany key

    The stored Monday page for one ISO week: what was promised, shipped, told, slipped and overdue, cost to build with measured and modeled kept apart, who carries what, and what changed, each figure with the refs behind it. Built by the Sunday sweep (or build_review_now) and kept as it stood then. snapshot is null for a week nobody built. Counts, sums, refs, titles and account names only; never a quote. Also returns the review settings and the neighbouring weeks.

  • list_delivery_runsany key

    Every delivery run, newest signature first: a closed-won deal and the promises made to that account while selling it, with counts done, in progress, not started and late (computed now). A run opens by itself when a deal turns closed won.

  • get_delivery_runany key

    An account's latest delivery run with its rows: each promise made while selling, with owner, due date and lateness (computed now), state (done, in progress, not started, from the linked work), and whether the customer was told. other_runs lists earlier runs for the same account.

  • list_documentsany key

    List the Google Drive files chosen and the Notion pages shared with CommitOps: what kind each is, the account it belongs to, when it last changed and when it was read, and the outcome of the last read. A document with no account that is not a questionnaire or RFP is not read until someone names one with set_document.

  • list_sibling_feedsany key

    List the RepoOps and SalesAsCode feeds this company connected: the agent each pushes as, its source, when it last pushed and how many pushes it made. An empty list is normal: CommitOps works without either sibling.

  • list_teamsany key

    This workspace's teams, each with its members (people and agents) and the authority each holds on that team's rows, and whether teams are on. With teams on, someone who is not an owner sees only their teams' accounts and assertions, plus those no team holds.

  • get_ssoadmin

    This workspace's SSO connection (SAML 2.0 or OIDC): the bound domains, the identity provider's entity id and sign-on URL or OIDC issuer and client id (never the secret), when each signing certificate expires, whether SSO is required, when it last tested good and when someone last signed in, and the URLs to paste into the identity provider. Scale only to configure; reading is never blocked. Needs admin.

  • get_audit_exportadmin

    One audit export by id, or the 20 most recent when no id is given: its status, who asked, when it was made and when the file expires, its counts, the SHA-256 of the file and of its manifest, and the signature. Pass include_bundle true with an id to receive the .tar.gz itself as base64 (up to 8 MB; larger ones download from /settings). Needs admin.

  • record_promisepropose

    Call this the moment you commit to something for a customer, so the company knows what you promised. Send the exact words of the commitment as quote and the full message you sent as message_text; the quote must appear in the message verbatim, whitespace aside, or the call is rejected and nothing is written. The promise is filed as a candidate made by you, with the message as evidence. It is never kept on your say-so: a person reviews it, and you can never keep your own promise. Retrying the same quote from the same message returns the first row.

  • propose_assertionpropose

    Propose a promise somebody made to a customer, found in a message, a transcript or a document you have. Send the exact words as quote, the full text they came from as message_text, who said it as speaker, and a locator pointing back (a message id, a recording offset, a page). The quote must appear in message_text verbatim, whitespace aside, or the call is rejected and nothing is written. The promise is filed as a candidate for a person to keep or discard. Today only promises can be proposed; claims and entitlements follow.

  • keep_candidatekeep

    Move a candidate from the review queue into the ledger, as open. This is the decision that makes a promise count. A person with the keep authority may keep any candidate. An agent may keep only under an auto_keep policy a person granted it, within that policy's bounds, and never an assertion it made itself; the database refuses those and this tool returns the refusal. Optionally set the owner who must deliver it.

  • discard_candidatekeep

    Remove a candidate from the review queue because it is not a real commitment, is a duplicate, or names the wrong account. The discard is recorded with you as the actor and counts in the kept rate. Needs the keep authority. Optionally say why with a reason code; it labels the example the classifier learns from.

  • link_worklink_work

    Link a promise, by ref, to a pull request or issue the work sources mirrored, as a link a person made. It writes the link, a dated history event, and a work_link verification, which reads true once every satisfying item has merged or closed. A linked pull request gets the CommitOps comment unless the org turned comments off. Both the ref and the work item must be in your org; anything else is not found. Overrides an earlier unlink of the same pair.

  • unlink_worklink_work

    Remove the link between a promise and a work item, with a dated history event and a new work_link verification. No automatic pass will link the pair again; only link_work can. Use it when a link is wrong: a wrong link tells a founder something shipped when it did not. The pull request's comment is updated to match.

  • confirm_proposed_linklink_work

    Confirm a link the similarity pass proposed between a promise and a work item. Similarity never links on its own; this call is the person deciding. It becomes a link a person made, with its score kept as the confidence, a work_link verification, and the PR comment.

  • reject_proposed_linklink_work

    Reject a link the similarity pass proposed. The refusal is kept, so no pass proposes or links that pair again. Rejecting a wrong match is as useful as confirming a right one.

  • match_nowlink_work

    Run the four match passes for one promise against the work already mirrored, instead of waiting for the sweep. Pass 1, Satisfies C-142 in a PR or issue, links at 1.00. Pass 2, the same roadmap slug, links at 0.90. Pass 3, title similarity above 0.82, only proposes: the proposals come back with their scores for a person to confirm or reject. Pass 4 is no match, which is a correct answer.

  • set_roadmap_sluglink_work

    Set or clear the roadmap slug on a promise, such as saml-sso. Pass 2 links the promise at 0.90 to any pull request or issue carrying the same slug: a GitHub or Linear label named roadmap:saml-sso, or a Linear project whose name reduces to it. Runs passes 1 and 2 for the promise at once. Send null to clear it.

  • edit_candidatekeep

    Correct a candidate before it enters the ledger: its title, owner, due date, strength or whether it blocks a deal. Each change is written to its history with you as the actor (a title change records that the title changed, not the words). Set keep to true to keep it in the same call, under the same rules as keep_candidate. The quote and its source never change; they are the evidence. Needs the keep authority.

  • paste_sourcepropose

    Add a call transcript or an email thread as text, for one account, and read it for promises. Lines that start with a speaker label ("Dana Whitfield: ...", optionally after a [00:12:30] timestamp) become turns; a speaker who is one of this company's people, or is listed in our_speakers, is our side. The paste becomes its own source, so deleting it later deletes every word it contributed. With extract_now (the default) it is read at once and the new candidates come back by ref; otherwise the extract sweep reads it. Every result is a candidate for a person to keep or discard. Pasting the same text for the same account and time again changes nothing.

  • move_due_datekeep

    Change the date an open promise is due, for example after the team re-plans. The old and new dates are written to the promise's history with you as the actor and an optional note, and the history is never rewritten, so anyone opening the promise sees that the date moved and when. Moving a date does not tell the customer anything. Needs the keep authority.

  • assign_ownerkeep

    Set who must deliver an open promise or a candidate: a person or an agent in this company, by principal id or display name. Pass null to leave it with nobody, which puts it on the no-owner filter. The change is written to the history with you as the actor. Needs the keep authority.

  • withdraw_assertionwithdraw

    Take an open promise off the ledger because the company will not do it, the customer no longer wants it, or it was superseded. It stays visible as withdrawn with its quotes and history, and leaves every open list and total. The withdrawal is written to the history with you as the actor. Withdrawing does not tell the customer. Needs the withdraw authority.

  • draft_told_emailcommunicate

    Write the note telling a customer that a promise shipped, as a draft in the caller's own Gmail (an agent's goes in the Gmail of the person who operates it). It is never sent: the person reads it and sends it, or not. The draft is offered only when every satisfying pull request or issue has merged or closed and the latest work_link verification says so and is dated after the last merge; otherwise the reason names what is not shipped. It is addressed to the customer contact on the evidence, or to `to`, which must be an address at the account's domain. It claims only that the work shipped and when. Pass dry_run to see the check and the words without writing anything. Needs the communicate authority and the Write drafts in Gmail permission on /connect.

  • mark_toldcommunicate

    Record that the customer was told a promise shipped, when it happened somewhere CommitOps cannot see. It writes a communication with you as the actor and a dated history row, and the promise leaves shipped and not told when the date is on or after the work shipped. reference is a pointer (a message id, a link, "Oct 14 call"), never what was said. Needs the communicate authority.

  • confirm_toldcommunicate

    Decide a "looks told" proposal from the told sweep, by its id from the gaps tool. confirm true records the communication it found and the promise leaves shipped and not told; confirm false rejects it, and that message or meeting is never proposed again for this promise. Needs the communicate authority.

  • run_told_sweepcommunicate

    Look now, instead of at the next hourly run, for customers already told about promises on shipped and not told: mail sent to the account's domain after the merge, a draft we made that has since been sent, and meetings with the account after the merge. A strong match records the communication and drops the row; a weak one becomes a "looks told" proposal for a person. Reads up to 25 rows per call. Needs the communicate authority.

  • set_public_visibilitycommunicate

    Choose where a kept promise is shown outside the company. account_page puts it on its own account's promise page, which only that customer's link opens. company_page puts it on the company's public page at /p/org/<slug>, which anyone can open, and needs a public title first (set_public_title), because that page names no customer. Nothing is shown until a person turns it on. A viewer sees the title, a plain status, and only what set_promise_page_options allows; never a quote or an amount. The change goes in the promise's history. Needs the communicate authority.

  • set_public_titlecommunicate

    The title a customer reads on the promise page, in the company's words. Without one, the account page shows the ledger title and the company page does not show the promise at all. Write it for the customer: what they will get, not who asked or what a deal is worth. Pass null to clear it, which also takes the promise off the company page. The history records that the public title changed, not what it says. Needs the communicate authority.

  • create_promise_page_linkcommunicate

    Create the link that shows one customer account its promise page: the promises marked for its page, each with a plain status. No sign-in for the viewer, so treat the link like a password. The token is returned once and never again; to send it to someone new later, copy it from where you sent it, or rotate. One live link per account: if one exists this refuses, and rotate_promise_page_link replaces it. Needs the communicate authority.

  • rotate_promise_page_linkcommunicate

    Replace an account's link with a new one. The old link stops working at once, for everyone who has it, and any site embedding it shows that the page is not available. The new token is returned once. Use it when a link went somewhere it should not, or to send a fresh one. Needs the communicate authority.

  • revoke_promise_page_linkcommunicate

    Turn an account's link off. Anyone who opens it after this sees that the page is not available, with no hint of why. Nothing about the promises changes. Needs the communicate authority.

  • set_promise_page_optionsadmin

    Turn account pages on or off for the whole company, and choose what a viewer sees beside each title: the promised date, the work items behind it (keys, titles and links, which can name repositories), and owner names. All four start off. Dollar figures, quotes and deals are never shown, and there is no option to show them. Needs admin.

  • set_company_pageadmin

    The company's public promise page at /p/org/<slug>: the promises marked public with set_public_visibility, under their public titles, with no customer named. Set enabled, the slug, and the hosts allowed to embed it with /embed.js, beyond the company's own domains ("example.com" allows it and its subdomains over https; "localhost:3000" allows a local test page). embed_domains replaces the whole list. Returns the one script tag a site adds. Needs admin.

  • propose_dealpropose

    For an account with no CRM deal: propose an inferred deal seeded from a promise's evidence, the mail thread it was read from. The amount is the one dollar figure in our own words around that quote, or empty when there is none or more than one; the caller never supplies it, so no figure is invented. It enters no total until a person confirms it with confirm_deal. Refused when the account already has an open CRM or inferred deal: attach the promise to that one instead.

  • confirm_dealkeep

    A person confirms an inferred deal is real, optionally setting or correcting its amount at the same moment. From then on its amount may enter totals, through any promise marked blocking on it. Only a person can confirm; an agent's call is refused. A CRM deal needs no confirming.

  • edit_dealkeep

    Change an inferred or manual deal's name, amount, currency, stage, close date or status. A CRM deal is refused: edit it in the CRM, which stays the system of record. When an agent changes a confirmed deal's amount or currency, the confirmation is cleared and a person confirms again.

  • attach_dealpropose

    Link a promise to a deal on the same account, so the deal shows on the promise and the promise on the deal. Pass is_blocking true only when a person has said the deal waits on this promise: only a person may set it, and an agent's call with it is refused. A deal's amount enters a total only when the promise is blocking (mark_blocking) and this link is blocking, and each deal counts once however many promises it waits on.

  • mark_blockingkeep

    A person says a promise does, or does not, block a deal. Sets the promise's blocking flag, and, when deal_id is given, the flag on its link to that deal too, attaching it if needed. A total counts a deal only when both are set. Only a person can call this.

  • sync_crm_nowadmin

    Bring the next sync of each connected CRM (HubSpot, Attio, Salesforce, Pipedrive) forward to now, or of one provider. A sync reads companies with their domains and open and recently closed deals with amount, currency, stage, dates and owner, only what changed since the last pass, and never notes, emails or activities. It runs on the job runner within minutes; running is true when one is already under way. Needs admin.

  • merge_askskeep

    Fold one or more asks into another when they are the same request in different words. Every mention moves to `into`, and the others are gone. Pass title to rename the one that stays. Needs the keep authority.

  • split_askkeep

    Move some of an ask's mentions into a new ask, when two different requests were clustered together. Pass the evidence ids from get_ask; at least one must stay behind. The new ask is named from the first moved mention unless you pass title. Needs the keep authority.

  • mark_not_askkeep

    Take an ask off /asks because it is not a request for the product: a bug report, a question about billing, chatter the detector misread. Its words stay attached, so the next sweep never raises them again. Needs the keep authority.

  • send_ask_to_linearlink_work

    Turn an ask into a Linear issue through the org's Linear connection, only when that connection was granted write. Otherwise nothing leaves and you get a plain summary to copy: the ask's name, accounts, the two dollar figures, the roadmap state and a link back, never a quote or an account name. team_key picks the Linear team ("ENG"); the workspace's first team otherwise. An ask already sent returns its issue. Needs the link_work authority.

  • build_review_nowkeep

    Assemble a week's Monday page now instead of waiting for Sunday, and store it, replacing that week's page if there was one. A week still running is read up to this moment. Sends nothing. Needs the keep authority.

  • send_reviewcommunicate

    Send a stored week's page now: as a Gmail draft addressed to the review recipients, in your own Gmail (an agent's goes in its operator's), which you then send; and as a post in the digest's Slack channel. Choose either or both; by default, the ways the settings name. Counts, refs, titles and account names, never a quote. Build the week first if it has no page. Needs the communicate authority.

  • open_delivery_runkeep

    Open a run for an account by hand: when a person marks a deal won, or the CRM has not caught up. With opportunity_id, a manual or confirmed inferred deal still open is marked won today, which opens the run; a CRM deal is left as the CRM has it and the run opens beside it. Without one, the run opens for the account as of today. owner sets who carries the handoff. An existing run is returned, with the owner updated when given. Needs the keep authority.

  • send_delivery_statuscommunicate

    Write a plain note to the customer saying where each promise made during the sale stands (done and when, in progress, not started yet, and the date we gave), as a draft in your own Gmail (an agent's goes in its operator's). It is never sent by us. It uses the promise page title when one is set, never a quote, a ref or an amount. Addressed to the customer contact on the evidence, or to `to`, which must be at the account's domain. Pass dry_run to see the words and write nothing. Needs the communicate authority and Write drafts in Gmail on /connect.

  • add_claim_surfacepropose

    Add a page of this company's own site (the homepage, the pricing page, a features or security page) to read for capability claims. It is read within the hour and then once a day, politely: robots.txt is respected and the user agent names us. What it claims arrives as candidates for a person to keep. API reference docs are refused (any path like /api, /reference or /openapi, or an api. host): the register stays out of OpenAPI drift. Company plan and above.

  • crawl_surface_nowpropose

    Read one page added with add_claim_surface right now instead of waiting for the hourly sweep, and say what it found: new candidates, lines matching existing claims, and lines that disappeared since the last read. A page we could not read (robots, an error, a timeout) changes nothing about what it said before. Company plan and above.

  • upload_claim_documentpropose

    Read a sales deck, a signed security questionnaire or an RFP answer for capability claims. Send the file as content_base64 (PDF or DOCX, read by its bytes) or a pasted answer as text. Each claim found becomes a candidate, or one more place an existing claim appears, pointing at its page. The same file twice is one document. Over the HTTP API the whole body is capped at 1 MB, so a file of about 700 KB; the screen takes up to 4 MB. A scanned PDF with no text layer yields nothing. Company plan and above.

  • add_capability_checkverify

    Say how a claim is verified. endpoint_check: {url, method, expect_status, json_path?, op?, value?} hits an HTTP endpoint. flag_check: {adapter: json_endpoint, url, flag_key, expected} reads a flag from a JSON document. config_check: {adapter: json_endpoint, url, json_path, op, value?} reads a config value. code_check: {mode: merged_pr, pr: "owner/repo#123"} passes while that pull request is merged and not reverted, from what our GitHub App can read; reading files (mode file_pattern, adapter repo_file) needs the Contents permission, which the app does not have, so those answer unknown. human_attestation: a person confirms it with attest_claim; it expires after recheck_days and the register nags. Every run writes a dated verification. Company plan and above.

  • run_check_nowverify

    Run one automated check on a claim now instead of waiting for the daily sweep, and get what it found, dated. A false result moves the claim to broken; a true one to satisfied; unknown (it could not run) moves nothing. Every run is kept as history. A human attestation is not run: use attest_claim. Company plan and above.

  • attest_claimverify

    As a named person, confirm that a claim is true today (result true) or say it is not (result false). Dated now, recorded with your name, and good for the claim's recheck window (or its attestation check's), after which the register shows it as attestation expired and check_claim answers unverified until someone attests again. Only a person may attest; an agent is refused. A false attestation moves the claim to broken. Company plan and above.

  • set_claim_detailsverify

    Set what check_claim offers to say instead when this claim is false or unverified (say_instead, e.g. "EU residency is on the roadmap, with no date committed"), how many days a check stays good (recheck_days), and whether it is public. Company plan and above.

  • resolve_overclaimverify

    Close an overclaim once someone has acted: corrected (the customer was told the right thing), claim_is_true (a person confirms it; attest the claim too so the register says so), not_a_claim (the detector misread it), or added_to_register (it matched nothing, and it should be a claim: this proposes one from the same words, for a person to keep). Company plan and above.

  • upload_contractpropose

    Read a signed order form, MSA, amendment or renewal for one customer account and propose its entitlement terms: each a feature_key (api.rate_limit, seats, sso, data_residency), an operator (eq, gte, lte, includes, unlimited), a value and unit, and the clause as a verbatim quote with its page. Send content_base64 (PDF or DOCX, read by its bytes) or text. The model reads it under zero data retention routing; every clause must appear word for word on a page or the term is thrown away and counted. Terms arrive as candidates for a person to keep with keep_contract_term. The same file twice is one document. A scanned PDF with no text layer yields nothing. A CLM connector is not built. Contract ingestion is included on Scale and a $299 add-on on Team and Company.

  • keep_contract_termkeep

    Keep a proposed contract term (E-031) as an entitlement, so reconcile_entitlements checks it against the running system. Correct the parse first if it is wrong: feature_key, operator, value, unit, term_kind (grant, or obligation for residency, retention and the like, where a difference is a breach), more_is_better (false for a response time), and price_cents_year (one unit for a year, from your price list when the contract states none; it prices over-grants). claim_ref links a claim in the register that says the same thing, such as a pricing page line. Needs the keep authority; the database refuses an agent keeping a term it proposed. Contract ingestion is included on Scale and an add-on below.

  • add_entitlement_sourceverify

    Say where the running system records what each account is granted. kind plan_config: {adapter: json_endpoint, url} or {adapter: inline, document} (a config file's JSON, no database needed) or {adapter: repo_file, repo, path}, with {plans: {<plan>: {<feature_key>: value}}, accounts: {<account name, id or domain>: {plan, overrides}}} in the document (plans_path, accounts_path and features move or rename the parts). kind flag_service: {adapter: json_flags, url or document, flags: {<feature_key>: <flag key>}}. kind code, the hardcoded check: {files: [paths], account_plans: {<account>: <plan>}, mappings: [{feature_key, symbol, field?, unit?}], repo?} reads constants such as RATE_LIMITS.enterprise = 10_000, objects keyed by plan, ENTERPRISE_SEATS = 50, if (plan === 'enterprise' && count > 10000), and lists like SSO_PLANS, in TypeScript, JavaScript and Python, with the file and line. Code is read from files you hand read_entitlements_now, or through the GitHub App once it has Contents read. The same name again replaces the config. Scale plan.

  • read_entitlements_nowverify

    Read one source (by id or name) or every enabled one now, and write what each account is granted as dated rows with the source and a locator: the file and line for code, the JSON path for a config, the flag and rule for a flag. Nothing earlier is overwritten. For a code source, hand over the named files in files when the GitHub App cannot read the repo (it has no Contents permission today). For a plan_config or flag source, document replaces the configured URL for this read. Then call reconcile_entitlements. Scale plan.

  • reconcile_entitlementsverify

    Compare every kept entitlement with the latest value each source read for that account, and record the run: a dated row per term with its direction (under_granted, over_granted, not_granted, mismatch, breach for an obligation the system plainly violates, or match), and a dated verification per entitlement, which moves it to broken when it differs and to satisfied when every term matches. Nothing earlier is overwritten. read_first reads every enabled source before. Returns the KPI line: over-granted per year at the terms' prices, accounts that cannot use what they bought and the ARR behind them (each account once), and breaches. Scale plan.

  • create_credentialadmin

    Issue an API and MCP key for yourself or an agent you operate (an owner may issue for anyone). The key is returned once, in this response, and cannot be shown again; store it before you do anything else. It carries only scopes your own key carries and the target principal holds, and expires after expires_in_days (90 unless you say). Needs admin.

  • list_credentialsadmin

    The keys you may manage: your own and those of agents you operate, or every key in the company for an owner. Shows the prefix, scopes, last use, expiry and revocation. Never shows a secret. Needs admin.

  • revoke_credentialadmin

    Revoke a key by its id or its 8 character prefix. It stops working on the next call. Revoking is permanent; issue a new key instead of reviving one. Revoking an OAuth access token also revokes the refresh tokens behind it, so the client has to ask a person again. Same reach as list_credentials. Needs admin.

  • set_budgetadmin

    Set this company's monthly ceiling on model spend, in US dollars. At or past it, extraction stops calling a model until the month turns. Zero stops every model call. warn_ratio is the share of the budget that raises the warning, 0.8 unless given. Needs the admin authority. Returns the month's status under the new budget.

  • set_analytics_opt_outadmin

    Turn product analytics off (opted_out true) or back on for this whole company. Off means no event is sent for anyone in it from the next call on. Needs the admin authority.

  • set_digestadmin

    Choose where and when the daily Slack digest goes: a public channel by name ("#founders") or id, a local time (default 08:30), the weekdays (default Monday to Friday), the company's IANA time zone ("America/Chicago"), and whether it is on. Fields left out stay as they are. Slack must be connected on /connect first. The digest carries refs, titles, account names, dates and counts, never a quote. Needs the admin authority.

  • send_digest_nowcommunicate

    Post today's digest to the chosen Slack channel now: new candidates since the last digest, promises due this week or late, and what shipped with nobody telling the customer. The scheduled one still goes at its time. Refs, titles, account names, dates and counts only, never a quote. Needs the communicate authority.

  • set_cost_modeladmin

    The two numbers the modeled cost on the Monday page needs: loaded_daily_rate_cents, what one engineer-day costs the company loaded (null clears it, and then no estimate is made), and parallelism, how many things an engineer carries at a time (default 2). The page shows the formula and these inputs beside the estimate and never adds it to measured spend. Fields left out stay as they are. Needs the admin authority.

  • set_review_scheduleadmin

    Who receives the Monday page and when the Sunday sweep assembles it: recipients (principal ids of people in this workspace), review_day (ISO weekday, 7 is Sunday), review_at (HH:MM in the org's time zone, default 18:00), by_email (a draft in your own Gmail addressed to them) and by_slack (a post in the digest channel). The org's time zone is set with set_digest or here. Fields left out stay as they are. Needs the admin authority.

  • list_principalsany key

    Everyone who can act in this company, people and agents in one list: name, type, role, what each may do, who operates each agent, and whether it may keep anything without a person. Use it to find a principal id before creating a key or assigning an owner.

  • create_agent_principaladmin

    Add an agent to the company as a principal of its own, so what it says and does is recorded against it and scored like a person. Name it, say what kind of agent it is and whose it is (agent_vendor), and name the person accountable for it (operated_by, yourself unless you are an owner). It starts with the authority you give it, never more than you hold, and may only propose until an owner sets a bounded auto_keep policy. Then issue it a key with create_credential. Needs admin.

  • update_principaladmin

    Set a principal's authority, pause or retire it, or make a person an owner. An owner may change anyone but themselves; anyone else with admin may change only the agents they operate. A person who joined by company domain starts with no authority, and this is how an owner grants it. Authority granted never exceeds your own. Pausing an agent stops every key it holds on the next call. Needs admin.

  • invite_memberadmin

    Invite someone by email. When they next sign in with Google at that address they join this company with the role and authority given here, never more than you hold. Nothing is emailed; tell them to sign in at /signin. Inviting the same address again replaces the open invitation. Lasts 14 days. Needs admin.

  • list_invitationsadmin

    Open invitations to this company, newest first, and optionally the accepted, revoked and expired ones. Needs admin.

  • revoke_invitationadmin

    Withdraw an open invitation by its id. The address can no longer join through it. Needs admin.

  • grant_auto_keepadmin

    Let one agent keep candidates without a person, inside four bounds: a confidence floor, the kinds and strengths it may keep, and a daily limit. Replaces any policy it held. Only an owner may grant one, it is recorded with who granted it and when, and every row the agent keeps this way carries the policy, shows as machine-kept, and one in five goes to a person for review. The agent still may never keep anything it made itself. Adds the keep authority to the agent; its key needs keep too. Company plan and above.

  • revoke_auto_keepadmin

    Take an agent's auto-keep policy away, so it may only propose again. Rows it already kept stay kept and keep the policy that allowed them; review or withdraw them separately. Removes the keep authority, which an agent cannot use without a policy. An owner, or the person who operates the agent, may revoke. Never refused for the plan.

  • review_auto_keptkeep

    A person's verdict on one row an agent kept under its policy: right (a person would have kept it) or wrong (it should not be on the ledger as kept). Stored once per row and never changed. A wrong verdict does not move the row; withdraw or edit it on its page, and consider narrowing or revoking the policy. Needs the keep authority, and only a person may review; an agent is refused.

  • record_spendany key

    Report what an agent cost on one day, measured from its vendor's bill or meter, in cents. It shows as Spend on the scoreboard. Measured only: a modeled or estimated figure does not belong here and is never summed with measured cost. An agent reports for itself; a person reports for an agent they operate, or an owner for any agent. Reporting the same day again replaces the figure.

  • link_github_installationadmin

    Tell CommitOps which org a GitHub App installation belongs to, so its webhooks land here. The install flow at /connect binds an installation the signed-in person can reach; this tool binds one by id, for an agent or a script: pass the installation id from the app's installation settings URL and the account it was installed on. An installation already bound to another org is refused. Needs admin.

  • link_linear_workspaceadmin

    Tell CommitOps which org a Linear workspace belongs to, so its webhooks land here. Pass the workspace's organization id, the organizationId on every Linear webhook. A workspace already bound to another org is refused. /connect binds a workspace through Linear's own consent; this tool binds one by id, without a token. Needs admin.

  • set_pr_commentsadmin

    Turn the CommitOps comment on linked pull requests on or off for the whole org. It is on by default. Off, links and verification work as before and no comment is posted or edited. A public repository's comment names only the ref, never the account or the dollars, whatever this is set to. Needs admin.

  • set_mr_commentsadmin

    Turn the CommitOps note on linked GitLab merge requests on or off for the whole org. It is off by default. On, a merge request that satisfies a promise gets one note, edited in place when its links change, saying which promise and, on a private project, the account, the open dollars and the date; a public or internal project's note names only the ref. The GitLab connection must hold the api scope (connect with the note grant). Needs admin.

  • gitlab_webhook_setupadmin

    Give the URL and secret token to paste into a GitLab project's or group's Settings, Webhooks, for one GitLab connection, with the triggers to tick: merge request events, issue events and comments. GitLab sends nothing until a person adds it. The token is derived for this connection alone and stops working when the connection is disconnected. Needs admin.

  • connect_gitlab_tokenadmin

    Connect a self-managed GitLab instance, which our gitlab.com OAuth app cannot reach, with an access token a person creates there: a personal, group or project access token with read_api, or api if the merge request note should be posted. The instance must be https and must not resolve to a private address. The token is checked with one call, stored encrypted, and never returned or logged. gitlab.com connects through OAuth on /connect instead. Then add the webhook from gitlab_webhook_setup. Needs admin.

  • start_checkoutadmin

    Create a Stripe Checkout link for Team or Company, at the band this company's accounts put it in, monthly or annual (two months free). Add-ons are optional. Tax is calculated by Stripe Tax. Returns a URL for a person to open and pay. Refuses when the company already has a live subscription (use change_plan), above 400 accounts (quoted), and for Scale (quoted and invoiced). Needs the admin authority. Answers unavailable when billing is not configured.

  • change_planadmin

    Move a live subscription to another self-serve tier at the same band and interval. An upgrade takes effect now and Stripe prorates it. A downgrade takes effect at renewal: until then the company keeps what it paid for, and current_plan shows the change waiting. Choosing the current tier again cancels a waiting downgrade. To stop paying, cancel in open_billing_portal, which also takes effect at renewal. Needs the admin authority.

  • open_billing_portaladmin

    Create a Stripe Customer Portal link where a person updates the card, downloads invoices, or cancels. A cancel takes effect at renewal. Needs the admin authority and an existing billing account (start_checkout creates one).

  • list_sourcesany key

    List what this company has connected (Gmail or Outlook, Google or Microsoft Calendar, GitHub, GitLab, Linear, Jira, the CRMs, the transcript sources, Google Drive, Notion, Slack Connect and the RepoOps and SalesAsCode feeds), each with its state, when it last synced, any error code, its first run, and counts: for mail the external threads read and the internal threads skipped without being opened, for a calendar the external meetings stored, for documents how many are chosen and how many wait for an account, for Slack Connect the shared channels read and the internal ones skipped, and for every source the quotes stored from it. A source in needs_reconnect stopped syncing because the provider refused its grant; a person connects it again on /connect. Pasted transcripts are not listed.

  • disconnect_previewany key

    Count what disconnecting a source would delete, before anyone confirms: every quote that came from it, every assertion left with no quote from anywhere else (kept ones included), the messages waiting to be read, the threads and meetings recorded, and any work items. The record that decisions were made stays. Call this and show the numbers to the person before calling disconnect_source.

  • sync_source_nowpropose

    Fetch new mail, meetings, call transcripts, changed documents or Slack Connect messages for one Gmail, Outlook, Google Calendar, Microsoft Calendar, Fireflies, Granola, Zoom, Gong, Google Drive, Notion or Slack Connect source now instead of waiting for the sync sweep (every 15 minutes for mail and Slack Connect, hourly for a calendar and Drive, every 30 minutes for transcripts and Notion). Slack Connect still keeps to Slack's limit of one history call a minute outside the Marketplace. Spends up to 25 seconds fetching, then returns; the sweep carries on from where it stopped, and the extract sweep reads what was fetched. GitHub, GitLab, Linear and Jira arrive by webhook and need no sync; CRMs use sync_crm_now. A source in needs_reconnect must be connected again on /connect first.

  • disconnect_sourceadmin

    Disconnect a source and delete everything it contributed, in one transaction: its quotes, any assertion left with no quote from another source, its waiting messages, threads, meetings and work items, and its sync jobs. For Google, the grant is also revoked at Google when no other connection uses it. Returns the counts it deleted, which match disconnect_preview taken in the same transaction. Needs admin. Cannot be undone.

  • connect_transcript_keyadmin

    Connect a call transcript provider that works with a key the customer pastes: fireflies (an API key from Fireflies settings, Integrations, Fireflies API, any plan) or granola (a key starting grn_, Business plan or above). The key is checked with one list call, then stored encrypted; it is never returned or logged. The first pull reads every transcript from the last 90 days, a chunk at a time, and then every 30 minutes. Connecting the same key again replaces nothing but the stored copy. Zoom and Gong connect through OAuth on /connect instead. Needs admin.

  • add_drive_filespropose

    Record files a person picked in the Google Picker on /connect, so CommitOps reads them: Google Docs, PDFs and Word files, up to 10 MB each. Say what kind they are and, to find promises in them, which account they were written for. Each is read at once and again whenever it changes in Drive. CommitOps can open only files picked through its Picker; any other id is marked not_found.

  • set_documentpropose

    Say which account a connected document was written for, what kind it is, or who reads it. Naming an account lets CommitOps look for promises in it; marking it a questionnaire or RFP also sends its capability statements to the claim register. The document is read again on the next pass, which this call starts. Send account null to clear it.

  • remove_documentadmin

    Stop reading one Drive file or Notion page and delete everything it contributed: its quotes, any assertion left with no quote from elsewhere (kept ones included), and its claim surfaces. The rest of the source stays. For a Notion page, also stop sharing it with the integration in Notion, or the next pass finds it again. Needs admin. Cannot be undone.

  • connect_siblingadmin

    Connect a sibling product's feed. Makes an agent principal for it (named RepoOps or SalesAsCode, operated by you), its own source so disconnecting forgets what it sent, and a key returned once in this response. Paste the key into the sibling's settings; it then pushes to CommitOps over the API or MCP as that agent. RepoOps sends measured agent spend per merged change and roadmap slugs; SalesAsCode sends deals and the promises it found, which arrive as candidates. CommitOps works without either. One feed per product. Needs admin, and an owner.

  • record_work_costlink_work

    RepoOps only. Report what coding agents measurably cost for one pull or merge request, in cents: the metered spend of the agent sessions tied to that change. attribution says how they were tied: branch (the sessions ran on the change's own branch) or file_overlap (they touched the same files, and RepoOps rated the match strong). A weaker match, or a figure from a model rather than a meter, must not be sent; spend RepoOps cannot tie to a change stays unattributed and is never spread. Stored as cost_basis measured and never added to a modeled figure. Reporting again replaces the figure. A change CommitOps has not seen is mirrored from what you send.

  • record_work_slugslink_work

    RepoOps only. Say which roadmap items one pull or merge request belongs to, as slugs such as saml-sso. A promise carrying the same slug (set_roadmap_slug) is linked to the change at 0.90 by match pass 2, as a roadmap:saml-sso label would. The list replaces what you sent before for this change, so send [] to withdraw them; slugs from the change's own labels stay. A change CommitOps has not seen is mirrored from what you send.

  • record_dealpropose

    SalesAsCode only. Send one company and one of its deals, in the shape every CRM connector uses: the company's id in SalesAsCode, its name and website domains; the deal's id, name, amount in cents (null when unknown, never a guess), ISO currency, stage, open, won or lost, close date, renewal date and owner. The company links to the account CommitOps already has with exactly that domain, else becomes one; a domain shared by two accounts links to none. Stored with source crm, so it counts wherever a blocking promise waits on it. Sending the same deal again updates it.

  • configure_ssoadmin

    Set this workspace's SSO connection, replacing any before. SAML 2.0: pass protocol saml and the identity provider's metadata_url (public https) or metadata_xml. OIDC: pass protocol oidc, issuer (https), client_id and client_secret; the secret is stored sealed and never shown again. domains lists the workspace's own domains to bind; only addresses there sign in through it, and a domain may be bound by one workspace only. A new or changed connection is untested and not required until test_sso comes back good. People who sign in through it for the first time arrive as members with no authority. Pass remove true to delete the connection. Scale only. Needs admin.

  • test_ssoadmin

    Check this workspace's SSO connection: the bound domains, each SAML signing certificate's expiry and the metadata URL, or the OIDC discovery document. Returns a sign-in link, good for ten minutes; open it, sign in at the identity provider with an address at a bound domain, and when the answer comes back good the connection is marked tested and nobody is signed in. Requiring SSO waits for that. Scale only. Needs admin.

  • set_sso_enforcementadmin

    Require SSO for this workspace's bound domains, or stop requiring it. While required, Google sign-in is refused for addresses at those domains, a Google session at those domains stops on its next request, and a person who signed in with Google before moves to their SSO login, keeping their authority. Requiring needs a good test_sso first. Turning it off never waits on the plan. Scale only to turn on. Needs admin.

  • create_teamadmin

    Create a team by name, unique in the workspace ignoring case. Add people and agents with add_team_member and put accounts or assertions in it with set_team_scope. Creating teams changes nothing anyone sees until set_team_scope turns teams on. Scale only. Needs admin.

  • add_team_memberadmin

    Add a person or an agent to a team (by team id or name) with the authority it may use on that team's rows (propose, keep, verify, communicate, link_work, withdraw; never admin), or change that authority, or pass remove true to take them off the team. A member's own workspace authority still applies everywhere it can see; a team grant applies only to that team's rows, and acts through a signed-in session (a key carries the principal's own authority). Scale only to add. Needs admin.

  • set_team_scopeadmin

    Turn teams on or off for the workspace (enabled), and put an account (account_id) or one assertion (ref) in a team, or take it out with team null. An account's team covers every assertion on it. With teams on, someone who is not an owner sees only their teams' rows plus those no team holds, on every screen and through every tool. Off by default. Turning teams off never waits on the plan. Scale only otherwise. Needs admin.

  • export_audit_bundleadmin

    Build the audit export: every assertion this company has made (promises, claims and entitlements, every status), each with every quote it rests on (speaker, source, locator, said_at), every event in its history, every verification with checked_at, the work it links to, what the customer was told, and the deals waiting on it. One .tar.gz of JSON and CSV with a manifest listing a SHA-256 per file, signed with HMAC-SHA256 by a server key. Kept 7 days, then cleared. Up to 2000 assertions it is built now and comes back ready; above that it is queued and get_audit_export reports when it is ready. Scale only. Needs admin.

  • add_addonadmin

    Add the white-label promise page ($99 a month; it hides our mark on the customer-facing page) or extra workspaces ($149 a month each; each covers one more workspace you own with this plan) to the live subscription, as a Stripe subscription item prorated for the rest of the period. quantity is how many extra workspaces to add; the white-label page is one. Prices come from plan_grid. Scale is invoiced, so there it is a note to us instead. Needs admin.

  • remove_addonadmin

    Remove the white-label promise page, or some extra workspaces (quantity, default 1), from the live subscription, credited for the rest of the period. The promise page shows our mark again at once. Extra workspaces cannot drop below the number covered now; stop covering one with cover_workspace first. Needs admin.

  • cover_workspaceadmin

    Put another workspace you own on this workspace's plan, using one extra workspace this plan pays for, or take it off (covered false). A covered workspace gets this plan's tier and keeps its own people, keys and rows. It needs a signed-in person who owns both workspaces, so an agent key cannot do it. Needs admin.

Full input and output schemas: openapi.json. What the product does with your customers’ words: security.