Skip to content
Console
Browse documentation
Reference

Integration job verification

Verify the one integration job your application test exercised, product events or feature flags, without needing a test error, trace, log or replay.

On this page

After your agent wires Anectico into an application and runs a controlled test, it asks one question about the job it integrated: did the selected events, or the selected flag exposures, arrive as expected? Integration job verification answers that question and nothing else. A product-event integration needs no test error, trace, log or session replay to verify, and a verified job says nothing about those signals either.

It is a read: it sends nothing, changes nothing, stores no report, runs no model and is never rerun for you. Your agent decides when to call it and when to retry.

Surface How
REST POST /api/v1/instrumentation/verify with the JSON request as the body
MCP execute_read_action with action verify_integration and the JSON request as arguments
CLI anectico doctor integration --file request.json (plus the usual --project and --json)

Project-bound keys may omit project_id; naming a different project is refused. The CLI refuses a file whose project_id contradicts --project.

Jobs

job selects exactly one job, and each job accepts only its own fields:

job Fields Checked by
product_events samples, optional tracking_plan_id + tracking_plan_revision Integration event verification
flags exposures, optional compare_local_remote Feature-flag exposure verification

Every request also carries start_time and end_time: the event-time window [start, end), millisecond precision, at most one hour. The selection fields have exactly the meaning, bounds and presence rules of the read that checks them, so session_id: "" still checks for an empty session and an omitted session_id skips the check.

These are refused with 400 before anything is read: a missing or unknown job; a field of the other job (for example exposures on a product_events request, even as an empty list); an unknown field; a field given twice; a body org_id; and, for the flags job, an exposure whose expected_evaluation_status is not evaluated or whose expected_is_fallback is not false. The flags job verifies successful application use; to verify that your application recorded a fallback or an evaluation error, use feature-flag exposure verification directly.

errors, traces_logs, replay, surveys and experiments are not jobs here yet and are refused by name. For an error or trace story, use anectico doctor instrumentation as described in verify your setup.

Product events

{
  "project_id": "2d3c9f8e-1a1b-4c5d-9e0f-123456789abc",
  "job": "product_events",
  "start_time": "2026-10-15T09:00:00Z",
  "end_time": "2026-10-15T10:00:00Z",
  "tracking_plan_id": "c0ffee00-1234-4abc-8def-0123456789ab",
  "tracking_plan_revision": "3",
  "samples": [
    {
      "event": "checkout_completed",
      "message_id": "test-run-42-checkout",
      "source_id": "7f1e2d3c-4b5a-4968-8776-5544332211aa",
      "distinct_id": "test-person-42",
      "session_id": "test-session-42"
    }
  ]
}

Feature flags

{
  "job": "flags",
  "start_time": "2026-10-15T09:00:00Z",
  "end_time": "2026-10-15T10:00:00Z",
  "compare_local_remote": false,
  "exposures": [
    {
      "message_id": "test-run-42-flag",
      "source_id": "7f1e2d3c-4b5a-4968-8776-5544332211aa",
      "flag_key": "checkout_v2",
      "expected_value": true,
      "expected_flag_version": "2026-10-15T09:30:12.123456Z",
      "evaluation_mode": "remote",
      "test_case_id": "case-42",
      "expected_evaluation_status": "evaluated",
      "expected_is_fallback": false,
      "expected_input_context": { "basis": "explicit_inputs", "required_inputs_present": true },
      "distinct_id": "test-person-42"
    }
  ]
}

compare_local_remote defaults to false: the answer then makes no claim that local and remote evaluation agree, and carries no comparison. With true, each flag key and test case must have one local and one remote exposure that are comparable and record the same value.

The answer

Field Meaning
verdict verified_sample when every required check is observed_match; failed when a required check is mismatch or not_observed; undetermined otherwise.
checks The required checks in the job's order, each with check, required, state, reason and a selector (index into your samples or exposures, and the event, message_id, source_id, flag_key, test_case_id and property key it is about).
population Counts of your selected samples or exposures: requested, observed, not_observed, ambiguous, undetermined, verified, failed. basis is explicitly_selected_application_samples.
start_time, end_time The window as requested.
effective_start_time, effective_end_time The window the read actually covered after readable history; empty when nothing was read.
checked_at When the answer was released.
sources The read behind the job (product_events or flag_exposures) with its read_cutoff, start and finish clocks, limit_reached and limit_reason.
upstream_completeness Always unknown.
limitations Plain statements of what this answer does not establish.
links Always empty: there is no proof page for this read.
evidence The full answer of the read that checked the job, under product_events or flags, exactly as that read returns it.

The check names are:

  • product_events: tracking_plan (when a plan is pinned), then per sample event, distinct_id, session_id (when requested), groups (the account, when requested), identity, plan_declaration (with a plan) and one property per declared or requested key, then read_budget.
  • flags: per exposure event, distinct_id, session_id (when requested), identity, flag_key, value, definition_version, evaluation_mode, test_case_id, evaluation_status, is_fallback, input_basis, required_inputs_present, input_binding; with compare_local_remote, one local_remote_comparison per flag key and test case; then read_budget.

States keep the meaning of the read that produced them: observed_match, mismatch, not_observed, withheld, unavailable, ambiguous, and not_comparable for a comparison that could not be established (its reason is the first reason the flag read gave, such as missing_inputs). read_budget is unavailable with a limit_… reason when the read reached a limit. A withheld, unavailable, ambiguous or not-comparable required check never verifies, and an observed event survives as its own fact next to it.

Scopes

Scope What it needs it for
query:read Required for every job. (MCP also needs mcp:read.)
analytics:read Required for both jobs.
flags:read Required for the flags job.
persons:read The identity check. Without it identity is withheld.
tracking_plans:read The tracking_plan and plan_declaration checks. Without them they are withheld.
agents:content:read property checks and the recorded flag fields. Without it they are withheld.

A job's required scope that is missing refuses the request (403) before anything is read. If a scope, the project's content policy or the selected data changes while the read runs, no answer is released: the call fails and you start a fresh read.

Limits

The window is at most one hour, with at most 20 samples or exposures and at most 20 property checks per sample. Every other limit is the limit of the read behind the job and is returned under evidence. The whole call stops after 20 seconds. Normal rate limits and agent budgets apply; there is no separate fee.

Two limits of the shared product-event read are listed in every answer's limitations:

  • The read is not narrowed by date: it reads every retained event of the selected names in the project, so a project with millions of them can reach a read limit and report unavailable for an event that exists. Select fewer distinct event names per call in that case.
  • Two sources that send the same event name, timestamp, distinct ID and message ID keep one stored event, so verifying one source can report not_observed because the other source's copy was kept. Use a unique message_id per source in tests.

Retrying

A call that fails with 429 (another verification for the project is running), 409 or 503 released no answer; retry the same request shortly. A not_observed or unavailable check right after the test usually means the event has not been read yet: wait briefly and verify again with the same request. Do not resend events to make them appear.

What a verified sample does not prove

  • That other events, flags, people or application paths are instrumented: only the selected samples of this one job were checked.
  • That errors, traces, logs or replay work: they were neither required nor checked.
  • That everything the application emitted arrived: SDK configuration, sampling and client-side loss are not observed, and an accepted intake request is not readable evidence.
  • That a person saw anything, or that the application authenticated its own inputs.

The stages between your code and stored evidence, how long to wait before trusting a negative answer, and what has and has not been run are on What integration verification proves and what it does not.