https://api.attensira.com/v1. Every one takes Authorization: Bearer atn_live_<32 hex>, and every one also takes an optional ?project=<workspace id> when the key’s organisation has more than one workspace — see authentication.
Each endpoint below names the MCP tool it is the twin of, and answers with the same payload. The tools without a REST endpoint yet are listed under MCP-only for now at the end of this page.
?project= is always the workspace, never a project. A project is a work area on the wire: it is read and steered under /v1/work-areas, and a goal or a deliverable that points at one carries its id as work_area_id. Creating a project and changing its settings are in the dashboard only.
Before you start: what costs money and what destroys data
Nothing else on this page produces a bill or erases history.
Status codes
APOST that creates a durable resource answers 201. POST /v1/ask and POST /v1/automations/{id}/runs answer 200, because what they return is a handle to work in progress rather than a resource at a new URL. Everything else answers 200. Failures are the error envelope.
Find and measure
GET /v1/search
Read-only. No credits. MCP tool:
search.Shell
Response
type tells you which endpoint can fetch the hit in full: prompt → GET /v1/prompts/{prompt}, page → GET /v1/pages, session → GET /v1/sessions/{id}, automation → GET /v1/automations/{id}. 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. Answers themselves are not searched — they are read verbatim through GET /v1/memory/answers/history and GET /v1/memory/answers/slice.
Every string on a hit is capped at 400 characters, not just
snippet. A complete model answer can never come back through search, no matter which fields a hit carries. Fetch the session for the full text.has_more. total is how many items matched up to the server’s fetch ceiling — a floor, not a grand total.
GET /v1/analytics/
Read-only. No credits. MCP tool:
get_analytics.Shell
Response
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. A tracked platform with no readings in the window appears as tracked: true, readable: false with a null rate — present, and not zero.
area=bot rows carry visits, pages, purpose_mix, last_seen (null when it never came) and agents instead of the rate fields. A model can only cite a page it has fetched, so check bot before concluding a page underperforms on content — but a row here counts only what our middleware recorded, so absence is no proof nothing came.
competitor and source are workspace-wide aggregates. For the rivals and cited sources of one prompt, GET /v1/prompts/{prompt} already returns both — no second call needed.GET /v1/prompts/
Read-only. No credits. MCP tool:
get_prompt.Shell
Response
topic is null when the prompt is not filed under one and country is null for the workspace default. Competitor and source rates are on this prompt’s own answers_read.
Passing exact text saves a search round-trip when you already know the wording; inexact text will not match. Percent-encode it — a prompt containing / or ? will otherwise change the route.
GET /v1/pages
Read-only. No credits. MCP tool:
get_page.Shell
Response
delta is always {value: null, real: false} here: the page fold has no earlier window to compare against, and the contract’s word for that is “no basis”, not a number.
If this comes back empty, check GET /v1/analytics/bot before rewriting the page — a model cannot cite a page it has never fetched.
POST /v1/evidence/query
Read-only. No credits. MCP tool:
query_evidence.metric (required), group_by, days or from and to, the filters topic_ids, prompt_ids, engines, surface, country, markets, property_ids, competitor, intent, stage, state, domain and text_contains, and limit. The query_evidence reference lists every metric with what it can be grouped and filtered by. A field the query does not know is refused rather than ignored, so a misspelt filter cannot come back as unfiltered numbers.
Shell
Response
value is in unit, and null means unmeasured, never 0: the row’s gap says why. n is on every row; for Search Console it is the impressions behind the row. gaps names everything the answer could not measure, and 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).
A question with no honest answer — an unknown metric, a metric grouped or filtered in a way it does not support, a from–to span over 365 days, an id the workspace does not have — is a 400 with type: "invalid_request" and a message that names the problem and what to ask instead. A question too broad to answer in time is a 422 whose message says what to narrow. days and limit outside their ranges are clamped to the nearest bound rather than refused.
GET /v1/deciding-sources
Read-only. No credits. MCP tool:
deciding_sources.GET /v1/analytics/source ranks by citations; this ranks by influence over a decision. See Deciding sources.
Returns
groups, most influential first, one per prompt, platform and surface. Each carries a label, n, present, a recommendation, and sources ranked by weight, each with domain, url, citations, share, present and action. The full row is described under deciding_sources.
GET /v1/win-plan
Read-only. No credits. MCP tool:
win_plan.
Returns
prompt, n, evidence, the steps in order, rereads_at and credits_estimate, as described under win_plan.
The receipts
The numbers above are folds over stored answers. These endpoints hand back the rows themselves, verbatim. See Deep reads.GET /v1/memory/answers/history
Read-only. No credits. MCP tool:
answer_history.
Returns
answers, readings, has_more and next_cursor. An answer over 8 KB is cut and carries truncated: true, with text_bytes the full length. A failed sample is listed with failed: true, never dropped. The row shape is described under answer_history.
GET /v1/memory/answers/slice
Read-only. No credits. MCP tool:
answer_slice.Shell
surface, model, competitor, cited_domain, brand_named, sentiment, the brand positions and text_contains) must all hold for one sample, and only matching samples come back. Without topic_id or prompt_ids, text_contains covers at most 30 days; a wider window is a 400 saying what to narrow. The full semantics are in the answer_slice reference.
GET /v1/memory/citations/timeline
Read-only. No credits. MCP tool:
citation_timeline.
Returns
domain, url, total, prompts and series, one entry per platform, each with points for every day of the window: day, citations, mean_position (null when nothing that day carried a position) and prompts. A zero day is a real zero.
GET /v1/memory/pages/history
Read-only. No credits. MCP tool:
page_history.
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 a 404.
Returns url, known, and versions oldest first, each with what changed since the one before. The row shape is described under page_history.
Track
POST /v1/prompts
Starts tracking one or more prompts. From the next daily run, each is read across every platform your plan includes.
There is no
platform field. Which surfaces a prompt runs on comes from your plan, not from the request.
Shell
201 Response
added 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 because 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.
DELETE /v1/prompts/
Permanently stops tracking a prompt and frees its slot. Its historical data goes with it and this cannot be undone — fetch it first if you want it.Response
POST /v1/competitors
Answers
201. No credits. MCP tool: add_competitor.201 Response
DELETE /v1/competitors/
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.Response
Automations
GET /v1/automations
Read-only. No credits. MCP tool:
list_automations.Response
status is active (runs on its trigger), paused (does not), or done (a once trigger that already fired). tools: [] means the default read-only set.
Paused and retired automations are always listed. One the product paused on its own carries retired_reason and retired_at. next_run_at is null for an event automation.
GET /v1/automations/
Read-only. No credits. MCP tool:
get_automation.Response
latest_run is null when the automation has never run. Pass its id to GET /v1/sessions/{id} for the full trace.
POST /v1/automations
Answers
201. Creating is free; each run it performs spends credits. MCP tool: create_automation.Shell
GET /v1/automations.
Shell — an event automation
PATCH /v1/automations/
No credits. MCP tool:
update_automation.name, instruction, trigger, event_types, tools, status (active or paused), timezone, run_at_minute and run_on_weekday, with the same rules as POST /v1/automations. event_types is valid only when the trigger is event.
Returns the automation in the shape shown under GET /v1/automations.
POST /v1/automations//runs
Runs an automation immediately, outside its cadence. Returns a session handle, not a finished result.Shell
Response
GET /v1/sessions/{id}. Re-sending this POST without an Idempotency-Key starts a second billed run.
DELETE /v1/automations/
Permanently deletes an automation and its schedule. This cannot be undone — confirm withGET /v1/automations/{id} first. Its past runs are kept as sessions, readable through GET /v1/sessions.
Response
Inbox
Everything waiting on a person, and every act the dashboard’s Inbox offers on it. Each act goes through the same path as a click in the dashboard, so a yes or an answer means the same thing wherever it was given, and the action log records your key as the one who gave it. Each row’stype says which endpoint acts on it, and its ask_kind (approve, answer, do or info) says what it asks of a person:
Every write needs a read-and-write key; a read key gets
403. Approve, answer and decline only on the person’s instruction. Every act returns next_item_ref when something else is waiting: the row the ranking puts first now, readable with GET /v1/inbox/items/{ref}.
GET /v1/inbox
Read-only. No credits. MCP tool:
list_inbox.
Each row in
items carries type (work_item, ask or task), id, ref, ask_kind, 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, 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.
Shell
Response
top holds the first limit of them; the rest are in sections, grouped by ask_kind. total_open counts rows, decisions counts decisions, and merged_count is how many sightings are not shown as rows of their own. See At most three decisions first for the order.
GET /v1/inbox/items/
Read-only. No credits. MCP tool:
get_inbox_item.
To approve a specific version, copy
work_item.change.proposal.captured_at from here into the approve body. 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.
POST /v1/inbox/tasks//answer
Answers a task whoseask_kind is answer with the person’s words. 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.
Request
Response
resume.status is resumed (a running run reads the answer from its next step; a finished, failed or suspended one starts a new turn on it, which spends credits), queued_after_approval (the run reads it once its pending approval is answered), not_started (the run was cancelled, or no run asked) or failed (the answer is saved, but the run could not be handed it; retry from the row’s page in the dashboard). A second answer to the same row is 409; a row that is not a question is 400.
POST /v1/inbox/tasks//resolve
No credits. MCP tool:
resolve_inbox_task.
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.
POST /v1/inbox//approve
No credits. MCP tool:
approve_work_item.
Idempotent: approving twice approves once, so a retry after a timeout is safe. Returns the work item and
next_item_ref.
A work item that a run started over the API or MCP filed is approved by a person, in the app. With a key or a token, approving it is 403 with reason: "self_approval" and an app_path; declining it still works.
edited_value is accepted only for an article, a LinkedIn post or a rewritten passage that is still waiting, and is 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 422, and nothing is approved. An edit is checked against the workspace’s rules like any draft; one that breaks a rule is 409.
POST /v1/inbox//decline
No credits. MCP tool:
decline_work_item.
The reason is what stops the same proposal coming back; the reason and note are kept on the item and in its activity. Returns the work item and
next_item_ref.
POST /v1/inbox/asks//approve
No credits for the call; the run it lets go carries on as before. MCP tool:
approve_ask.{id} is the row’s ask_id.
An ask from a run that was started over the API or MCP is approved by a person, in the app: with a key or a token it is
403 with reason: "self_approval" and an app_path. Declining it still works.
Response
edited_value is 400. The run is back on the queue and has not made the call yet; poll GET /v1/sessions/{id}. A session in another workspace is 404; an ask already answered, expired, or no longer the one the run is waiting on is 409.
POST /v1/inbox/asks//decline
No credits. MCP tool:
decline_ask.
Returns
outcome: "rejected" in the same shape as approve. Same 404 and 409.
Agent
POST /v1/ask
Open-ended investigation the measurement endpoints cannot answer — why a prompt is losing, what to change on a page — run by the Attensira agent, which crawls pages, audits them as a model sees them, and searches the web. Try a measurement endpoint first:/v1/analytics/{area} for any metric or ranked list, /v1/prompts/{prompt} for one named prompt, /v1/pages for one URL. Those are free and immediate; this costs credits and takes time.
Response
status is complete (the answer is present), running (poll the session after poll_after_ms) or failed (the run ended without an answer). A running response is the success case, not an error.
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 /v1/sessions/
Read-only. No credits. MCP tool:
get_session.Shell
Response
status is the three-word vocabulary above; state is the engine’s own finer word, so a run parked on a question for you reads awaiting_person under a running status. The events trace shows which tools the agent called and with what arguments — the place to look when an answer seems wrong and you want to know which slice it read. answer is the agent’s last message and is filled in for a finished session whether or not the trace was asked for.
Listing, stopping and feeding sessions
GET /v1/sessions, POST /v1/sessions/{id}/cancel, DELETE /v1/sessions/{id} and POST /v1/sessions/{id}/context are on their own page: Sessions.
Loop health
GET /v1/loop-health
Read-only. No credits. Works on a spent balance. MCP tool:
get_loop_health.Response
status is working, idle or blocked. Each runs entry has status fired, skipped or failed, and a skip carries a reason: no_credits, manual_trigger, parked_on_ask, flag_disabled, retired, paused, cap_reached or in_flight. Every count is read once for its date and is not a trend.
Account
GET /v1/account
Read-only. No credits. MCP tool:
get_account.project.
Response
platforms is the authority on which surfaces were queried at all, so a platform missing from it was never measured rather than measured at zero. They belong to the resolved workspace, so the array is empty whenever project is null.
project is null when the organisation has several workspaces and the request named none. That is the answer, not an error — workspaces carries the ids, and every other endpoint then needs an explicit ?project=. This is the only endpoint that answers without one, which is why the “several workspaces” error elsewhere points here.
An endpoint that fails with 403 is missing a scope listed in scopes.
GET /v1/costs
Read-only. No credits. Works on a spent balance. MCP tool:
get_costs.Shell
Response
spent_usdis the month’s spend less refunds, and every breakdown adds up to it. Ad spend is never part of it.forecast_usdis spend divided by the days elapsed, times the days in the month:nullfor the first three days of a month, and what the month cost once it is over.- A
nullwork_area_idis a workspace’s unassigned spend: chats and the Chief of staff. An emptyworkspace_idinby_workspace, namedAcross workspaces, is spend that belongs to the organisation rather than one workspace. by_kindalways listsagent_work,data,paid_placementandcreators; nothing is charged under the last two today.unattributedappears only when a charge could not be placed.deliveredinby_type, andcommittedincommitted, arenullfor a type we do not count.nullis never0.committedandcredited_back_usdare the organisation’s even whenprojectnames a workspace.credit_usdis the credit for undelivered work: what the close credited, or for an open month what it would credit now. In the example it is0because the month’s spend has not passed the value of what was delivered. See Plans for the rule.
GET /v1/account.
GET /v1/ai-traffic/install
Read-only. No credits. MCP tool:
get_ai_traffic_install.Response
GET /v1/wins
Read-only. No credits. Works on a spent balance. MCP tool:
list_wins.sentence, which says exactly that.
No parameters. Returns at most the 50 most recently found wins, and leaves dismissed wins out.
Shell
Response
kind is named (the answer named the brand) or linked (it cited a page on your domain); one prompt on one engine can give one win of each kind, never two of the same. quote is a verbatim excerpt of at most 400 characters, never edited, and null when no answer that day gave an excerpt that passed the honesty check; quote_truncated says whether it stops short of either end of the answer. cited_url is the first page on your domain the answer cited, or null. date is the day of the answer and reading_since the first day we read the prompt on that engine, both YYYY-MM-DD in the workspace’s time zone. The list is ordered by detected_at, when the win was found.
seen is whether someone has opened the win in the dashboard, and unseen counts every undismissed win nobody has opened, including any beyond the 50 returned. Reading this endpoint marks nothing seen. share_url is the public link to the win card while it is shared, and null otherwise.
GET /v1/brief
Read-only. No credits. MCP tool:
get_brief.
Counts, never a day-over-day comparison, until a seven-day window exists. The fields are described under
get_brief.
PATCH /v1/settings/agents
No credits. MCP tool:
update_settings.unattended_mode, or publish_without_approval and send_without_approval turned off. Raising the mode, turning either permission on, or changing act_path_allowlist is 403 with reason: "autonomy_raise_in_app" and the field. Make that change in the app under Settings → Autopilot.
Returns the settings in force.
GET /v1/github/install-url
No credits. MCP tool:
connect_github.url.
Memory
Writes into what the workspace knows about itself. See Knowledge and skills.POST /v1/observations
Answers
201. No credits. MCP tool: record_observation.
Every id is resolved against the workspace before anything is stored. One that does not exist there is a
400, never a stored fact.
POST /v1/skills
Answers
201. No credits. MCP tool: write_skill.Set up a workspace
A key holder adds a workspace for a domain: the agents draft the business from its site, the person decides what to keep, and the person pays in their own browser. Nothing here can charge. Both endpoints act on the key’s own account and take no?project=: there is no workspace to select yet, and a ?project= is refused with that reason. A new person with no account starts from an assistant over MCP instead, where signing in comes before any account exists; see Set up from your own assistant.
POST /v1/onboarding/workspace
Needs a read-and-write key. No charge. MCP tool:
start_workspace.
Returns
workspace_id, status, the drafted profile (each fact with the page it came from, or a question to ask when nothing was found), the suggested competitors and platforms, the proposed goals and the plans. status is drafting, needs_input, ready_to_confirm, awaiting_payment, active or first_readings_ready; the fields are described under start_workspace. An account holds one workspace waiting for payment at a time, so a second unpaid domain is a 409 naming the one to finish.
POST /v1/onboarding/workspace//confirm
Needs a read-and-write key. No charge. MCP tool:
confirm_setup.
An omitted list keeps what was proposed; an empty list keeps none of it. Returns
checkout_url, requires_browser (always true), expires_at and budget_consent, as described under confirm_setup. An account that already pays for a plan is a 409. The endpoint never charges and never uses a saved card: the person pays in their browser, and the start endpoint then reads active.
Goals
What the agents aim at: a metric, a target and a date, with a pace verdict from the daily readings. See Goals.GET /v1/goals
Read-only. No credits. MCP tool:
get_goals.
Returns
goals, oldest first, each with baseline and current as {value, n} (a null value is not measured yet, not zero), target, target_date, pace (state is ahead, on_pace, behind or unmeasured), the projects it drives as work_area_ids, and status. The full row is described under get_goals.
POST /v1/goals
Needs a read-and-write key. No credits. MCP tool:
set_goal.
The baseline is the first reading taken after the goal is set, never a field: a body with
baseline is a 400.
PATCH /v1/goals/
Needs a read-and-write key. No credits. MCP tool:
set_goal.400.
A goal’s metric and its params never change: to measure something else, set a new goal and archive this one.
Projects
A project is an area of work with its own crew of agents, and on the wire it is a work area. Creating a project and changing its settings are in the dashboard only. See Projects.GET /v1/work-areas
Read-only. No credits. MCP tool:
list_projects.id, name, description, team (each crew member with their status line), goal_id, unread, needs_you, budget_cap_usd and last_activity_at. Archived projects are left out.
GET /v1/work-areas/
Read-only. No credits. MCP tool:
list_projects.direction (what people have told it, word for word), the triggers its crew runs on, automation_ids, and the feed’s newest 50 posts, newest first. A project outside the workspace is a 404.
POST /v1/work-areas//steer
Needs a read-and-write key. Posting is free; the crew’s reply is an agent run and spends credits. MCP tool:
steer_project.
A steer is a post and nothing else: it never approves work, changes a setting or publishes anything, and the run that answers it meets the same approvals as every run. A field other than
text is refused. The response is described under steer_project.
Deliverables
GET /v1/deliverables
Read-only. No credits. MCP tool:
list_deliverables.
Returns
deliverables and next_cursor (null at the end). result is null until there is something to measure. The row is described under list_deliverables.
Reports
GET /v1/reports/latest
Read-only. No credits. MCP tool:
get_report.
Returns the report’s period, its facts with their
n, the share link when it is shared, and the markdown in full: unlike the MCP tool, nothing is cut. A cadence whose first report has not published yet is a 404.