Skip to main content
The Attensira MCP server serves its tools at 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 returns 403 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 an ask 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.
run_automation accepts an idempotency_key. Pass one on every call. It maps to the Idempotency-Key header upstream, so a retried or duplicated call does not produce a second billed run.
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?“.
Read-only. No credits. REST: GET /v1/search.
One search across the workspace’s prompts, pages, automations and agent sessions. Use it to locate something by wording when you do not have an id — a prompt that sounds like the one you have in mind, the page you half remember the title of. 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 main measurement tool. One call returns a ranked slice of your tracking data for a window. 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.
Which pages and domains actually decided the AI answers — the listicles, reviews and docs the models leaned on — whether you already appear on each, and the next move for each. Unlike 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.
The plan for winning one tracked prompt: what is deciding the answer today, what to change, and in what order. Ask for a prompt the workspace is losing — 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}.
Everything recorded for one prompt: where it is filed, its rate per platform, and who was named and cited instead. 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.
How one page performs in AI answers: its citation rate on every answer sampled, per platform, and the prompts whose answers cited it. For whether AI systems are fetching the site at all — as opposed to citing it — call 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.
Your own data question as a table: one metric, grouped by up to two dimensions, filtered, over a window. “Share of voice by engine and week”, “Google clicks by page”, “wrong claims by topic”. It reads the same stored days and folds them the same way as the dashboard boards, so the numbers match what the dashboard shows for the same window. Use 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
  • value is in the table’s unit: share (0 to 1), position, count or weight. null means unmeasured, and a gap names why; 0 is a measured zero.
  • n is 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.
  • labels gives the readable name where a key is an id: a topic’s name, a prompt’s text.
  • ref names the records the row was counted from, at most five ids. For answer metrics they are prompt ids, which answer_history opens.
  • gaps lists 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_basis says which calendar the day labels count in: slot_day, search_console or utc. See Google search.
  • truncated is true when there were more rows than limit. Without a time dimension the strongest rows are kept; with one, the newest whole days or weeks.
Grouping by 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 what record_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.
Every sampled answer to one tracked prompt, verbatim and newest first, with citations and reading ids — the receipts behind 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.
Every answer matching a predicate, verbatim. Terms AND together and select the sample; at least one is required. 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.
One domain’s or one page’s citations per day, per platform, with mean position and how many prompts cited it — the same rollup 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.
One page’s versions: every version captured, when, and what changed between them. It covers the workspace’s own pages and the cited and competitor pages it watches. Use it before claiming a page changed. 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

Costs credits. Needs a read-and-write key. REST: POST /v1/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 no platform 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

Destructive. Needs a read-and-write key. REST: DELETE /v1/prompts/{prompt}.
Stops tracking a prompt and frees its slot. Confirm the prompt with get_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.
Tracks a competitor domain so it is scored alongside the project in competitor analytics. It does not create new readings, so it costs nothing. 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

Destructive. Needs a read-and-write key. REST: DELETE /v1/competitors/{id}.
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’s type 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.
Everything waiting on a person: approvals the agent stopped for, questions, work it could not finish alone, failed automations, and approvals that expired unanswered. 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}.
One row by its ref, in any state, in full: the whole proposal a work item would make, the question a task asks and its answer once given, a done row as done. 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

Needs a read-and-write key. Costs credits when the run that asked had already finished, because it starts a new turn on the answer. REST: POST /v1/inbox/tasks/{id}/answer.
Answers a task whose ask_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.
Closes a task the agents raised. 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.
Says yes to a work item the agents stopped for, and lets them carry the change out — as proposed, or as the person edited it. Only a row whose 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.
Says no to a work item, with the reason why. 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.
Allows a paused run, once, the exact call it stopped to ask about: a row whose 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.
Refuses the call a paused run asked for. The run reads the reason and note first, then carries on without the call. 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.
Lists every automation in the workspace as 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}.
Full definition for one automation, with its most recent run inline as 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.
Defines a new automation that runs an instruction on a trigger. With no trigger it runs daily at 09:00 in the workspace’s time zone. 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

Costs credits. Needs a read-and-write key. REST: POST /v1/automations/{id}/runs.
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

