# Alerts Source: https://docs.befailproof.ai/agenteye/alerts Find out the moment something crosses your line, on the channel your team already watches, instead of hearing about it from a customer. Find out the moment something crosses your line, on the channel your team already watches, instead of hearing about it from a customer. Set a rule once and Failproof AI Observability checks it on a schedule, then pages you by email, Slack, webhook, or right in the dashboard. The Alerts page: a grid of alert-rule cards, each showing its trigger, evaluation window, channels, and an info, warning, or critical severity badge *Every alert rule at a glance: what it watches, how often, where it pages, and how urgent.* ## Hear about problems before your users do Stop refreshing a dashboard hoping to catch a regression. Reach for an alert whenever there is a signal you would want to hear about even when nobody is looking, and have it land where you already are: * **Email**, to whoever should know. * **Slack**, a rich message with a button that jumps straight to the incident. * **Webhook**, a JSON POST for PagerDuty, Opsgenie, or your own endpoint, with an optional signature so the receiver can trust it. * **In-dashboard**, quiet by design, for when you are tuning a rule and do not want to page anyone yet. Attach any combination to a single rule, and its severity (info, warning, or critical) rides along so the urgent ones look urgent. ## Build the rule in a form, not JSON You describe what "broken" means in a form, and Failproof AI Observability writes the underlying rule for you. The JSON spec is just what that form produces under the hood, so you can read it to understand a rule but you rarely type it. The new-alert form: name and description, an enabled toggle, and a trigger picker offering metric threshold, custom SQL, evaluation score, compound eval, and per-event conditions *Pick a trigger and the form swaps in the right fields; Save writes the rule.* The happy path is quick: name it, pick a **trigger** (what to watch), set the **threshold and window** (how bad, over how long), attach at least one **channel**, then **Save** and hit **Test** to fire a synthetic notification and confirm every destination is wired up. Under the hood that produces a small spec like: ```json theme={null} { "metric": "p95_latency_ms", "op": ">", "value": 5000, "window_secs": 900 } ``` You are not limited to one kind of signal. Pick the trigger that matches how you think about the failure: | Trigger | Fires when | | -------------------- | -------------------------------------------------------------------------------------------------------------------- | | **Metric threshold** | a preset metric (error rate, p95 or p99 latency, event or error counts, token spend) crosses your line over a window | | **Custom SQL** | your own read-only query returns a row, or a value it computes crosses a threshold | | **Evaluation score** | an evaluator score's average (say, hallucination) crosses a threshold | | **Compound eval** | several score checks combine with any, all, or at-least-N logic, to catch a regression that only shows across scores | | **Per event** | a single matching event lands: a specific agent, a specific error type, or a message substring | Already staring at a failure on the [Errors page](/agenteye/error-tracking)? Every row there has a **+ alert** button that opens this same form prefilled to catch that exact failure again, so the incident you just triaged becomes the one that pages you next time. **Where to find it:** Alerts live at `//alerts`. Creating, editing, deleting, and testing rules needs **`alerts:write`**; `alerts:read` is enough to look. The recipient picker lists your org's members by name, so you can page a person without leaving the form. ## Page me only when it is real One bad measurement should not wake you. The **M of N** noise filter controls how many of the last few checks must fail before the alert actually pages you. Set it to **3 of 5** and the rule fires only after it has breached three of its last five checks, so a jittery signal stops crying wolf; leave it at the default **1 of 1** to fire on the first breach. You also choose how often the rule runs, from presets of 1m, 5m, 15m, and 1h, matched to how fast the signal really moves. ## What happens when an alert fires A breach opens an **incident** and pages your channels once. From there your team acknowledges it, assigns an owner, talks it through, and resolves it, all against a clean, attributed record. That triage workflow has its own home: see [Incidents](/agenteye/incidents). ## Related * [Incidents](/agenteye/incidents): track a firing alert from open to acknowledged to resolved. * [Error tracking](/agenteye/error-tracking): group agent failures and promote one to an alert in a click. * [Dashboards](/agenteye/dashboards): watch the shared boards the thresholds you alert on come from. * [CLI and agents](/agenteye/cli-and-agents): create alerts and ack incidents from your terminal, or script them into CI. # API Keys Source: https://docs.befailproof.ai/agenteye/api-keys API keys control who and what can reach your Failproof AI Observability server, so a collector can send events without ever gaining read or admin powers. API keys control who and what can reach your Failproof AI Observability server, so a collector can send events without ever gaining read or admin powers. Each key carries one or more permissions, and each permission gates specific server routes; you grant only the few a job needs. Most deployments create just three kinds of key. ## The 3 keys most deployments need | Key | Permissions | Who uses it | | ------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Collector key | `events:add` | The `agenteye-collector` on each agent machine, to send events. | | Dashboard read key | `events:read`, `keys:read` | A read-only operator or integration that queries data without changing it. | | Bootstrap admin key | all permissions | The operator who first brings the instance up (and the dashboard). Seeded from the `ADMIN_KEY` environment variable. See [Bootstrap admin key](#bootstrap-admin-key). | Start here. Reach for the full permission catalogue below only when you need a narrower, custom-scoped key. See also [Recommended key layout](#recommended-key-layout) and [Creating keys](#creating-keys). *** ## Permissions The server enforces a fixed catalogue of permissions; each one gates specific HTTP routes. An **admin key** holds all of them; a scoped key holds the subset you grant on creation. Unknown permission strings are rejected when a key is created. > **Note:** Two valid permissions are human/dashboard-only and cannot be granted to an API key: `orgs:admin` (instance administration, which is operator-only) and `keys:update`. A request to `POST /keys` or `PATCH /keys/:id` that tries to grant either one is rejected with HTTP 422. See the `keys:update` row below for why a bearer key may create keys but never edit them. ### Events ingest & query | Permission | HTTP routes | What it allows | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `events:add` | `POST /events` | Ingest batches of events from a collector. The only permission a collector needs. | | `events:read` | `GET /events`, `GET /events/latency_aggregate`, `GET /events/environments`, `GET /events/models`, `GET /sessions/:session_id/export` | Query events, list the known environments, list the model identifiers seen in the data (used by the Models view and model filters), compute the latency aggregate that powers the heat-map / percentile band, and export a session as JSONL. The shared filter-bar facet endpoints `GET /events/environments` and `GET /events/agent_ids` are reachable with **either** `events:read` **or** `evaluations:read`, so the sessions page (gated `evaluations:read`) reuses the same per-org facet. `GET /events/models` is not one of them: it requires `events:read`, so a principal holding only `evaluations:read` gets a 403 from it. | ### Sessions & evaluations | Permission | HTTP routes | What it allows | | --------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | `evaluations:read` | `GET /sessions`, `GET /evaluations`, `GET /evaluations/aggregate`, `GET /evaluations/environments`, `GET /evaluation-jobs` | List sessions, read evaluation results, the rolled-up eval health used by dashboards, and the evaluation-job worker queue state. | | `evaluations:trigger` | `POST /sessions/:session_id/re-evaluate` | Manually enqueue a re-evaluation for a finished session. | ### Dashboards | Permission | HTTP routes | What it allows | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | | `dashboards:read` | `GET /dashboards`, `GET /dashboards/:id`, `GET /dashboards/:id/tiles` | List dashboards, load one, and read its tiles. | | `dashboards:write` | `POST /dashboards`, `PUT /dashboards/:id`, `POST /dashboards/:id/tiles`, `PUT /dashboards/:id/tiles/:tile_id`, `DELETE /dashboards/:id/tiles/:tile_id`, `PUT /dashboards/:id/tiles/layout` | Create and edit dashboards, add / edit / remove tiles, and reorder the tile grid. | | `dashboards:delete` | `DELETE /dashboards/:id` | Delete an entire dashboard (tile-level deletion lives under `dashboards:write`). | ### Saved queries (SQL composer) | Permission | HTTP routes | What it allows | | ---------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `queries:read` | `GET /queries`, `GET /queries/:id`, `GET /queries/schema` | List saved queries, load one, and inspect the read-only schema the composer targets. | | `queries:write` | `POST /queries`, `PUT /queries/:id` | Create and edit saved queries. SQL is still routed through the same read-only role and guarded SQL checks as a `queries:run` call. | | `queries:delete` | `DELETE /queries/:id` | Delete a saved query. | | `queries:run` | `POST /queries/run` | Execute saved or ad-hoc SQL against the read-only role used by the composer. | ### AI assistant | Permission | HTTP routes | What it allows | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `agent:use` | `GET /agent/conversations`, `POST /agent/conversations`, `GET /agent/conversations/:id`, `PATCH /agent/conversations/:id`, `DELETE /agent/conversations/:id`, `PUT /agent/conversations/:id/messages` | Talk to the AI assistant and manage your own (private) conversations. Required on the **user** to see the assistant dock; the assistant's own key is `dashboard-assistant` and is seeded separately (see below). | ### API keys | Permission | HTTP routes | What it allows | | ----------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `keys:create` | `POST /keys` | Create a new scoped API key. Does **not** grant editing an existing key's permissions (that is `keys:update`). | | `keys:read` | `GET /keys` | List existing keys. Secrets are never returned by this endpoint. | | `keys:update` | `PATCH /keys/:id` | Edit an existing key's permissions. A **human/dashboard-only** permission; it cannot be assigned to an API key (a bearer key may create keys but never edit them). | | `keys:disable` | `POST /keys/:id/disable` | Revoke a key. Protected keys (`admin`, `dashboard-assistant`) can't be disabled; rotate them via env var + restart. | | `keys:regenerate` | `POST /keys/:id/regenerate` | Rotate a key's secret. Protected keys can't be regenerated through this route. | ### Dashboard users | Permission | HTTP routes | What it allows | | -------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `users:create` | `POST /users`, `GET /users/defaults` | Invite a new dashboard user (issues an email + one-time passcode (OTP) login) and read the dashboard-configured default permission set used to seed the invite form. | | `users:read` | `GET /users`, `GET /users/:id` | List users and load a single user record. | | `users:update` | `PUT /users/:id` | Edit a user's permissions. Updates dispatch a permission-change email to the affected user and take effect on their next request; no relogin required. | | `users:delete` | `DELETE /users/:id`, `POST /users/:id/enable` | Disable a user (revokes their sessions immediately) and re-enable a previously disabled user. | These permissions back the dashboard's **Users** page, where each member's granted scopes are shown as chips: The Users page: a card per dashboard user with their email, granted permissions, and edit/disable controls ### Operational settings | Permission | HTTP routes | What it allows | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `settings:read` | `GET /settings`, `GET /settings/schema`, `GET /settings/model-context-windows`, `GET /settings/model-context-windows/resolve` | View dashboard-managed operational settings and their metadata; list per-model context-window overrides; and resolve the effective window for a model. | | `settings:write` | `PUT /settings/:key`, `PUT /settings/model-context-windows`, `DELETE /settings/model-context-windows` | Edit operational settings and add, change, or remove per-model context-window overrides. Changes affect new events without restarting the server. | The Settings page: dashboard-managed operational settings such as allowed sign-ins and session/OTP lifetimes, editable without a restart ### Alerts & incidents | Permission | HTTP routes | What it allows | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | | `alerts:read` | `GET /alerts`, `GET /alerts/:id` | View configured alert definitions. | | `alerts:write` | `POST /alerts`, `PUT /alerts/:id`, `DELETE /alerts/:id`, `POST /alerts/:id/test` | Create, edit, delete, and test-fire alert definitions. | | `incidents:read` | `GET /alerts/incidents`, `GET /alerts/incidents/:iid`, `GET /alerts/incidents/:iid/comments`, `GET /alerts/incidents/:iid/subscribers` | View incidents and their triage trail. | | `incidents:write` | `POST /alerts/:id/incidents` | Open an incident manually against an existing alert. | | `incidents:ack` | `POST /alerts/incidents/:iid/ack`, `POST /alerts/incidents/:iid/assign`, `POST /alerts/incidents/:iid/resolve`, `POST /alerts/incidents/:iid/comments`, `POST /alerts/incidents/:iid/subscribe`, `POST /alerts/incidents/:iid/unsubscribe` | Acknowledge, assign, resolve, and comment on incidents. | ### Audits | Permission | HTTP routes | What it allows | | -------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | `audits:read` | `GET /audits`, `GET /audits/:id`, `GET /audits/:id/runs`, `GET /audits/findings`, `GET /audits/findings/:fid` | View audit definitions, run history, and findings. | | `audits:write` | `POST /audits`, `PUT /audits/:id`, `DELETE /audits/:id`, `POST /audits/:id/run`, `POST /audits/findings/:fid/status` | Create, edit, delete, and run audits; triage findings (acknowledge / mute / dismiss / resolve / reopen / assign). | > **Note:** To give a key the audit surface, grant `audits:*` to it explicitly. See [Upgrade and backward-compatibility notes](#upgrade-and-backward-compatibility-notes) for how existing grantees were migrated when Audits shipped. > The recipient-picker endpoint `GET /alerts/recipients` (which lists the member emails an alert editor can notify) is reachable by a holder of **either** `alerts:read` **or** `alerts:write`, so alert editors can populate the picker without being granted `users:read`. > A dashboards viewer needs **both** `dashboards:read` (to load the saved views) and `evaluations:read` (the health metrics are computed from evaluation data). Grant `dashboards:write` to let a user create or edit dashboards, and `dashboards:delete` to remove them. > `/health` and `/auth/*` (OTP request, OTP verify, session check, logout) are unauthenticated by design; they're the login flow and liveness probe. `GET /access-granters` requires a valid key but no specific permission, so any logged-in user can see which admins to contact about access changes. *** ## Permission Sets Permission sets let you apply a named role instead of hand-picking individual tokens every time. Rather than selecting a dozen permissions one by one for each new dashboard user or API key, you choose a set, and everyone assigned to it carries a consistent, reviewable grant. Editing a custom set re-applies the new grant to every user already assigned to it, so a role change is one edit rather than a sweep through every member. Every organization is seeded with three built-in sets: | Set | Permissions | Intended for | | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `read-only` | `events:read`, `keys:read`, `users:read`, `evaluations:read`, `dashboards:read`, `queries:read`, `settings:read`, `alerts:read`, `audits:read`, `incidents:read` | View-only access across every operational surface. | | `standard` | everything in `read-only`, plus `evaluations:trigger`, `queries:run`, `incidents:ack`, `agent:use` | Read-only plus the everyday on-caller actions: run queries, re-evaluate sessions, acknowledge incidents, and use the AI assistant. | | `admin` | every assignable permission | Full control of the org. | The three built-in sets are **immutable**; their names always mean the same thing, so `read-only`, `standard`, and `admin` are safe to reference in policy and onboarding. An operator can create additional **custom sets** to model roles specific to your organization (for example, a "dashboard author" role or a "collector-only" role). Sets are surfaced in the dashboard and managed over the API at `GET /permission-sets` (list, gated by `users:read`) and `POST /permission-sets` / `PUT /permission-sets/:name` / `DELETE /permission-sets/:name` (create, edit, delete a custom set, gated by `settings:write`). Deleting or editing a built-in set is refused. Set membership is what backs two other features: * **`DEFAULT_USER_PERMISSIONS`** (the grant preselected when an admin opens **+ new user**) defaults to the `standard` set. * **The `--set` flag** on `agenteye-orgctl` (operator member management) starts a member from a named set, which you then fine-tune with `--add` / `--remove`. > **Note:** When a set includes a permission that is not key-assignable (for example a custom set carrying `keys:update`), seeding a key from that set drops the non-assignable tokens; the server would otherwise reject the key with HTTP 422. Dashboard users are not subject to that restriction. *** ## Bootstrap Admin Key The admin key is the single root credential that lets an operator bring up access from nothing: with it you can mint every other scoped key, invite the first dashboard users, and configure the instance before any other key exists. It is the one key you do not create through the keys API; it is provisioned from the environment so the server is reachable on first boot. Set the `ADMIN_KEY` environment variable on the server. On every startup the server upserts this value as an admin key with all permissions. To rotate: change `ADMIN_KEY` to a new secret and restart the server. *** ## Organization scoping **Organizations themselves are created and managed out-of-band by an operator, not through this keys API.** Org and member lifecycle (create / rename / delete / purge an org; add / update / remove a member) is done with the **`agenteye-orgctl`** CLI; there is no HTTP API or dashboard button for it. What *is* unchanged: **per-org API keys are still minted in the dashboard (or via this keys API)** by org members. In a multi-org deployment, every key an org member creates (through this keys API or the dashboard **Keys** page) belongs to **one organization** and can only ever read or write that org's data; the org is stamped on the key at creation and enforced on every request. The two bootstrap keys are the only exception: the `admin` key (seeded from `ADMIN_KEY`) and the `dashboard-assistant` key (seeded from `AGENT_API_KEY`) are **instance-scoped** (they carry no org). The dashboard authenticates with the `admin` key so it can proxy per-org requests on behalf of signed-in members. Single-tenant deployments need not think about this; all keys belong to the built-in `default` org. *** ## Creating Keys Use the admin key (or any key with `keys:create` permission) to create additional scoped keys. ### Collector key (ingest only) ```bash theme={null} curl -s -X POST http://your-server/keys \ -H "Authorization: Bearer $ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "prod-collector", "key": "your-collector-secret", "permissions": ["events:add"] }' ``` ### Dashboard key (read only) ```bash theme={null} curl -s -X POST http://your-server/keys \ -H "Authorization: Bearer $ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "dashboard", "key": "your-dashboard-secret", "permissions": ["events:read", "keys:read"] }' ``` When you create a key over the HTTP API, you provide the `key` value yourself; choose a strong secret and store it securely. (The dashboard works the other way: it generates a strong secret for you and shows it once at creation; see [Key Management in the Dashboard](#key-management-in-the-dashboard).) The response confirms the key was created: ```json theme={null} { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "prod-collector", "permissions": ["events:add"], "created_at": "2026-04-01T12:00:00Z" } ``` *** ## Listing Keys ```bash theme={null} curl -s http://your-server/keys \ -H "Authorization: Bearer $ADMIN_KEY" ``` Key secrets are not returned in list responses, only IDs, names, and permissions. *** ## Disabling a Key Disabling revokes access immediately without deleting the key record. ```bash theme={null} curl -s -X POST http://your-server/keys//disable \ -H "Authorization: Bearer $ADMIN_KEY" ``` *** ## Regenerating a Key Generates a new secret for an existing key. The old secret is invalidated immediately. ```bash theme={null} curl -s -X POST http://your-server/keys//regenerate \ -H "Authorization: Bearer $ADMIN_KEY" ``` The response includes the new plaintext secret, **shown only once**. *** ## Key Management in the Dashboard The **Keys** page in the dashboard provides a UI for all of the above operations. You need a key with `keys:read` permission to view the list, and `keys:create` / `keys:update` / `keys:disable` / `keys:regenerate` for the create / edit / disable / regenerate actions respectively. Editing a key's permissions (`keys:update`) is separate from creating one (`keys:create`), so you can grant an operator the ability to mint keys without the ability to re-scope existing ones, or vice versa. The admin key covers all of these. When you create a key from the dashboard you do not supply the secret; the dashboard generates a strong secret for you and displays it **once** at creation. Copy it immediately and store it securely; it is never shown again, exactly as with a regenerate. You can still pick the key's permissions directly, or seed them from a permission set (see below). The API Keys page: a card per key showing its name, granted permissions, and creation time, with regenerate and disable actions; protected keys like admin are marked *** ## Recommended Key Layout | Key | Permissions | Used by | | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | | `admin` (bootstrap via `ADMIN_KEY` env var) | all | Ops/setup, and the dashboard (authenticates with `ADMIN_KEY`, proxies user requests with permission checks) | | Per-host collector key | `events:add` | Collector on each agent machine | | `dashboard-assistant` (bootstrap via `AGENT_API_KEY` env var) | `events:read`, `evaluations:read`, `dashboards:read`, `dashboards:write`, `queries:read`, `queries:write`, `queries:run` | AI assistant, seeded automatically, **protected**; can't be edited through the API | | Assistant telemetry key (optional) | `events:add` | AI assistant self-instrumentation, if enabled | > **Note:** The assistant's key is **seeded automatically** by the server from the `AGENT_API_KEY` env var (the same secret the agent presents as `AGENTEYE_API_KEY`); there is no manual key-minting step and no admin key involved. Its permissions are fixed in source code so scope can't be widened by misconfiguration: read across events / evaluations / dashboards, plus dashboards-write and queries-read / write / run for the "Ask AI to write a query" authoring flow. All SQL still goes through the same read-only role and guarded SQL path as a user-written query, so this widens the *authoring surface*, not the data surface; destructive operations (`queries:delete`, `dashboards:delete`) deliberately stay off the assistant key. Like the `admin` key, it is **protected**: it can't be disabled or regenerated through the keys API, only rotated by changing `AGENT_API_KEY` and restarting. Dashboard *users* additionally need the `agent:use` permission to see and use the assistant. If you enable self-instrumentation, give the assistant a separate `events:add`-only key. *** ## Upgrade and backward-compatibility notes You only need these if you are upgrading an existing instance; new deployments can skip them. > When Audits shipped, existing grantees were widened along the same role shapes as alerts: every user and permission set holding `alerts:read` gained `audits:read`, and every holder of `alerts:write` gained `audits:write`. Existing API keys were **not** widened. Grant `audits:*` to a key explicitly if it needs the audit surface. > Stored grants of the legacy `alerts:ack` token are parsed as `incidents:ack` so on-callers retain access without rekeying. The token is no longer assignable from the dashboard's user editor; the matrix offers `incidents:ack` instead. *** ## Next steps * [Python SDK](/agenteye/python-sdk): how your agent code authenticates when sending events. * [Security](/agenteye/security): how sign-in, access control, and per-organization data isolation work. # AI Assistant Source: https://docs.befailproof.ai/agenteye/assistant Ask your agent data a question in plain English and get an answer that links straight to the evidence. Ask your agent data a question in plain English and get an answer that links straight to the evidence. No SQL to write, no dashboards to dig through — the **Failproof AI Observability** assistant is the fastest way for anyone on your team to get answers about your agents. The Failproof AI Observability assistant answering a plain-English question inside the dashboard, showing a live Agent Activity table, a per-agent model-usage breakdown, and written takeaways, with the queries it ran shown inline *Ask in plain English and get an answer built from your own data. Here it breaks down which agents are busiest and which models they use, and shows the queries it ran so you can verify every number.* There is nothing to learn. Open the chat, type what you want to know, and follow the links it hands back: ``` You: which sessions errored today? AI: 5 sessions errored today, newest first. Each one is linked: • checkout-agent 14:02 tool timeout • billing-agent 11:47 unhandled error • ...and 3 more You: summarize this session (asked while viewing a run) AI: This run took 12 steps across 3 tools and failed near the end when a payment tool returned an error. It scored low on your "resolved" eval. Links: the session, the failing event, and that evaluation. ``` ## Just ask, and jump straight to the proof You stop guessing and you stop writing queries. Ask "how is quality trending in prod this week?", "which sessions errored today?", or "summarize this session," and you get a straight answer in seconds instead of building a query and reading it yourself. Every answer comes with its receipts. The assistant links the exact sessions, saved queries, and dashboards it used to reach the answer, so you can click through and confirm rather than take its word for it. It is also **page-aware**: ask about "this session" while you are viewing one and it already knows which run you mean. Reopen any earlier conversation later from the history switcher and pick up where you left off. ## Turn a good answer into a saved query or dashboard When an answer is worth keeping, ask the assistant to save it. It drafts the SQL for a saved query, or assembles a dashboard from those queries, then shows you an **Approve / Reject** card. Nothing is written until you click Approve, so you get the speed of "just ask" with the last word always yours. On the **Queries** page it goes a step further and becomes a SQL author: describe the query you want ("show error rate by agent for the last 7 days") and it streams SQL straight into the editor, opening a diff view so you can **Accept** or **Reject** the change before it lands. The Observability Queries page and its SQL editor *The Queries page: this editor is where the assistant streams a draft, read-only query for you to accept or reject.* Authoring SQL by asking here uses the `queries:run` permission, the same one behind the editor's **Run** button. Chat everywhere else needs `agent:use`. ## Safe to hand to the whole team You can open the assistant up to everyone without worrying about what it might touch: * **It reads only what you can already see.** Answers are scoped to your own read permissions, so it never widens your data surface. * **Every write waits for you.** Saved queries and dashboards are created only after your explicit Approve click, and there is no setting that turns that gate off. * **It can never delete anything.** No delete tool is exposed and the assistant holds no delete permission. Deletions stay in your hands, in the dashboard. * **It stays inside your org.** The assistant only ever sees the organization you are currently viewing. * **Your questions stay yours.** Prompts and answers live in your own Observability database; product analytics records usage metadata only, never your prompt text. ## Where to find it The assistant rides along on the right edge of every page under your org (`//...`). Click the rail, or press `⌘J` / `Ctrl+J`, to expand it into the full chat panel, and drag its edge to resize; your width is remembered across reloads. You need the **`agent:use`** permission to use it, otherwise the rail is greyed out. If it has not been switched on for your deployment yet (it needs an LLM connection), you will see a muted rail in place of a working chat. ## Related * [CLI and agents](/agenteye/cli-and-agents) * [Queries](/agenteye/queries) * [Dashboards](/agenteye/dashboards) * [Evaluation suite](/agenteye/evaluation-suite) # Audits: your automatic reliability analyst Source: https://docs.befailproof.ai/agenteye/audits Failproof AI Observability goes looking for the failures you never wrote a rule for and hands you a ranked, evidence-backed to-do list of exactly what to fix. Failproof AI Observability goes looking for the failures you never wrote a rule for and hands you a ranked, evidence-backed to-do list of exactly what to fix. It is like having an analyst comb your logs every night, then leaving the short list on your desk by morning.