> ## Documentation Index
> Fetch the complete documentation index at: https://docs.attensira.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Goals

> A goal is one number from a fixed catalog, a target and a date. Attensira measures where it starts, reads it daily by 06:00, and says whether it is ahead, on pace, behind or unmeasured with the same arithmetic everywhere.

A goal is one number Attensira can read, a target for it, and a date: *named in 30 of 60 prompts on ChatGPT by 31 December*, *2,400 Search Console clicks over 28 days by 31 March*. You say what you want in your own words; the agent turns it into a goal you can measure, and you decide whether to create it. After that the readings, the pace and the re-planning are the agents' job.

Every goal is held to three rules:

* **Where it starts is measured, never typed.** The baseline is the first successful reading Attensira takes after the goal is created. No person, assistant or model can set it.
* **A number that could not be read is never a 0.** The goal reads as **unmeasured**, with the reason ("Connect Search Console").
* **A goal reports where a number stands, never why.** Our shipped changes appear beside the chart as markers. No goal sentence says a number moved *because* of our work, and nothing is ever described as won, driven or earned.

## Setting a goal from your own words

On **Analytics → Goals**, type what you want into **Add a goal in your own words**, for example *Double demo requests from search by March*, and press **Propose a goal**. A chat opens in goal mode, and the Chief of staff takes it from there:

