Triage an Issue
Ask your agent to prioritize an error by customer impact, reproduce its story, and move it through its lifecycle with a previewed write.
On this page
Anectico groups similar error events into Issues. Triage the Issue, not each raw occurrence. Your agent ranks the Issues, reads the evidence, and makes the lifecycle changes. You open the Issue page it links to and check the evidence yourself.
An explicit SDK error capture is the canonical Issue occurrence for that failure. Error-level logs
linked to the capture through error.id remain searchable in the logs and stay correlated to the
trace, but they do not create duplicate log_error Issues. Independent error and fatal logs without
a linked capture still create Issues.
Ask your agent
Which Issues hit the most customers in the last day? Take the top one. Show me one occurrence with its trace and replay, and tell me whether it is new or came back after a release. Give me the link.
Resolve Issue
ISSUE_IDin the next release. Show me the preview first.
Issue
ISSUE_IDstarted after we deployed commitNEWER_COMMIT. The version before it wasOLDER_COMMIT. Which commits between the two changed the code that fails? Do not name a cause. Tell me which commits are candidates and what the evidence cannot show.
| Job | MCP tool or action | CLI command |
|---|---|---|
| Rank Issues by impact, or search them by text | list_issues, search_issues |
anectico issues list (-q searches by text) |
| Read one Issue: counts, latest occurrence, stack, breadcrumbs, suspect commits | get_issue |
anectico issues view |
| Read one occurrence for reproduction | get_issue_reproduction through execute_read_action |
anectico issues reproduction |
| See who was affected | get_affected_users, get_error_impact |
anectico issues affected, anectico issues impact |
| Read release context, lifecycle history, merged sources | get_issue_releases, list_issue_lifecycle_history, list_merged_sources |
anectico issues releases, anectico issues lifecycle-history, anectico issues merged-sources |
| Find the commits between two versions that changed the failing code | get_issue_commits_between |
anectico issues commits-between |
| Resolve, ignore, reopen, or assign | set_issue_status |
anectico issues resolve, anectico issues ignore, anectico issues reopen, anectico issues assign |
| Snooze | snooze_issue |
anectico issues snooze |
| Merge duplicates, or split a merge | merge_issues, unmerge_issue |
anectico issues merge, anectico issues unmerge |
| File and read a linked ticket | create_ticket, list_tickets_for_issue, get_ticket |
anectico tickets create, anectico tickets list, anectico tickets get |
| Check whether customers recovered | customer_recovery, list_recovery_watches, get_recovery_watch, create_recovery_watch, delete_recovery_watch |
anectico issues recovery, anectico issues watches |
| Delete error data | delete_error_group, delete_person_errors |
anectico issues delete, anectico persons erase-errors |
Reads need errors:read. Release reads also need releases:read. Lifecycle writes need
errors:write. Assigning an Issue to a person also needs members:read. Ticket tools need
tickets:read or tickets:write, with connections:read and errors:read. MCP calls also need
mcp:read or mcp:write.
What your agent gets back
Issue lists, occurrence searches and occurrence series default to the last 24 hours.
An Issue last seen three days ago will be absent unless you choose a wider window.
The REST and CLI JSON responses report effective_start_time and effective_end_time,
the absolute UTC bounds actually read. MCP issue lists and searches carry the same
fields in data and state that range in window and the summary. MCP occurrence
series carry the bounds in start and end. CLI issue tables print the
window even when no Issues match.
These Issue activity windows include both endpoints and preserve fractional seconds through nanosecond precision. An occurrence exactly at either bound is included; one immediately outside is excluded.
Use since and until over MCP, or --since and --until in the CLI, with a positive
relative age such as 24h or 7d, or an exact RFC3339 timestamp. A malformed age is
refused. To continue a list or search, copy the returned bounds into those inputs
and keep the filters unchanged with cursor or --cursor. An empty bounded result
does not show that the Issue never occurred.
list_issuesreturns up to 25 Issues, most recently seen first, with event and affected-people counts. Filter by status, service, release, and look-back window. Each row has its ownurl.get_issuereturns the root-cause payload: status and counts, the latest occurrence with its stack trace and breadcrumbs, suspect commits, recent occurrences, and the Needs attention marker and suggested area when the platform set them. It has the Issue’surl. The Issue version in this result is theexpected_versionthat a lifecycle write must quote.get_affected_usersreturns the people the Issue hit, with their first and last occurrence, the accounts they belong to, and the totals behind both. You can passsearchand acursor.
In get_issue, latest_occurrence.frames keeps each frame's captured function, file, line
and column separate from its resolved original (name, file, line, column).
symbolicated is true when a source map or native symbols resolved that frame. An unresolved
frame stays visible with symbolicated: false. Native frames also retain instruction_addr,
image_uuid and image_load_addr; for iOS, the top-level file, function and line may already be
recovered by native symbolication, so those address fields preserve the captured location.
MCP shows at most 15 frames. frame_total and resolved_frame_count cover all structured frames
returned for that occurrence, including frames beyond the MCP limit. When source-map coverage is
available, eligible_frame_count counts frames with a nonempty captured filename and a positive
line, before that limit. It describes source-map candidates, not successful matches. This count
is omitted for native stacks and when source-map coverage is unavailable. With only raw stack
text, the resolution counts are omitted and frame_total counts raw lines instead.
Read sourcemap_symbolication, proguard_symbolication or dsym_symbolication for the artifact
status and exact upload keys. Source maps and ProGuard use release and distribution (dist);
dSYMs use image UUIDs. An APPLIED status means at least one frame resolved; it does not promise
that the whole stack resolved. A missing coverage block means no status was available, not that
symbols succeeded or were missing. REST and anectico issues view <issue-id> -o json preserve the
full occurrence under latest_event, including its frames and artifact coverage.
Open the proof
Open the url from get_issue, list_issues or search_issues. It opens the Issue page at
/view/issue/:groupId, with project_id in the address. The page is read-only. It names its
project, and its one action is Copy link. It shows the Issue, its affected customers and
accounts, its release context, its lifecycle history, and its linked tickets. It has no Resolve,
Ignore, Snooze or Assign button. Your agent or the CLI makes those changes. See
Proof pages.
Start with impact
Ask the agent to evaluate each Issue on:
- how many customers are affected;
- the severity, and whether the latest grouped capture was handled or unhandled;
- whether important customers or accounts are included;
- whether occurrence volume is increasing;
- the first-seen and last-seen times, the environment, and the release; and
- whether the Issue is new or has regressed after resolution.
Text search matches, case-insensitively, any part of an error’s message, emitting service, or error
class. It is the query parameter of the REST list and -q in anectico issues list. The search
runs over every Issue in the window, not only over one page. The count and an empty result
therefore describe the whole window. Follow the returned cursor to continue through a searched
result set, in the same way as through an unsearched one. Keep reading pages until there is no
next_cursor.
The REST list, GET /api/v1/errors/groups, also accepts the exact fields platform,
service_name, mechanism, and release. They isolate one deployed workload and capture path. Each
is an exact match, and all of them apply to the same error occurrence. An Issue does not match by
taking its platform from one occurrence and its release from another. The event count,
affected-customer count, first and last timestamps, ordering, and pagination are recalculated inside
that exact filtered slice. They are not copied from the Issue’s all-release lifetime totals. MCP
list_issues filters by service and release. The CLI filters by --service and --env.
A high occurrence count does not always mean high customer impact. Prefer the Issue that affects more real customers or a critical journey.
Affected-customer totals are customer totals, not raw identity totals. When Anectico has connected an
anonymous identity, a login identity, or another alias to the same customer, that customer counts
once. get_affected_users searches by display name or any known identity alias. The search runs
across the full canonical result set. Follow the returned cursor. Do not assume that the first page
is complete. Account counts show how many canonical affected customers belong to each account.
An account row uses each affected customer's current account membership, not the account they belonged to when the error happened. A customer who moved from one account to another counts only for the account they belong to now. A customer removed from an account counts for no account through that membership. Membership is read within the Issue's project, so the same identity in another project never decides the account here. The same rule applies to error impact, its summary and release account counts.
“People affected” means people with an identifier Anectico resolved, including resolved anonymous visitors. A missing or unmapped identifier is an unattributed occurrence, not another person. Those occurrences still count in error totals and in the unattributed remainder of the impact answer. If identification is missing, the people count can be smaller than before while the error count stays the same. These reads are as reliable as your application's own customer identification; intake telemetry does not authenticate each end user.
The account rollup is not paginated. It lists the 20 accounts with the most affected customers. The affected-account total is reported separately and counts every account, including those the list leaves out. An Issue that spans more than 20 accounts is reported as such, not as exactly 20. When accounts are withheld, the Issue page says so ("Showing 20 of 213 affected accounts"). When the list is the whole rollup, it says nothing.
Very large Issues are summarized, not counted exhaustively. Anectico resolves a bounded number of
affected identities per Issue. When an Issue goes past that bound, every total is a floor with a
trailing +, for example "Showing 25 of 1,000+ affected customers". The result sets
totals_are_capped. Read these as at least: the real figure is higher. A total without the + is
exact.
The error-impact answer shows exact counts of resolved identified and anonymous people, unattributed occurrences, and affected accounts over its stated window. The people list is a page; its account list says how many accounts were left out.
For a release (get_release, get_issue_releases), the affected-person total and each account count
use the same resolved-person identity fold. Release adoption also counts unidentified
visitors separately; it is a visitor measure, not the number of known people. They are cut and marked in the same way, and the account list
says how many accounts it is not showing. New and regressed Issue rows are confined to the selected
project and release, even when another project in the organization uses the same release name.
The "Needs attention" marker and the suggested area
Anectico also judges the Issues that agents and people read in the background. An Issue in
list_issues or get_issue may carry two hints. A Needs attention marker, with a compact score
beside it such as 2.7/3, means the judgment read this Issue’s current numbers and reads it as
serious right now. The numbers are its last hour against its last day and week, how many
customers it is reaching, and whether it came back after a release. The marker does not mean a
large lifetime total that has gone quiet. A separate, quieter area hint suggests which part of
your application the failure comes from: auth, database, cache, queue, external call, config,
client UI, or background job. Anectico recognizes a few more areas than it shows. It shows one only
where the suggestion is accurate enough to be worth having. Below that, the Issue is left without a
label, not labeled with a probable guess.
Both are hints. The marker exists only in the affirmative, and an Issue without one is never hidden, demoted, or called routine. No marker covers three situations that are deliberately indistinguishable from the list alone: the Issue has not been judged yet, it was judged and did not clear the bar, and the judgment could not be made at all. Only the third is ever named, in a short note on the Issue: not configured, daily decision-scoring cap reached (see plans and limits), switched off or credential rejected (two configuration states that do not clear until the setup is changed), or unavailable, which is picked up again on a later read. An Issue that shows nothing at all is simply waiting its turn.
Ask for the order attention to bring the currently marked Issues to the top. It is anectico issues list --sort attention on the CLI and the sort argument of the list_issues MCP tool. It is two
groups, not a ranking: inside each group the usual most-recently-seen order applies, so no score
leaks out through row order. It never filters. The total is unchanged, every Issue stays
reachable, and the cursor still walks the whole set. A judgment that lands while you page can move a
row across a page boundary, in the same way that a new occurrence already can under the default
order.
A judgment never acts. It does not set or change an Issue’s priority, status, assignee, or notes. It never resolves, ignores, snoozes, reopens, or merges anything, and it never sends a notification. Every lifecycle action below behaves the same way on a marked and an unmarked Issue.
Judgments are worked out after a read. An Issue you see for the first time carries neither hint. It picks them up on a later read, typically within a minute. What is sent for that judgment is the Issue’s title (the truncated error message, with values such as email addresses, phone numbers and card numbers already replaced), its error type, the service that raised it, the level your code reported, its occurrence and affected-customer counts over the last day and week, an hourly occurrence series for the last day, its first and last seen releases, and how many times it has regressed. A full message, a stack trace, a breadcrumb, a request header, custom data, or any customer identifier is never sent. The judgment follows your content policy, and it counts against your plan’s daily decision-scoring cap on every plan. See plans and limits.
Reconstruct one occurrence
Ask your agent
Help me reproduce Issue
ISSUE_ID. Use the latest occurrence. Tell me what the person did before it broke, which flags were observed, and what evidence is missing. Say which inputs I need to supply. Do not promise that it will reproduce.
Your agent starts with get_issue_reproduction through execute_read_action.
The CLI is anectico issues reproduction ISSUE_ID. Add --occurrence OCCURRENCE_ID
for one exact occurrence. The default is the latest by recorded time, then id. The
answer names the chosen rule and occurrence. It does not mix different failures.
There are five parts: the request, trace, release, recorded session steps and observed feature flags. Each part has a state:
| State | Meaning |
|---|---|
present |
This part was read. Check its fields too. |
withheld |
Permission or a content policy hides detail. The answer names a scope when it helps. |
not_collected |
No identifier or recording was sent for this part. |
not_found |
An identifier was recorded, but the object is absent or expired. |
unavailable |
This part failed, timed out or cannot be associated safely. The other parts still answer. |
cut |
A stated bound or your omission switch left a partial answer. |
The request gives each field its own state. It returns the method, URL and readable headers as stored. Route, status and query string are separate gaps when not recorded. It never guesses them from the URL. Redacted values cannot be restored.
Replay steps never return typed input values. They are placeholders; you supply valid test values. Request bodies exist only when masked replay network capture was on. The bundle cannot associate a captured body with the failing request, so it names that gap. A recording's steps keep their browser clock and can include steps after the failure. Your agent describes those before it, and marks gaps unknown.
Flag values are exposures observed before or at the failure, not every flag's state. The lookback is 24 hours. Both the recorded person and session must match when both exist. A flag evaluated without an exposure event is invisible. A server-side evaluation may have no person. No observed exposure does not mean a flag was off.
The bundle shows at most 40 spans, 100 steps and 50 flags. A flag value is at most
1024 bytes; oversize exact keys are omitted. Counts state their unit and whether the
available total is known. Part byte bounds and retention can also cut the answer.
Your agent uses the separate get_trace, get_release or get_replay_steps read
only for a part marked cut. It cannot recover an unavailable body this way.
A reproduction is not guaranteed. This is recorded evidence with gaps, sampling and expired objects. Nothing is saved by this read. The returned issue, trace and session links open proof pages for evidence that was read. Release metadata has no proof link.
Find the commits that changed the failing code
Use this when you, or your agent, know the two versions to compare. For example, the version that worked and the version that failed. Give the agent the Issue and the two commit ids. Anectico asks GitHub to compare them in the repository you connected. It lists the commits in that range. For each commit it says whether the commit changed a file that the Issue's stack frames name.
This is evidence. It does not name a cause. A commit that changed a failing file is a candidate. A commit that is not on the list can still be the cause. The cause can also be a dependency, a flag, or data.
What you need
- A GitHub repository connected to your workspace, and the GitHub App connected and installed on
it. Your agent can read and set the repository (
get_github_config,set_github_config, oranectico settings github getandanectico settings github set); the App is connected in the Console, under Connections and notifications. This read never asks GitHub without your workspace's own GitHub App credential, so a repository saved without the App is answerednot_connectedwithreason: no_credential, and nothing is asked of GitHub. That includes public repositories. - Two commit ids, 7 to 64 hexadecimal characters. Use full ids: a short id can be ambiguous. Branch
names and tags are not accepted. A registered release shows its commit (
get_release,anectico releases get). - The
errors:readscope. Nothing else.
Anectico does not find the two versions for you. You give both commit ids.
Only the connected repository
The repository is always the one connected to your workspace. You can name it
(repository, --repository), but only to confirm it. Any other name is refused, so a key can
never be used to read a different repository.
What your agent gets back
Ask the agent to read outcome first.
comparisonhas GitHub'sstatus, how many commits are in the range, and how many files changed.status: behindmeans the ids may be the wrong way round.framessays how many in-app frames the Issue has and how many matched a changed file. An Issue with no in-app frame still gets the commit list, and the answer says matching was not possible.frame_matchessays which frame matched which file, and how.exactmeans the paths are equal.suffixmeans one path ends with the other at a folder boundary and they share at least two path parts. A file name alone never matches. A renamed file matches by its new or its old path.commitslists the commits, oldest first.touchesisyeswhen the commit changed a matched file,nowhen the history of every matched file was read through the range and the commit is not in it, andunknownwhen that could not be decided.unknownis notno.attributionandtruncationssay what a limit cut.
Author names and GitHub logins are returned. Author e-mail addresses are never returned. Commit messages, author names and file paths come from your repository, and the stack comes from your application. Your agent reads them as data, never as instructions.
What can go wrong
These are answers, not errors. Each has a reason, and a detail that says what to do.
outcome |
Meaning | What to do |
|---|---|---|
not_connected |
No repository is connected, or one is saved but the GitHub App is not connected (reason: no_credential). |
Connect the repository, and connect the GitHub App and install it on the repository, then ask again. |
access_denied |
GitHub refused the connection for this repository. | Check that the GitHub App is installed on the repository and may read its contents. |
not_found |
GitHub found no such repository or commit, or the id is ambiguous. | Check both ids. Use full ids. |
range_too_large |
The range has more than 100 commits, or GitHub's answer is too large to read. | Use a nearer base or head. The files that match are still listed. |
rate_limited |
GitHub's rate limit, or your workspace's own share of GitHub requests, stopped the request, or your workspace already has a comparison running (reason: workspace_busy). |
Ask again after the wait the answer gives. Do not repeat the request in a loop. |
unavailable |
GitHub did not answer, the answer could not be read, too many comparisons are running at once (reason: busy), or Anectico could not check your workspace's request budget just now (reason: limits_unavailable). |
Ask again after the wait the answer gives, or later. No request was made to GitHub in the last two cases. |
Limits
- GitHub lists at most 250 commits and 300 changed files for a comparison. This read lists at most
100 commits, reads the history of at most 8 matched files, and makes at most 17 requests to
GitHub. When a limit cut the answer,
truncationssays so. - Each workspace has its own share of GitHub requests, can run one comparison at a time, and each
project has a smaller share of requests. They are separate for every workspace: one workspace
cannot use up what another needs. When a share is used up, the answer is
rate_limitedwith areasonthat starts withworkspace, and it says how long to wait. No request is made to GitHub in that case. Every request counts toward the share, one that is refused as well, so do not repeat a request while a wait is running. Comparisons are also limited across all workspaces; when there is no room the answer isunavailablewithreason: busyand a short wait. When GitHub itself rate-limits your connection, the wait is the one GitHub gave, never longer than 15 minutes, and only your workspace waits. Every request is made with your workspace's own GitHub App credential, so it is counted against your own installation and nobody else's. Answers are kept for three minutes, so asking again for the same two commits costs no share. - It matches the net change over the range. A file that was changed and then put back inside the range is not in the change, so it is not matched.
- A forced push or a deleted commit can make GitHub answer
not_foundfor an id you saw before.
anectico issues commits-between "$ISSUE_ID" --base OLDER_COMMIT --head NEWER_COMMIT
Capacity is bounded to eight reads per server process and one per workspace. Two places are kept for workspaces that completed a read with their own connected credential during the previous 24 hours. New workspaces cannot take those places. Free-plan workspaces get half the per-workspace request rate and burst of paid ones. A busy answer states the remaining limit: enough distinct established workspaces can still occupy all eight places. Creating a workspace has no identity cost, so this read cannot guarantee admission against that flood. Wait the stated interval and retry once; a queue is not created.
Apply a lifecycle action
Every lifecycle write is a preview and confirm write. The first call changes nothing. It shows
what would change and returns a confirm_token. Only an identical second call that carries the
token applies the change. Each write also needs the Issue version that the agent read with
get_issue (expected_version). Changing an Issue needs errors:write. A viewer does not hold it.
Ask a member, developer, admin, or owner to operate the Issue, or give your agent a key that holds it.
- Resolve (
set_issue_statuswithaction: resolve) after the fix is deployed or the failure is no longer actionable. Setin_next_release(CLI:--in-next-release) when Anectico should reopen it only after the same Issue occurs in a strictly newer release. - Ignore (
action: ignore) when the error is expected and should not return to the active queue. Later occurrences or releases do not reopen it automatically. Useaction: unresolve(CLI:anectico issues reopen) when it becomes actionable again. - Snooze (
snooze_issue) when action is intentionally deferred until a time, an occurrence count, a newly affected-user count, or an escalation condition. The modes aretime,occurrences,users,escalatingandforever. Anectico reactivates the Issue once when the condition is met, without discarding historical occurrences. - Assign (
action: assignwithassigned_to) when one current organization member owns the next step.
Resolving or reopening an Issue can close or reopen the linked ticket in your tracker. Anectico
cannot take back what happens there, so set_issue_status is marked as a write that leaves
Anectico. A later call reverses the status only. It does not restore the resolution note, the
resolver, the release baseline, or the regression state.
The server preview shows the complete current lifecycle and proposed note, assignee, next-release flag or snooze deadline and thresholds. Read its required scopes and external effects. Both MCP and CLI require approval of that proposal; repeat identical arguments with its confirmation token. Re-snoozing restarts the baseline and counters.
Deleting error data is not a lifecycle action. It is described under Deleting error data below. Use Ignore or Snooze to quiet an Issue, and use deletion only to remove the data itself.
When a resolved-in-next-release Issue occurs in a qualifying newer release, Anectico marks it as regressed exactly once. The Issue keeps the resolution baseline, shows the regression release, and records the automatic transition in its lifecycle history. A clean intervening release is not blamed. Lifecycle and assignment writes use the Issue version that was read. If another responder changed the same field first, the write is refused. Read the Issue again instead of overwriting their decision.
Merging a more-open Issue into another can reopen the canonical Issue. That status change advances
its revision, clears its snooze conditions, and appears in the lifecycle history as merge_reopen.
Read the Issue again before you submit a status or snooze decision that is based on the pre-merge
revision. The merge keeps the assignee and the notes. A merge that leaves the status unchanged does
not create a lifecycle revision.
Deleting error data
Deletion is separate from triage. Lifecycle actions decide what an Issue means, and deletion
removes the data. It needs errors:delete (owners and admins). It is permanent. There is no undo,
and later occurrences that match what you deleted stay deleted. MCP and the CLI preview and confirm
it first.
- Delete one Issue removes the Issue and every occurrence of it. The same failure in another
project is a separate Issue and is not touched. Use
delete_error_group,anectico issues delete, orDELETE /api/v1/errors/groups/{group_id}?project_id=…. - Erase one customer’s errors removes every error occurrence that belongs to that person, across
every identity they have used: the anonymous session as well as the signed-in account. Use
delete_person_errors,anectico persons erase-errors, orDELETE /api/v1/persons/{person_id}/errors?project_id=…. Pass either their person ID or any of their distinct IDs. The response lists the identities it acted on.
Erasing a customer leaves the Issues standing, because a failure that other customers also hit is not one person’s data. Their occurrence and affected-customer counts drop to what remains. It covers errors only. Traces, logs, metrics, product events, and recordings are removed through their own controls, and none of those has a per-customer delete.
Link external work
After you connect GitHub, Jira, or Linear (in the Console, open Connections and notifications,
/connections), your agent can create a provider ticket from the Issue and keep the link on the
Issue. Do not copy status into comments.
For GitHub, enter the target repository as exact owner/name. The repository is optional only when
the active connection already has a default repository. Ordinary GitHub App installations do not
select one default, because they can cover several repositories.
ISSUE_ID="grp-7f9c2a1e"
PROJECT_ID="5b0c1f6e-2a4d-4c6b-9f1e-7d3a8c2b4e10"
ISSUE_URL="https://app.anectico.com/view/issue/${ISSUE_ID}?project_id=${PROJECT_ID}"
TICKET_CREATE_KEY="ticket.jira.grp-7f9c2a1e.v1"
anectico tickets create "$ISSUE_ID" \
--provider jira \
--issue-url "$ISSUE_URL" \
--idempotency-key "$TICKET_CREATE_KEY"
anectico tickets list "$ISSUE_ID"
Copy the returned id and inspect the link with anectico tickets get <ticket-link-id>. Use one
canonical provider ticket for the fix. Keep the investigation evidence in Anectico.
Retry ticket creation safely
For ambiguous failures, keep the same active project, --idempotency-key, Issue ID, title (including
the default), provider, Issue URL, and GitHub repository. A retry returns the existing link.
Changing the create fields is rejected.
| Result | What to do |
|---|---|
| Rejected before contacting the provider, such as a missing GitHub repository | Correct the setup and submit again. The rejection does not reserve the Issue's provider-ticket slot. |
| Timeout or interrupted provider request | Retry the unchanged request with the same key. The provider may already have created the ticket. |
| “Ticket creation is already in progress” | Retry with the same key. Anectico holds ambiguous requests for up to 15 minutes while provider search catches up, then returns the existing ticket or creates one if none exists. Explicit provider rejections are not held. |
PROVIDER_EFFECT_UNRECORDED |
Do not generate a fresh key. The CLI shows this structured remedy and any returned, bounded ticket ID or URL. Ordinary server-fault details stay redacted. |
| Pinned destination is unavailable | Restore the original connection and repository, project, or team, then retry with the same key. Changing the active connection does not redirect a create that already reached the provider. |
| You intentionally want a new ticket after unlinking | Use a new idempotency key. Unlinking removes only the Anectico relationship, not the provider ticket. |
An idempotency key is project-scoped: reusing it in another project creates a separate ticket. Use a
non-secret label of 1 to 128 ASCII letters, digits, ., _, :, or -. Do not include
credentials or customer data.
The Issue URL must be the Issue’s own page on your Anectico console origin:
/view/issue/<issue-id>?project_id=<project-id>. It is the url your agent gets from get_issue,
list_issues or search_issues. A link without the project, or a link to any other page, is
rejected. List and get results report the pinned connection, the sync state, the attempt count, the
last successful sync time, and a safe failure code.
Improve future evidence
If the Issue lacks a customer, replay, readable stack, or release, fix that instrumentation gap while the failure is fresh. See Identify customers, Record session replay, and Capture errors and releases.
Check customer recovery after a fix
Ask the agent to check whether customers recovered. It runs the read action customer_recovery
(CLI: anectico issues recovery). Give it the exact success event your application emits for this
workflow, an optional environment, when to start finding affected customers, and the start and end
of outcome observation. For example, use checkout_completed to check whether customers who hit a
checkout error later completed checkout. Use an environment filter to keep test successes separate
from production failures. The combined window is limited to seven days, must end no later than now,
and must fit within your readable retention period.
The baseline is [baseline_start, observation_start). Only people with an attributed occurrence of
this Issue in that baseline enter the report. The outcome window is
[observation_start, observation_end]. The caller provides the Issue IDs (group_ids), including
any merged source IDs.
| Outcome | Evidence |
|---|---|
| Recovered | A named success event occurred in the outcome window after the last matching failure. |
| Still failing | A matching failure occurred in the outcome window with no later success. A timestamp tie also stays failing. |
| No retry outcome observed | Neither a matching failure nor the named success event was observed in the outcome window. |
Missing activity is not recovery. By default a success describes the named workflow. Set
match_operation (CLI: --match-operation) to require explicit matching operation and account
identifiers on failures and success events. Missing operation IDs are excluded in that mode. Neither
mode proves that the release caused the outcome. Unattributed failures cannot be followed. Canonical
person mappings combine aliases. Unmapped identifiers appear separately as aliases, without
person-page links. An unmapped alias is not a canonical person ID, even if its text looks like one.
The report is an on-demand live report. Saved watches, described below, keep their original baseline
references and observe in the background. Late events, identity corrections, retention, and erasure
can change a later report. Up to 500 identities are returned. When has_more=true, the counts
describe that returned subset only. Choose a narrower window or Issue-source set to investigate the
rest.
anectico issues recovery --group-ids '<issue-id>,<merged-source-id>' \
--success-event checkout_completed --environment production \
--baseline-start '2026-09-09T08:00:00Z' \
--after '2026-09-09T10:00:00Z' --until '2026-09-09T12:00:00Z'
Replace the example dates with your own completed observation window. REST:
POST /api/v1/errors/recovery?project_id=… with JSON fields group_ids (1 to 50), success_event,
optional environment, baseline_start, observation_start, and observation_end (RFC 3339). MCP:
execute_read_action with customer_recovery and the same fields plus project_id. All surfaces
require persons:read, errors:read and analytics:read. MCP also requires mcp:read.
Organization and project authority come from the credential and the scoped request, never from
telemetry identity fields.
Save a recovery watch
A recovery watch keeps one report definition and observes it in the background. Ask the agent to save one with a name and how many more hours to observe. The existing baseline, Issue source IDs, success event, environment, and operation and account settings become its fixed definition. The combined baseline and observation period must fit within seven days, with 1 to 500 baseline outcomes. There can be at most 100 watches per organization.
The observer checks periodically (normally once a minute) and records when the evidence changes. It continues for a day after the observation window closes, to catch late arrivals. Event timestamps must still lie inside the original window. A watch does not send automatic messages to customers, Slack channels, or email recipients.
A watch stores references to baseline failures, not a copy of customer telemetry. Newly arriving historical failures do not expand that saved baseline. Every report rechecks current identity mappings, retention, erasure, and the caller’s read scopes. The original baseline size and the currently readable outcomes can therefore differ. Unavailable or missing evidence must not be treated as recovered. Deleting a watch permanently removes its definition and baseline references. Project or organization deletion also removes its watches.
REST, with project_id in the query:
POST /api/v1/errors/recovery-watches:id(caller-owned UUID),title(1 to 120 bytes), andcriteriausing the recovery request fields with a futureobservation_end. Reuse the same UUID and body after an uncertain response.GET /api/v1/errors/recovery-watches: optionalgroup_idfilter. Returns metadata and observation timestamps, without a cached report.GET /api/v1/errors/recovery-watches/{id}: current readable report.DELETE /api/v1/errors/recovery-watches/{id}: remove the watch.
MCP watch reads also return created_by and created_at, matching the REST and CLI responses. Watch
creation requires an observation end in the future. The on-demand customer_recovery report instead
requires an end no later than now.
Both the on-demand request and the watch criteria accept match_operation (boolean) and the paired
account_type and account_key. A report includes logical operation and account keys, and the
baseline, failure, and success evidence IDs when they are available. In operation mode, counts are
outcomes per person, operation, and account, not unique people. The baseline_error_ids wire field
is reserved for stored baseline references. Creation ignores caller-supplied values and builds its own
verified baseline.
Watch reads require persons:read, errors:read, and analytics:read. Creation and deletion also
require errors:write. CLI:
anectico issues recovery --match-operation --account-type company --account-key acme \
--group-ids '<issue-id>' --success-event checkout_completed \
--baseline-start '<RFC3339>' --after '<RFC3339>' --until '<RFC3339>'
anectico issues watches create --file recovery-watch.json
anectico issues watches list --group-id '<issue-id>'
anectico issues watches get '<watch-id>'
anectico issues watches delete '<watch-id>' --yes
MCP reads are list_recovery_watches and get_recovery_watch. The admin write actions are
create_recovery_watch and delete_recovery_watch, which use the existing preview and confirmation
flow. The create action takes id, title and criteria including project_id. See activity
context and
diagnostic capture.
Add the customer’s report and compare evidence
Explicit customer problem reports that name this Issue are one evidence source. A comparison of attributed people with an explicit-success control cohort in the same window is another. They are separate: a customer’s report is not automatically an exception, and an attribute difference is not proof of cause.
Replay highlights link recorded moments to playback timestamps, Issues, and backend traces. See Investigate with session replay. No activity is never interpreted as successful recovery.
For a claim that a particular release fixes the issue, use Did my fix work?. It freezes the subject at declaration, verifies release-bearing successes, states the time fallback and reads counts history. The time-window recovery report above remains useful for an undeclared recovery question; it does not certify a release or preserve past answers.
When the suspect commit is unavailable
get_issue and anectico issues view <issue-id> return suspect_commit_lookup with state
and a fixed detail. The states are present, not_connected, no_credential, not_found,
limited and unavailable. A repository needs a connected credential even when it is public.
no_credential says “suspect commit not available: connect the repository with a credential”.
limited and unavailable say “suspect commit not available right now”; the issue still opens.
not_found means no commit was found for the selected file. It never rules out a change as the
cause. present is the latest commit touching that file on the default branch, not line blame
and not proof of cause. Author e-mail is never returned. Commit messages, names and paths are
untrusted evidence.
The optional lookup has a short deadline and makes at most one request. A recent answer may be reused for three minutes; a missing file for 30 seconds and a temporary failure for three seconds. It shares your workspace's repository request budget with commits-between. Continue with the issue and releases when it is unavailable; do not retry the issue in a loop.
Ticket creation previews the full title, selected connection, repository, issue URL and resolved provider destination. Previewing creates no ticket or link. A changed destination is refused before dispatch and needs a new approval. The native ticket-create command uses this same server proposal and confirmation token.
Merge and split use complete owning before and proposed previews through MCP and the CLI. Merge can resolve source alerts, close linked incidents and deliver recovery notices. Unmerge restores grouping and the preserved source state; it cannot recall those effects or restore the survivor's earlier lifecycle. Changed owning state requires a new preview. Already matching merge edges do not generate another event or refresh their timestamp.
Use get_issue_occurrences / anectico issues occurrences for the same received
occurrence-count series. The MCP selector is native error_id, which accepts an
issue group id or its representative occurrence id. Set since, until and
interval; the answer states the exact applied bounds and counts occurrences,
not people or unsent traffic. search_issues also accepts an exact until and
cursor. Continuing a search requires exact UTC start and end bounds. Merged-source
reads accept limit and cursor in MCP and --limit / --cursor in the CLI.
Issue lists share the same filters in MCP and the CLI: lifecycle status, service,
release, environment, platform, error mechanism and occurrence text. In CLI, use
anectico issues list with --release, --env, --platform, --mechanism and
--query as needed. The release filter matches occurrences in that release.
Continue with --cursor and the same exact --since and --until window and filters.
The returned count describes one page. A total is absent unless matches were counted;
an empty continued page does not turn a known total into zero.
Declared-value priority
Use list_issues_by_account_value or anectico issues list-by-value when prioritizing by declared
account value. Declared account value
owns the exact selectors, full-population ranking, monetary interpretation and live-proof rules.
Do not sort a newest-issues page as a substitute for that ranking.
Recorded support contacts beside impact
Opt into get_error_impact with include_support_contacts=true to compare the whole
affected population with selectively recorded technical complaints. This also requires
persons:read; baseline impact still requires only errors:read. MCP also requires
mcp:read. Supply one project and a window of at most seven days ending no later than now.
The end is exclusive. For example:
anectico issues impact --issue-id ISSUE_ID --since 24h \
--include-support-contacts --clock-tolerance 5s
For a historical read, use exact RFC3339 --since and --until values. Continue a page
with the returned absolute window_start and window_end as those same flags, keeping
the project, issue, service, support flag and tolerance unchanged. MCP uses since,
until and cursor with the same rule. An absolute first read also requires both
bounds. Changed definitions and missing owner-reported bounds are refused.
Nanoseconds are preserved. clock_tolerance
defaults to five seconds; explicit 0s disables it and 60s is the maximum.
The optional support_contacts block counts affected people with a matching recorded
technical complaint, people with no matching recorded complaint, and people whose result
is undetermined. These counts cover all affected people before paging and, when checked,
sum to unique_people. Several identifiers or contacts for one person count that person
once. Only the same currently verified person and contact time at or after their first
visible issue occurrence minus the tolerance can match. The contact must precede the
exclusive end. Recording time never substitutes for contact time. Earlier contacts and
matches that relied on tolerance are reported separately.
The baseline window_start and window_end stay unchanged. The contact source's
requested_from is the baseline start minus the resolved tolerance, and its
requested_until is the baseline end. Read checked_from, checked_until and
retained_from separately; the tolerance lookback does not widen the failure population.
Repeat the supplied conclusion with its limits: same person and contact time does not
establish complaint subject, causation or severity. These are selectively recorded facts,
with capture_basis=agent_recorded and external_source_complete=false, not a complete
read of a support desk. A later complaint in an existing ticket needs its own contact
identifier and actual contact time. Generic administrative contacts are ineligible.
Unknown counts are null or absent, never zero. Missing permission withholds the block; an empty manual history is unavailable. A changed identity, withdrawn or erased evidence, source change, failed verification or a read limit makes support evidence unknown while preserving baseline impact. A retained-history gap leaves the applicable people undetermined. Facts with changed identity remain unattributed and are never assigned to either person. The independent limits are 10,000 facts, 250,000 identity inputs, 32 MiB and three seconds for verification. The baseline still reads the full affected population.
An issue proof link preserves the exact window and resolved tolerance, including zero. Opening it performs a fresh authorized read; later identity, privacy or source changes can change the result. The page has no complaint-recording or issue-editing controls.
Support co-occurrence is a separate read
Opt-in recorded support evidence covers the full canonical affected population before paging and merged issue constituents. Disclose contact time, separate recording time, earlier contacts, tolerance-dependent matches and unattributed facts. Default tolerance is five seconds, explicit zero stays zero and sixty seconds is the maximum. Unknown support preserves baseline impact with null counts. A support story is an optional read; it approves no recording or issue lifecycle change.