Destructive. Needs a read-and-write key. REST: DELETE /v1/automations/{id}.
Permanently deletes an automation and its schedule — this cannot be undone. Its past runs are sessions and survive. Confirm it with get_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}.
Changes one automation in place — a partial edit. A field you do not pass is left alone, so pausing an automation cannot quietly rewrite what it does. 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 with get_analytics.

ask

Costs credits. Needs a read-and-write key. REST: POST /v1/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. Try get_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}.
Fetches a session started by 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: an ask, 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.
Sessions, newest first. Use it for “what is running right now?” or “what ran since Monday?”. 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.
Stops a running session before its next step. Credits already spent stay spent. Safe to repeat: if the run already finished, it returns that real ending unchanged.

delete_session

Destructive. Needs a read-and-write key. REST: DELETE /v1/sessions/{id}.
Permanently deletes a finished session and its trace. A running session is refused with a 409; 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.
Gives a session text or links it cannot find itself, as a message in its thread. 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.
Whether the workspace’s loop is 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.
Returns the org, every workspace you can reach, the one this call resolved to, the credit balance, which platforms that workspace tracks, and what this credential may do. Takes no required parameters. Call it first from a fresh integration — to collect the ids the 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.
What a UTC month has cost, in US dollars: the total, a month-end forecast, where it went, and the work the budget committed us to against what was delivered. The same figures as the Costs page. Call it when asked what Attensira cost this month, or what a client’s workspace spent. 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.
The same brief the morning email carries: the artifact of the day, what needs a person, counts for the window, and what re-reads when. See The morning 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.
Returns everything needed to start sending AI-crawler hits to Attensira: the ingest endpoint, the HMAC signing secret for your workspace, the signature header name, the replay window, the daily cap, and a copy-pasteable edge worker. Takes no parameters. Call it when AI traffic is empty and you need to know how to send us any. The signing secret is derived from the workspace id, so it is stable and can be shown again — unlike your API key, which is displayed exactly once. Because the response carries a secret, a signed-in OAuth connection is refused here with a message saying so; use an API key.

connect_github

Needs a read-and-write key, but does not spend credits. REST: GET /v1/github/install-url.
Starts connecting a GitHub repository: returns the install link for the Attensira GitHub App, scoped to this workspace. Call it when a fix needs a pull request and the workspace has no repository connected. Takes no parameters. Returns 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.
Sets how far a run may go on its own, and which paths act mode may touch. Absent fields are left alone. This is the customer’s decision: change it on their instruction, never to finish a task. See Approval. 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.
The workspace’s wins, newest first. A win is the first time an engine named your brand, or linked to your site, in an answer to a prompt that does not name your brand itself, after we had read that prompt on that engine on at least three earlier days with a successful answer and none of them did the same. A failed read counts toward neither half. A prompt and engine pair can give one win of each kind, 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.
Writes down something durable about this workspace so every future run starts knowing it — a pattern across answers, a source that keeps deciding. 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.
Records a rule this workspace wants followed — how to name things, a claim never to make, a procedure. Every future answer and draft obeys it. Write one the moment a customer states a preference as a rule (“always…”, “never…”). Creates only; revising is done in the dashboard. 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 takes project — 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.
Creates the workspace for a domain, or returns the one already started for it. Calling it again with the same domain never creates a second workspace: it is how you poll. 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.
Saves the person’s setup choices and returns their checkout link. Every call mints a new link, so give the person the latest one. 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.
Every goal in the workspace, with its current value against its target and whether the work is on pace. Takes no parameters. Returns 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}.
Creates a goal, or changes one by 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, and project is the workspace.

list_projects

Read-only. No credits. REST: GET /v1/work-areas and GET /v1/work-areas/{id}.
Without 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.
Gives a project’s crew the person’s direction, in their words. It is posted to the project’s feed and kept as the project’s direction, and the crew answers it with an ordinary run that replans. A steer is a post and nothing else: it never approves work, changes a setting or publishes anything, whatever the words say, and the run that answers it meets the same approvals as every run. 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.
What the crews delivered, newest first: where each piece of work lives and what the re-reads proved about it. 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.
The latest published client report for a cadence. 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.
The workspace’s markets, primary first, the platforms read in them, and how each platform is located in each market. Takes no parameters. Returns 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.
Prices a change to markets or platforms in AI responses a month, against what the plan includes. It changes nothing. 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.
The brand’s own properties beyond its main domain: other domains, subdomains, products and sub-brands. Takes no parameters. Returns 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"].