1. It reads the goals you already have, so it does not propose one twice.
2. It picks the one metric from the [catalog](#the-metric-catalog) that measures what you described, scoped to the assistant, topics or keyword you named. If the words are ambiguous (which event is a demo request, which assistant), it asks first, at most three questions.
3. It proposes the goal as a card. The card shows the metric, where the number comes from, **today's value with its `n`** (read from the source when the card is drawn, and not stored), the target and date, and the pace line between them.
4. You press **Create goal**, or **Not now**. Nothing exists until you press Create. Accepting the same card twice creates one goal.

If the metric's source cannot be read in your workspace (Search Console not connected, the AI traffic snippet not installed, Google Analytics or Stripe), the card says why and offers no Create. The Chief of staff offers the nearest metric that can be read, called a signal, and proposes it only if you agree.

The same goal mode starts from **Propose the next** on a goal that was hit or missed. Typing `/goal` in the chat composer does not start it yet.

<Note>
  The goal chat is a chat like any other and spends [credits](/account/credits) the same way. Setting a goal, editing it and its daily readings spend none, and they keep working when the credit balance is spent.
</Note>

### Starting goals at signup

During setup, Attensira proposes starting goals from what the first scan found: **become visible** on each AI assistant you left on, **be recommended** against the competitors you confirmed, and **grow clicks from Google Search** once Search Console is connected and Google Search is on. Each has a date 90 days out. You keep or switch off each one. The ones you keep are created when your plan starts, with each target set so it is never below where the goal starts.

## The metric catalog

A goal measures exactly one metric from this list. A metric outside it is refused, and so is a parameter the metric does not take: a goal that silently ignored *only the pricing topic* would read a different number from the one you asked for.

| Metric | What it counts | One reading covers | Better | Parameters |
| - | - | - | - | - |
| `ai_named_prompts` | Tracked prompts the assistant names you in, out of those in scope | The latest answer per prompt in the last 7 days | Higher | `platform` (required), `topic_ids` |
| `ai_share_of_voice` | [Share of voice](/measure/share-of-voice): answers that name you, out of every successful answer in scope | The last 7 days | Higher | `platform`, `topic_ids` |
| `ai_citation_rate` | [Citation rate](/measure/citation-rate): answers that cite your domain, out of every successful answer in scope | The last 7 days | Higher | `platform`, `topic_ids` |
| `google_keywords_top10` | Tracked Google keywords where you rank in the top 10, out of those read | The latest position per keyword in the last 7 days | Higher | `keyword_ids` |
| `google_keyword_position` | Your Google position for one keyword | The latest position in the last 7 days | Lower | `keyword_id` (required) |
| `search_clicks` | Search Console clicks | 28 days ending 4 days ago | Higher | — |
| `search_impressions` | Search Console impressions | 28 days ending 4 days ago | Higher | — |
| `ai_agent_fetches` | Fetches of your pages by AI systems, from the [AI traffic snippet](/traffic/ai-traffic) | 28 days ending 2 days ago | Higher | — |
| `ai_referred_visits` | Visits referred by AI assistants, from the AI traffic snippet | 28 days ending 2 days ago | Higher | — |
| `ga4_key_events` | Google Analytics key events | 28 days ending 2 days ago | Higher | `ga4_event` (required), `ga4_channel` |
| `ga4_sessions` | Google Analytics sessions | 28 days ending 2 days ago | Higher | `ga4_channel` |
| `stripe_new_customers` | New Stripe customers | The last 28 days | Higher | — |

* `platform` is one AI assistant your workspace tracks: `chatgpt`, `perplexity`, `google_ai`, `claude` or `gemini`. Without it, a share or rate goal reads across every tracked assistant. See [Models](/tracking/models).
* `topic_ids` narrows an AI goal to prompts in those [topics](/tracking/topics), at most 50. Every id must be a topic of this workspace.
* `ga4_channel` is `organic`, `ai_referred` or `all` (the default).
* An AI goal counts the same prompts the [Prompts](/tracking/prompts) board shows for that assistant, with the same rule for what *named* means. A prompt whose every read failed is in the whole it counts out of, never counted as a miss.

### Business signals

Four metrics are **business signals**: `ai_referred_visits`, `ga4_key_events`, `ga4_sessions` and `stripe_new_customers`. They are shown beside our work and never credited to it: a signal's sentence opens with *A business signal:*, and nothing in the product turns one into revenue we drove. There is no revenue-in-currency metric.

### What each workspace can read today

The catalog is the same for everyone. Whether a metric can be read is per workspace, and the metric picker, the proposal card and the API all say which and why:

| Source | Readable when | Otherwise the goal says |
| - | - | - |
| AI answers we read | Always | — |
| Google rank tracking | The workspace has tracked Google keywords | *No Google keywords are tracked yet* |
| Search Console | Search Console is [connected](/account/connections) and its history has been pulled | *Connect Search Console*, *Search Console needs reconnecting*, or *Search Console history hasn't been pulled yet* |
| AI traffic snippet | The snippet has reported at least once | *Install the edge snippet* |
| Google Analytics | Not yet: there is no Google Analytics connector | *Google Analytics isn't a connector yet* |
| Stripe | Not yet: there is no Stripe connector | *Stripe isn't a connector yet* |

A goal on a source that cannot be read can still exist (over the API, for example). It reads as unmeasured with that reason every day, and starts measuring the first morning its source can be read.

## Targets, dates and limits

| Rule | Value |
| - | - |
| Target, for a count | A whole number, at least 1 |
| Target, for a share or rate | Between 0 and 1: `0.4` is 40% |
| Target, for a Google position | A whole position from 1 to 100 |
| Target date | 7 to 400 days after the goal starts, and after today, as a `YYYY-MM-DD` day in your workspace's time zone |
| Name | At most 120 characters. Without one, the goal is named after its metric |
| Goals per workspace | At most **12** that are not archived. A 13th is refused with `409` until you archive one |

A goal's metric and parameters never change: a different metric is a different goal. You can change its name, target, date and status. A new target must beat the measured baseline.

## The first reading and the daily reading

**The first reading** is queued the moment a goal is created and lands within about 15 minutes. Until then the goal says *First reading by 09:15* (the time in your workspace's zone). Its first reading that succeeds becomes the **baseline**, the number the goal starts from. If its source cannot be read yet, the baseline waits for the first morning it can.

**Every morning**, from 04:00 on your workspace's own clock, Attensira reads each active goal once for that day. The readings normally land before the morning goal-pace check at 05:00, and always by **06:00**, ahead of the daily win plan. Each goal has at most one reading a day; a repeated or retried read is harmless.

A reading is one of:

| Reading | Means |
| - | - |
| **ok** | A value, with its `n` (prompts, answers, keywords or days behind it) and, for a count, the whole it is out of |
| **unavailable** | The source could not be read for a known reason, which the reading carries. No value, and never a 0 |
| **error** | The read was tried and failed. The next pass tries again |

A Google position reading that finds you outside the top 100 is a measured reading (*not in the top 100*), worse than any position, never unmeasured.

Only active goals are read. A goal that is hit, missed, paused or archived is not read until it is active again, so its chart stops at its last reading. Goal readings are part of the monitoring the platform runs, and spend no credits.

## Pace: ahead, on pace, behind or unmeasured

Every reading recomputes the goal's pace from stored readings, with fixed arithmetic. No model decides whether a goal is on pace, and the Goals page, the chip, the morning brief, the board report, MCP and the API all show the same stored verdict.

```text theme={null}
start     = the later of the goal's start day and its baseline's day
f         = (today − start) ÷ (target date − start), clamped to 0..1, in whole local days
expected  = baseline + (target − baseline) × f              the pace line
current   = mean of the ≤ 3 newest ok readings in the last 7 days
            (the median, for a Google position)
band      = the noise band for the metric's unit, below

ahead     current beats expected by more than the band
behind    current trails expected by more than the band
on pace   anything inside the band
```

"Beats" and "trails" follow the metric's direction: for a Google position, lower is better.

The pace line starts at the baseline's own day when the first good reading came after the goal was set (a source connected weeks later), so a goal never reads as behind for days nothing could measure.

The band keeps day-to-day noise from flipping the verdict. It is computed from the newest reading's sample:

| Unit | Band |
| - | - |
| A count out of N (prompts named, keywords in the top 10) | `max(1, √(N × p × (1 − p)))`, where `p = expected ÷ N`, held between 0.05 and 0.95 |
| A share or rate with `n` answers | `max(0.02, √(p × (1 − p) ÷ n))`, where `p = expected` |
| A 28-day count (clicks, impressions, fetches, visits, events) | `max(1, √expected)` |
| A Google position | 1 |

A goal is **unmeasured** when there is nothing honest to compare, and always says why:

| Reason | Means |
| - | - |
| *First reading by 09:15*, *Waiting for the first reading* | No baseline yet |
| The source's own reason (*Connect Search Console*) | The newest reading in the last 7 days could not be read |
| *No reading in the last 7 days* | Nothing was read in the window |
| *paused* | You paused the goal |

### The sentence

Each goal carries one sentence, written by the server and shown unchanged everywhere. It is built from counts with their `n`, places the value against the pace line, and never says why the number moved:

> Named in 21 of 60 prompts on ChatGPT (n = 58). 19 expected by today, so on pace for 36 by 30 Nov.

> Cited in 14% of AI answers on Perplexity against 10% expected by today (n = 180), so ahead of pace for 20% by 31 Dec.

> Search clicks: not measured yet. Connect Search Console.

A share read from a single answer is not a share, and says so: *too few answers read to give a share yet (n = 1)*.

## Hit, missed, paused and archived

| Status | How a goal gets there | How it leaves |
| - | - | - |
| **active** | Created, or re-opened | — |
| **hit** | A reading finds the smoothed current value at or past the target. It is not read again while hit | Raise the target, and the goal is active again |
| **missed** | Its date passes without being hit. It is not read again while missed | Move the date later, and the goal is active again |
| **paused** | You pause an active goal. It is not read while paused | Resume it |
| **archived** | You archive it, from any status. Archived goals leave the Goals page and the lists, and cannot be edited | Final |

Hit and missed come only from readings, and stay until you edit the target or the date. When a goal is hit or missed, a row appears in your [Inbox](/agent/inbox): *Goal hit: … Propose the next?* or *… missed its date. Move the date or propose the next?* Its button opens a chat with the ask filled in, where the Chief of staff proposes the next goal or a new date for you to accept.

## When a goal falls behind

At 05:00 on your workspace's clock, after the readings, Attensira looks at every active goal whose pace is **behind** and decides whether the gap is worth re-planning the work:

* More than **30%** of the climb from baseline to target behind, with fewer than **14 days** left, always counts.
* Otherwise the agent weighs the numbers (the gap, the days left, the readings with their `n`, the work already shipped and waiting for its [re-read](/measure/before-and-after), the last re-plan) and re-plans only on a confident yes.

What happens next follows your [approval mode](/agent/approval). In **Draft** or **Act**, one re-plan run of the daily win plan starts, named for the goal (*Re-plan: … is behind pace*), and the goal's chip reads **Behind, re-planning**. It is an ordinary run under your approval mode and change caps. In **Ask**, nothing starts: one Inbox row offers the re-plan (*… is behind pace: re-plan the work toward it?*).

A goal is re-planned at most once a week. A re-plan you cancelled, or an offer you dismissed, is not raised again that week. The check never edits a goal, a target or a setting.

## When a source breaks

If a connection the readings use stops answering (Search Console's grant was revoked), the Inbox gets one **Reconnect Search Console** row naming the goals waiting on it. It is the same row the connector's own health check raises, so you see one, not several. The next reading that succeeds closes it. *Not connected* and *not a connector yet* are states the goal shows, not failures, and raise nothing.

## Where goals show up

* **Analytics → Goals**, the first Analytics tab. Each goal is a tile with its current value, target, date, pace chip, sentence and source. Opening one shows its daily readings against the pace line, the days our changes went live as markers, and the controls you steer with: target, date, pause or resume, archive. A day that could not be read stays on the chart with its reason. Edits name the version you were looking at; if the goal changed since you opened it, the sheet reloads it and says so.
* **The Analytics overview**: each goal as a chip with its value and target.
* **The Monday [morning brief](/agent/morning-brief)**: a status line counting goals by pace, and each goal's sentence.
* **The board report**: each goal's pace for the period. See [client reports](/agencies/client-reports).
* **Your [Inbox](/agent/inbox)**: hit, missed, behind (in Ask mode) and reconnect rows.
* **Your assistant and your code**: below.

## From your assistant or your own code

The [MCP server](/mcp/overview) has the goal tools below, and the [REST API](/api/overview) has their twins:

| MCP tool | REST | Does |
| - | - | - |
| `get_goals` | `GET /v1/goals` | The workspace's goals, oldest first. Archived goals are left out. Over REST only, `?status=` takes a comma-separated list of `active`, `hit`, `missed`, `paused`, `archived`, or `all` |
| — | `GET /v1/goals/metrics` | The catalog as this workspace sees it: each metric's key, label, source, unit, direction and parameters, whether it can be read here (`available`, with `reason` when not), and the AI platforms the workspace tracks |
| `set_goal` without `id` | `POST /v1/goals` | Sets a goal: `{name?, metric, params?, target, target_date, work_area_id?}`. Answers `201` |
| `set_goal` with `id` | `PATCH /v1/goals/{id}` | Edits a goal: `{version?, name?, target?, target_date?, status?, work_area_id?}`. `status` is `active` (resume), `paused` or `archived`; `work_area_id: null` moves the goal to the whole workspace |

The writes need write access: a read-and-write API key, or an OAuth connection. They spend no credits and work when the credit balance is spent. Call `set_goal` only on the person's instruction.

* **The baseline is not a field.** A body carrying `baseline` is a `400`, and so is an edit that tries to change `metric` or `params`.
* **Retries.** Send an `Idempotency-Key` header (`idempotency_key` on `set_goal`) with a create: a retry answers `200` with the goal the first call set. The same key reused for a goal on a different metric is a `422` carrying that goal.
* **Versions.** Without `version`, an edit applies to the goal as it is now. With one, an edit of a goal that changed since you read it is a `409` carrying the goal as it now stands (`details.goal`).
* **Limits.** Past 12 goals that are not archived, a create is a `409` with `{limit}`.

Each goal comes back with:

| Field | Notes |
| - | - |
| `id`, `name`, `metric`, `metric_label`, `params` | What it measures |
| `source`, `source_status` | Where the number comes from, and `{available, reason}` for this workspace today |
| `unit`, `direction`, `signal` | `count_of`, `rate`, `rolling_count` or `position`; `up` or `down`; `signal` is `true` for a business signal |
| `baseline`, `current` | `{value, n}`. `value` is `null` when nothing was measured, never `0` |
| `target`, `target_date`, `start_day` | In the metric's unit; days are `YYYY-MM-DD` in the workspace's zone |
| `pace` | `{state, expected: {value}, reason}`. `state` is `ahead`, `on_pace`, `behind` or `unmeasured`; `expected.value` is the pace line today, `null` while unmeasured |
| `sentence` | The server's sentence. Quote it rather than writing your own |
| `status`, `status_reason` | `active`, `hit`, `missed`, `paused` or `archived` |
| `replanning` | `{since, session_id}` while a re-plan from the last 7 days is under way, else `null` |
| `scope`, `work_area_id`, `work_area_ids` | `workspace`, or the project that owns the goal; and every project serving it |
| `created_via` | `person`, `chief_of_staff`, `onboarding` or `assistant` |
| `version`, `created_at`, `updated_at` | Name `version` on an edit to refuse a stale one |

A goal set over MCP or the API is recorded as set by your assistant (`created_via: "assistant"`), on behalf of the key's person.

<Note>
  `set_goal` takes `name`, `metric`, `target`, `target_date` and `work_area_id`, and nothing else. It sends no `params`, so a metric that needs one (`ai_named_prompts` needs `platform`, `google_keyword_position` needs `keyword_id`, `ga4_key_events` needs `ga4_event`) is set with `POST /v1/goals`, or from your own words in the app. Pausing, resuming and archiving (`status`) and naming a `version` are REST only.
</Note>

### Webhooks

Every transition sends one [`goal.updated`](/api/webhooks#events) event: a goal set, edited, paused, resumed or archived, or a reading that moved its pace or status. A daily reading that changes neither sends nothing, and a pace that flips more than once in a local day announces only the first flip. The event carries the pace state, never the numbers behind the band.

## What goals do not do yet

* **Google Analytics and Stripe cannot be read.** Their metrics are in the catalog so a goal can name them; every such goal reads as unmeasured with the reason.
* **Keyword-scoped Google goals cannot be set yet.** A goal that names keyword ids (`keyword_id`, or `keyword_ids`) is refused with *keyword tracking isn't set up for this workspace yet*. `google_keywords_top10` across every tracked keyword can be set.
* **No forecast.** The pace line is a straight line from where the goal started to its target. Attensira says where a number stands against it, never where the number will land.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.