https://mcp.attensira.com/mcp over Streamable HTTP. Every tool except the two that set up a new workspace takes an optional project; omit it and your credential’s own workspace is used. Each tool below says whether it is read-only, whether it spends credits (add_context does only with run: true, and answer_inbox_question only when it restarts a finished run), and whether it deletes data permanently. This page lists every tool with its parameters, defaults and return shape, grouped the way the server lists them.
The agents do the SEO work; the tools are how you, or the assistant you ask, steer it: read what happened, set what to aim for, answer what is waiting on a person, approve or decline what the agents propose. A tool never approves anything on its own reading of a row. Approvals and settings change on a person’s instruction.
Every tool has a twin in the REST API with the same payload, and each says which endpoint below, except the markets reads, which say MCP-only. Use MCP when an assistant is doing the work; use REST when your own code is.
Projects are read with list_projects and steered with steer_project; Projects over MCP describes both. Creating a project and changing its settings are in the dashboard only. A project’s runs and automations are ordinary sessions and automations, so list_sessions, get_session, list_automations and get_automation include them.
Words that collide: project and id
On every tool, project is the workspace: one domain, with its own prompts, competitors and plan. It has meant that since the first tool shipped, and renaming it would break every client already calling.
A project in the product’s sense, an area of work with its own crew of agents, is a work area on the wire. list_projects and steer_project take its id as id, and every payload that points at one, a goal or a deliverable, carries it as work_area_id. Passing a project’s id as project is refused with a message naming the mistake.
Which credential each tool needs
A workspace API key is minted as read or read and write. Read tools work with either; the tools in the left column need a read-and-write key. Calling one with a read key returns403 with type: "forbidden" and the challenge WWW-Authenticate: Bearer error="insufficient_scope", scope="write" — the credential is valid, it simply may not do this. Scope is fixed when the key is minted and cannot be widened: mint a read-and-write key and swap it in.
An OAuth connection always carries read and write. Approving a client grants it your organisation, and there is no read-only consent — the scopes in the token are the authorization server’s own (openid, profile, email, offline_access, user:org:read), none of which names an Attensira permission. Restrict a connected assistant by what you ask it to do, or by the tool allow-list your client offers, not by scope.
get_account returns the scopes in force, so call it first from a new integration rather than discovering the gap on a failed write.
One tool is key-only:
get_ai_traffic_install hands back your workspace’s signing secret, and a signed-in connection is refused there on purpose — a consented OAuth token must never be able to read one credential out and turn it into another. Call it with an API key.What your assistant does shows its name
Work an assistant starts is labelled with it in the app. A proposal that came out of anask from Claude reads “via Claude” in the Inbox, and so does the work a project’s crew does in answer to a steer_project post sent from Claude. The MCP server passes on the name your client reports for itself; Attensira shows it only when it is one it recognises (Claude, Claude Code, ChatGPT, Cursor, Codex, VS Code), and otherwise writes “via your assistant” rather than a name it cannot vouch for. The label is display only. It grants nothing and changes nothing about what the call may do.
Before you start: what costs money and what destroys data
These tools spend credits or destroy data. Nothing else on this page produces a bill or erases history.start_workspace and confirm_setup never charge anything. confirm_setup hands back a checkout link, and the person pays in their own browser.
The
get_analytics area values for a topic rollup and a per-surface rollup are topic and platform. A platform is a stable identifier for an AI answer surface (ChatGPT, Perplexity, Google AI Overviews, Claude, Gemini) that survives the underlying model being replaced, so two windows a year apart stay comparable on the same key. The older wire words group and engine are no longer accepted.Reading what comes back
Every rate is{value, n} and every delta is {value, real}. A value of null means not measured; 0 with n > 0 is a measured zero. Per-platform metrics live in a platforms map keyed by platform, and each entry carries {tracked, readable}: tracked: false means your plan does not include that platform, so it was never queried, and readable: false on a tracked platform means nothing came back in the window that could be scored. Treating either as 0% invents a failure that did not happen.
Every ranked list carries id and label on each row, so the row can be handed straight to the detail tool that takes the id. For the full treatment of null against zero, small n, and when a delta is worth acting on, read Reading the numbers.
Find and measure
Ask these tools the questions you would ask an analyst: “which prompts am I losing on Perplexity?”, “what changed since last week?”, “which sources decided the answers?”, “does anyone cite our pricing page?“.search
Read-only. No credits. REST:
GET /v1/search.
Returns
total, has_more and hits. Each hit carries type (prompt, page, automation or session), id, title and, where there is one, a snippet. A hit whose label starts with the query ranks above one that merely contains it; at equal footing prompts come before pages, then automations, then sessions. Every string on a hit is capped at 400 characters, so a complete model answer can never come back through search — for the answers themselves, use answer_history or answer_slice.
Page on has_more. total counts what matched up to the session-search ceiling, so it is a floor rather than a grand total.
get_analytics
Read-only. No credits. REST:
GET /v1/analytics/{area}.
The envelope is
{area, days, window, order, filter, rows, total_rows, truncated} plus the area’s own headline numbers. total_rows is how many rows survived the filter and truncated whether limit cut them, so a short list can be told from a cut one. Every row carries id, label, the rates that apply to the area and, where the area has one, a platforms map.
Response — area: prompt
area: "bot" rows carry visits, pages, purpose_mix, last_seen (null when it never came) and agents instead of the rate fields, and answer with a note when no edge collector has ever reported — zero rows there means uninstrumented, not uncrawled.
area: "visibility" returns share of voice per platform — the fraction of runs on that platform that named you, not a share of a category that sums to 100%. Competitor rates (area: "competitor") use the same denominator as yours, so they do not sum to 1 either.deciding_sources
Read-only. No credits. REST:
GET /v1/deciding-sources.get_analytics with area: "source", which ranks by citations, this ranks by influence over a decision. See Deciding sources.
Returns
groups, most influential first, one per prompt × platform × surface. Each group carries a label in words, n (successful answers read), present (whether any source in the top ten is yours), a recommendation, and sources ranked by weight: domain, url (the exact page when one carried it, else null), citations, share, present, and action — the next move in words, such as “get listed” or “fix your own page”.
win_plan
Read-only. No credits. REST:
GET /v1/win-plan.deciding_sources says which those are.
Returns
prompt, n, evidence (measured, published or hypothesis), steps in order — each with a title, a why sentence built from the readings, a target page or domain (or null when it is your own site generally), the platform it acts on and a credits_estimate — plus rereads_at and credits_estimate for the whole plan. rereads_at is the day the next booked re-read for that prompt is actually read (see Before and after). Nothing here claims movement: the footer uses the no-change wording until the workspace has a re-read that came back moved.
get_prompt
Read-only. No credits. REST:
GET /v1/prompts/{prompt}.
Returns
id, text, topic (null when unfiled), country (null for the workspace default), visibility, citation, delta, position, answers_read, failures, a platforms map, competitors (each with name and a rate on this prompt’s own answers), sources (each with url, domain and a rate), and why — the standing in sentences, each built from a number on the same response. Passing exact text saves a search round-trip when you already know the wording; inexact text will not match.
get_page
Read-only. No credits. REST:
GET /v1/pages.get_analytics with area: "bot"; a model can only cite a page it has fetched, so that is worth checking before rewriting content.
Returns
url, title (null when it could not be read), citations and citation as a rate on total_answers, a platforms map whose entries carry the page’s citation rate on that platform’s own answers, prompts — each with id, text, citations and a rate on that prompt’s answers — and in_sitemap. The delta is {value: null, real: false}: the page fold has no earlier window to compare against, and the contract’s word for that is “no basis”, not a number.
query_evidence
Read-only. No credits. REST:
POST /v1/evidence/query.get_analytics for the ready-made boards and query_evidence when the cut you need is not one of them.
“Time” is
day or week; “prompt fields” are topic, prompt, intent, stage, persona and state. page is one of your own pages as Google and your traffic record it; url is a cited page, anybody’s. The Google metrics are explained in Google search.
A question with no honest answer is refused before anything is read. The tool returns an error (status 400) whose message names the problem and says what to ask instead:
A question too broad to answer in time is refused with status
422 and a message that says what to narrow, never answered with whatever rows arrived first.
Response — metric: share_of_voice, group_by: ["engine"], days: 30
valueis in the table’sunit:share(0 to 1),position,countorweight.nullmeans unmeasured, and a gap names why;0is a measured zero.nis on every row: successful answers for an answer rate, placed answers for a position, citations for a source share, impressions for Search Console, readings for rank tracking, the count itself for a count. Read it before the value.labelsgives the readable name where a key is an id: a topic’s name, a prompt’s text.refnames the records the row was counted from, at most five ids. For answer metrics they are prompt ids, whichanswer_historyopens.gapslists everything the answer could not measure, as{key, reason}: a span of days before your first tracked prompt (before_first_reading), a source that is not connected, days not recorded yet, a row with no value. An empty list is the claim that nothing is missing.day_basissays which calendar the day labels count in:slot_day,search_consoleorutc. See Google search.truncatedistruewhen there were more rows thanlimit. Without a time dimension the strongest rows are kept; with one, the newest whole days or weeks.
topic uses the topic each prompt is filed under now, so moving a prompt regroups its whole history.
The receipts
The numbers above are folds over stored answers. These tools hand back the rows themselves, verbatim, which is whatrecord_observation cites and what a person asks for when a number looks wrong. Their REST twins live under /v1/memory/.
answer_history
Read-only. No credits. REST:
GET /v1/memory/answers/history.get_prompt.
Returns
answers, readings (on this page), has_more and next_cursor (null at the end). Each answer carries reading_id and sample (its index within the reading), prompt_id and prompt, platform, surface (consumer or api), country, day, answered_at, text verbatim, text_bytes, truncated, mentioned, cited_own_domain, citations in order (url, domain, position, and context: the sentence of the answer that carries the link, "" when the text does not mention it, null when it was never looked for; see Citations and sources), competitors_named, position (your place among the names you track, absent when you were not named), stance (positive, neutral, negative, none or unscored; see Sentiment), brands (the full brand order, each brand with its own stance), claims (the factual statements the answer makes about a brand, quoted), and failed. brands and claims are null until the answer has been read for them and [] when it was read and holds none. Answers over 8 KB are cut on a character boundary and flagged truncated: true, with text_bytes carrying the full length. A failed sample is listed with failed: true and an empty text, never dropped: a bad week must not look like a quiet one.
answer_slice
Read-only. No credits. REST:
GET /v1/memory/answers/slice.
Same row shape and the same 8 KB cut as
answer_history.
Reading terms and answer terms. platforms, country, topic_id, prompt_ids and the dates select readings. The rest are answer terms, and they must all hold for one sample: an answer that named the rival and a different answer from the same reading that cited the domain do not match together. When an answer term is set, only the samples that satisfy every term come back, and failed samples are excluded, because a sample that did not happen cannot be judged. With only reading terms, every sample of the selected readings is returned, failed ones flagged.
none and unscored are different. none is an answer we scored that took no stance on your brand. unscored is an answer that has not been scored at all. Neither is neutral.
text_contains reads every answer in the window, so without topic_id or prompt_ids the window is at most 30 days; a wider one is refused with what to narrow. For answers about a subject rather than a phrase, use the agent’s recall. A slice too broad to read in one go is refused with what to narrow: a shorter window, prompt_ids or topic_id, a platform, or a shorter phrase.
citation_timeline
Read-only. No credits. REST:
GET /v1/memory/citations/timeline.get_analytics with area: "source" ranks, kept day by day.
Returns
domain, url (set when the question was one page), total, prompts, and series — one entry per platform, most cited first, each with points for every day the window touches: day, citations, mean_position (null when nothing that day carried a position) and prompts. A zero day is a real zero.
page_history
Read-only. No credits. REST:
GET /v1/memory/pages/history.
Returns
url (normalised), known (for your own page, whether it is in the workspace’s inventory; for a watched page, always true), versions and snapshots oldest first — each with id, first_seen_at, status, title, description, word_count, json_ld (present, absent or not_captured), canonical, robots, changed_bits and changes, the fields that moved since the version before (field, from, to). Metadata on a version taken before it was recorded reads not_captured, and is never reported as a change. Any other page on another domain is refused with a 404.
Track
These tools change what gets measured. Reach for them when the answer is “we are not tracking the right things”: “start watching these five buying-intent prompts”, “stop wasting a slot on that one”, “add the competitor who keeps showing up in answers”.add_prompts
Adds one or more prompts to the workspace. From the next daily run, each new prompt is read across every platform your plan tracks. There is noplatform argument — which surfaces a prompt runs on comes from the plan, not from the caller.
Returns
added — every prompt now being tracked, with id and text. A prompt that was already tracked comes back in added too, with its existing id, so a repeated call is idempotent all the way out; skipped is empty today. credits_spent and credits_remaining are null: tracking is charged as the prompts are read, not on this call. Your plan caps how many prompts you can hold at once, and a paste that would exceed it is refused with a 409 naming how many slots remain — see Plans.
remove_prompt
Stops tracking a prompt and frees its slot. Confirm the prompt withget_prompt first — this cannot be undone.
Returns
id and removed: true. No new readings are collected for that prompt afterwards, so any trend line for it ends on the day you remove it.
add_competitor
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/competitors.
Returns the competitor:
id, domain, name. Competitor share of voice uses the same denominator as your own — successful runs naming the brand over all successful runs — so adding a competitor never changes your numbers.
remove_competitor
Stops scoring a rival. Past readings keep what they already recorded, so history does not move — the rival simply stops being scored from here on.
Returns
id and tracked: false.
Inbox
Everything waiting on a human. Natural questions here sound like “is anything blocked on me?”, “what should I deal with first?”, “why has nothing happened since Tuesday?”, “I connected GitHub — clear that off my list”, “tell it the launch is on the 14th”. See Inbox for what ends up there and what each act does. Each row’stype says which tool acts on it, and its ask_kind says what it asks of a person:
Approve, answer and decline only on the customer’s instruction, never on your own reading of a row. Every act returns
next_item_ref when something else is waiting: the row the ranking puts first now, readable with get_inbox_item.
list_inbox
Read-only. No credits. REST:
GET /v1/inbox.
Each row in
items carries type (work_item, ask or task), id, ref, ask_kind (approve, answer, do or info), title, reason, session_id and updated_at, plus ask_id on an ask. A task row also carries what it asks: task.question (prompt, up to six options, and fact_ref when it fills a profile field), task.steps (numbered steps, each with an optional value to copy), and task.verification while a Done is being checked. list_approvable is true only on a proposed change that may be approved without opening it: one whose effect can be undone and that is classed safe.
view: "triage" is the Inbox’s own ranking, the same one the dashboard, the morning brief and the daily email read:
Response
top holds at most three decisions; everything after them is in sections, grouped by ask_kind. total_open counts rows and decisions counts decisions, the number the dashboard’s badge shows. merged_count is how many sightings are not shown as rows of their own: repeats a row absorbed, and duplicates folded into another row.
Worth calling before concluding the agents are idle. A workspace with rows here is one where nothing is moving until somebody answers.
get_inbox_item
Read-only. No credits. REST:
GET /v1/inbox/items/{ref}.
Returns the row with
type, id, ref, title and the task or work_item behind it. To approve a specific version, copy work_item.change.proposal.captured_at from here into approve_work_item. A row the duplicate check folded into another carries merged_into, the ref of the row to read instead; one it only suspected carries possible_duplicate_of and is not hidden. A malformed ref is 400; a ref from another workspace is 404, the same as one that names nothing.
answer_inbox_question
Answers a task whoseask_kind is answer with the person’s words, never your guess. The answer is saved to Company facts — the business profile field the question names, or a stated fact every later run reads — the row closes, and the run that asked is put back to work.
Send
answer or option, not both. Returns the closed task, fact (where the answer went: {kind: "profile_field" | "stated_fact", ref}), resume and next_item_ref. resume.status says what happened to the run:
A second answer to the same row is
409. A row that is not a question is 400.
resolve_inbox_task
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/inbox/tasks/{id}/resolve.done means the thing the agent needed has actually been handled — the integration connected, the record added — not that you plan to handle it. Nothing is queued to run when you send it.
A task that carries a check (a DNS record, a connection, a line on a page) is not closed by done: it stays open with verification.status: "pending", moves to in_flight, and closes on its own when the check passes. If the check still fails after its retries, the row comes back to needs_you with verification.failure saying why; sending done again checks again. Snoozing a row while its check is pending is 409. Returns the task and next_item_ref.
approve_work_item
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/inbox/{id}/approve.type is work_item is approved this way.
Idempotent: approving twice approves once, so a retry after a timeout is safe. Approving is the customer’s decision to make, not one to infer from the row. Returns the work item and
next_item_ref.
edited_value is accepted only for an article, a LinkedIn post or a rewritten passage that is still waiting, and is refused with 400 for anything else (a fix is edited in its pull request). The edited change keeps the agent’s original, and is always a claim: it waits for a person in every approval mode and never goes out on its own. An edit that adds or changes code is refused with 422, and nothing is approved. An edit is checked against the workspace’s rules like any draft; one that breaks a rule is 409.
decline_work_item
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/inbox/{id}/decline.
The reason is required and is the point of declining rather than ignoring: it is what stops the same proposal coming back.
wrong means the proposal is incorrect, not_now right idea wrong time, already_done handled elsewhere, never_touch do not propose this again for this page or topic. The reason and note are kept on the item and in its activity. Returns the work item and next_item_ref.
approve_ask
Needs a read-and-write key. The call itself spends nothing; the run it lets go carries on as before. REST:
POST /v1/inbox/asks/{id}/approve.type is ask and whose ask_kind is approve.
An ask is never edited: the yes is bound to the exact arguments the run asked about. Returns
session_id, outcome (allowed-once) and next_item_ref. The run is back on the queue and has not made the call yet; poll it with get_session. A session in another workspace is 404; an ask already answered, expired, or no longer the one the run is waiting on is 409. An ask whose ask_kind is answer is answered in its session, not here.
decline_ask
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/inbox/asks/{id}/decline.
Returns
session_id, outcome (rejected) and next_item_ref. Same 404 and 409 as approve_ask.
Automations
Automations are scheduled work: a weekly digest, a recurring audit, a check that runs after every deploy. Natural questions here sound like “email me a summary every Monday”, “what is already scheduled?”, “run last week’s report again now”.list_automations
Read-only. No credits. REST:
GET /v1/automations.automations: each with id, name, instruction, trigger, allowed tools, status (active, paused, or done for a once that ran), timezone, run_at_minute, run_on_weekday and event_types where set, and last_run_at (absent when it has never run). Takes no parameters.
Paused and retired automations are always listed. One the product paused on its own (for example a Daily check-in retired by detection) carries retired_reason and retired_at. next_run_at is null for event automations.
get_automation
Read-only. No credits. REST:
GET /v1/automations/{id}.latest_run ({id, status, state}, or null when it has never run) — so “did my Monday report run?” costs one call, not two. A paused or retired automation is returned like any other, with retired_reason and retired_at when the product paused it.
create_automation
Needs a read-and-write key. Creating costs nothing; each run it triggers does. REST:
POST /v1/automations.
Returns the created automation with its id.
next_run_at is null for an event automation. Creation is free; every run spends credits like a manual run.
run_automation
Triggers an automation immediately, outside its trigger. Returns a session handle —session_id, status and poll_after_ms — to poll with get_session, not the finished result.
delete_automation
Permanently deletes an automation and its schedule — this cannot be undone. Its past runs are sessions and survive. Confirm it withget_automation first.
Returns
id and deleted: true.
update_automation
Needs a read-and-write key, but does not spend credits. REST:
PATCH /v1/automations/{id}.
Pausing is how a schedule is stopped without losing it — deleting is the one that cannot be undone. Returns the automation in the shape shown under
list_automations.
Agent
The agent tools run a chat inside your workspace, with your tracking data in reach. Use them for questions that need reasoning across several slices — “why did our share of voice drop on Perplexity last week?”, “draft a plan for the three prompts we lose most” — rather than for numbers you can pull directly withget_analytics.
ask
Open-ended investigation the other tools cannot answer — why a prompt is losing, what to change on a page — run by an agent that crawls pages, audits them as a model sees them, and searches the web. Tryget_analytics, deciding_sources, win_plan, get_prompt or get_page first: those are free and immediate, this costs credits and takes time.
Returns
session_id, status (running at first — that is the success case, not an error), answer (null until complete) and poll_after_ms. Wait that long, then poll get_session with the returned id until status is complete.
The agent runs on an agent model — the LLM powering the chat. That is a different thing from a tracked platform, which is the answer surface Attensira reads on your behalf. Changing your agent model does not change what is measured.
get_session
Read-only. No credits. REST:
GET /v1/sessions/{id}.ask or run_automation: its status and, once finished, its answer. Use this to poll async work.
Returns
id, status (complete, running, failed), state (the engine’s own finer word — a run parked on a question for you reads awaiting_person under a running status), answer (the agent’s last message once complete; null while running or on failure), and events — present only when requested, each with a type such as tool.start or text.delta and the fields of that event — the way to see which tools the agent called and with what arguments.
Sessions
A session is one piece of agent work: anask, an automation run, a chat or the set-up run. These tools list them and act on them. REST twins are on Sessions.
list_sessions
Read-only. No credits. REST:
GET /v1/sessions.
Returns
sessions, each with id, title, origin, status, state, automation_id, created_at and ended_at.
cancel_session
Needs a read-and-write key. No credits; works on a spent balance. REST:
POST /v1/sessions/{id}/cancel.delete_session
Permanently deletes a finished session and its trace. A running session is refused with a409; cancel it first.
Returns
id and deleted: true.
add_context
Needs a read-and-write key. Costs credits only with
run: true. REST: POST /v1/sessions/{id}/context.
Pass
text, urls, or both. A cancelled session refuses new context. Returns session_id and status.
Account and settings
get_loop_health
Read-only. No credits. Works on a spent balance. REST:
GET /v1/loop-health.working, idle or blocked, with the reasons, and a day-by-day record of readings, automation runs and skips, findings, work produced, approvals pending, pull requests opened and re-reads due. Call it first when asked why nothing happened. See Loop health.
Returns
status, reasons and days. The per-day fields are documented under GET /v1/loop-health.
get_account
Read-only. No credits. REST:
GET /v1/account.project parameter takes, to confirm which workspace the credential points at, and before reporting any per-platform number: platforms is the authority on which platforms were queried at all, so a platform absent from it was never measured rather than measured at zero.
Returns org (id), project (id, name, domain — the workspace this call resolved to), workspaces (every workspace in the org, each with id, name, domain), credits (available, available_usd, held_units; absent when the balance could not be read, never a zero standing in for an outage), scopes — what this credential may do — and platforms. work counts this month’s work by type: committed (a null count is a type not tracked yet, not zero), delivered, waiting_on_you (held for a person, which is not a shortfall) and the month’s cap_usd. When it could not be read, work is null and work_unavailable_reason says why.
project is null when the organisation has several workspaces and the call named none. That is the answer rather than an error: workspaces carries the ids, and every other tool then needs an explicit project. platforms is empty in that case too, because platforms belong to a workspace rather than to the organisation. It answers without a workspace, so it is always the right call when another tool asks you to name one.
get_costs
Read-only. No credits. Works on a spent balance. REST:
GET /v1/costs.
Returns
period, currency (usd), as_of, workspace_id (the workspace named, or null for the organisation), and:
committed and credited_back_usd are the organisation’s even when project names a workspace: one budget commits work for every workspace in it.
The budget, its pace, the caps, the balance and how it is funded are not returned. They are set by a person in Settings → Billing, and no tool can read or change them. Read the balance with get_account. When the work needs more room, tell the person: only they can raise a budget or a cap.
The REST twin is GET /v1/costs.
get_brief
Read-only. No credits. REST:
GET /v1/brief.
Returns
date, edition (daily, or weekly for the Monday note), subject, text (the brief itself, as the email body), order (the weekly sections in the order the text reads them: shipped work and early signals before citations and goals), and sections, among them needs_you (at most three rows, each with an inbox id and title), goals (each goal’s name and pace) and the citation wins and re-reads. A section that is absent is not wired yet, never a zero. It reports counts, never a day-over-day comparison, until a seven-day window exists, and says “no proven change yet” until a verified re-read.
get_ai_traffic_install
Read-only. No credits. Key-only. REST:
GET /v1/ai-traffic/install.connect_github
Needs a read-and-write key, but does not spend credits. REST:
GET /v1/github/install-url.url — the App install link, and nothing else. GitHub hands back a user-to-server code only to a browser that completes the install, so the connection exists only once a person has followed the link. Each call mints a fresh single-use link, so fetch a new one rather than reusing an old one.
update_settings
Needs a read-and-write key, but does not spend credits. REST:
PATCH /v1/settings/agents.
At least one field is required. Returns the settings in force:
unattended_mode, the effective act_path_allowlist, act_paths_are_default, publish_without_approval and send_without_approval.
list_wins
Read-only. No credits. Works on a spent balance. REST:
GET /v1/wins.named and linked, and never the same kind twice. Only the first naming (or link) can be a win: one that came before those three days of reading is not, and no later answer of the same kind on that prompt and engine becomes one.
A win is a first since we started reading that prompt. It is not evidence that any work caused it. Say it the way sentence does, and keep “since we started reading” when you repeat it.
Takes no parameters besides project. Returns at most the 50 most recently found wins. Dismissed wins are left out.
Returns wins and unseen. Each win carries:
unseen counts every win in the workspace that nobody has opened in the dashboard and nobody has dismissed, including any beyond the 50 listed. Reading the list through this tool does not mark a win seen.
Response
Memory
Two writes into what the workspace knows about itself. See Knowledge and skills and What we know.record_observation
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/observations.
Ids are resolved against the workspace before anything is stored, so a guessed one is refused rather than remembered. Returns the observation with its
id, statement and n.
write_skill
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/skills.
Returns the skill with its
id, title and kind.
Set up a workspace
These tools let a person’s assistant set up a business from its domain: the agents draft it, the person decides, and the person pays in their browser. Neither takesproject — there is no workspace to select yet — and neither can charge anything. Sending project anyway is refused with the reason.
The order is: start_workspace → show the person what was drafted and ask → confirm_setup with what they kept → give them the checkout link → call start_workspace again until it reads active. The first recipe walks through it.
start_workspace
Needs a read-and-write key or a signed-in connection. No charge. REST:
POST /v1/onboarding/workspace.
Returns
workspace_id, domain, status, reason (why it needs input, else null), next (what to do now, in one sentence), and the draft: profile (facts read off the site, each with the page it came from, or a question to ask when nothing was found), competitor_suggestions, competitor_question, platform_suggestions, proposed_goals, plans and the budget range.
status moves in this order:
A signed-in connection works before there is any workspace: the first call sets up your organisation. An account can hold one workspace waiting for payment at a time: starting a second domain before the first is paid is refused, naming the one to finish.
confirm_setup
Needs a read-and-write key or a signed-in connection. No charge. REST:
POST /v1/onboarding/workspace/{id}/confirm.
Returns
workspace_id, status, checkout_url, requires_browser (always true), expires_at (null unless the payment provider states one), plan, budget_consent and next. budget_consent.line is the top-up rule the person agrees to by paying, in words: relay it as written. budget_consent.monthly_budget_usd is the budget that was agreed; it is null only for a rule agreed before budgets were kept apart from caps. A person who already has a card on file is sent to the billing page to confirm the plan in person, because an assistant has not been given that yes. An account that already pays for a plan has nothing to check out, and the call says so.
Goals
What the agents aim at. A goal is a metric, a target and a date; the daily readings say whether the work is on pace.get_goals
Read-only. No credits. REST:
GET /v1/goals.goals, each with id, name, metric and metric_label, unit, direction, baseline and current (each {value, n}; a null value is not measured yet, not zero), target, target_date, pace (state is ahead, on_pace, behind or unmeasured, with the expected value and a reason), sentence (the standing in words), work_area_id and work_area_ids (the projects it drives), status and created_via. The pace verdict is Attensira’s: quote it rather than comparing the numbers yourself.
set_goal
Needs a read-and-write key, but does not spend credits. REST:
POST /v1/goals and PATCH /v1/goals/{id}.id. On a change, fields you omit are left alone. Set goals on the person’s instruction.
Returns the goal’s
id. A change with nothing in it is refused rather than reported as a change.
Projects
A project is an area of work with its own crew of agents. The crew plans and does the work; a person steers it. Remember that on the wire a project is a work area, andproject is the workspace.
list_projects
Read-only. No credits. REST:
GET /v1/work-areas and GET /v1/work-areas/{id}.id, every project in the workspace. With id, one project and its latest feed.
The list returns
projects, each with id, name, description, status, team (each crew member’s role, name and status_line), goal_id and goal_text, unread, needs_you, live, autonomy, budget_cap_usd (the project’s monthly cap, null when none is set) and last_activity_at. One project adds its direction (what people have told it, word for word), triggers, automation_ids and feed: the latest posts, each with kind, text, at, because and its author.
steer_project
Needs a read-and-write key. Posting is free; the crew’s reply is an agent run and spends credits. REST:
POST /v1/work-areas/{id}/steer.
Returns
ack (the sentence to tell the person), feed_item_id, run_id (the run answering it, null when it could not start, with reply_error saying why) and plan_change, which is always null: a steer changes no plan by itself, and each change the crew makes lands in the feed as its own post. replayed is true when the key named a post already sent, and nothing was posted again.
Deliverables
list_deliverables
Read-only. No credits. REST:
GET /v1/deliverables.
Returns
deliverables and next_cursor (null at the end). Each deliverable carries id, type, title, work_area_id, location (provider, label and url: the pull request, CMS draft or post where it lives), status and status_label, result, approved_by (a name), run_id (the session get_session reads), run_url (the replay at the step that made it), dashboard_url, created_at and shipped_at. result is null when there is nothing to measure yet; otherwise it has a state, a label and a verdict that is null until a re-read reached one.
Reports
get_report
Read-only. No credits. REST:
GET /v1/reports/latest.
Returns
id, title, cadence, period, facts (each counted over its own n), movement_proven, not_read (what the report could not read), markdown, published_at, and share_url with share_expires_at when the report is shared. Through MCP the markdown is capped at 16 KiB and truncated says when it was cut: check it before quoting the end of a report, and send the person to the report page for the whole of it. Quote the facts as they are rather than recomputing them. See Client reports.
Markets and brand family
Which countries and languages the workspace is read in, and which domains and names count as the brand. Reading both is free. Changing either is the person’s, in the dashboard: more markets means more AI responses a month, and a property changes what counts as “you” in every number.get_markets
Read-only. No credits. MCP-only.
markets and support. A platform that cannot be located in a market is unsupported there, and is not read in it: that is not measured, never zero. To compare markets, call query_evidence with group_by: ["country"].
preview_markets
Read-only. No credits. MCP-only.
Returns
responses_per_month for the organisation and workspace for this workspace alone, each now and after the change, the plan’s monthly allowance, and over_by: how many responses a month the change lands over the allowance, 0 when it fits. overage_policy says what happens past the allowance.
get_brand_family
Read-only. No credits. MCP-only.
properties, each with a status of proposed, confirmed or rejected. Only confirmed properties count as the brand in the numbers. For a number per property, call query_evidence with group_by: ["property"].