Feature flags in your application
Have your agent reuse or create a flag, read it on your server, take the real treatment branch, record the exposure, and prove that the exact decision arrived under the right definition version.
On this page
A feature flag decides which branch of your code a person gets. Your agent wires that decision into your server, records an exposure each time the application uses a decision, and then asks Anectico whether the exposures of a controlled test arrived with the value and flag definition version the application reported. This page is the instrumentation workflow. Check rollout health covers flag configuration, rollouts and measuring exposures later.
What this covers
| Path | Covered |
|---|---|
| Node.js server with the Anectico JavaScript SDK, remote decisions | Yes |
| Node.js server with the SDK, local evaluation | Yes, for person-property targeting only |
| A server in any language, remote decisions over HTTP | One tested recipe. See Integrate without an SDK. |
| Browser or mobile application | Separate client-delivery workflow; see browser flags and mobile flags and headless surveys. The server sample verifier below does not qualify those SDK integrations. |
| Go and Python servers with their SDKs | Not by this workflow. Their flag clients record only the earlier exposure fields, so the exact checks below cannot verify them. |
A browser or mobile app evaluates flags with a client delivery key that holds only flags:evaluate
(from a page or app); this workflow does not yet
integrate or verify that path. The flags key this page uses reads every flag definition of the
project, so it must never reach a browser or an app.
Ask your agent
Add the
new-checkoutflag to my checkout service. Reuse it if it exists. Serve the new branch to the pro plan, record the exposure, run the service as two people, and verify exactly what arrived.
| Job | MCP tool or action | CLI command |
|---|---|---|
| Read existing flags | list_flags, get_flag |
anectico flags list, anectico flags get |
| Create a flag, after a preview you approve | create_flag |
anectico flags create |
| Learn what Anectico decides for a known person and the flag's current definition version | decide_feature_flags |
anectico flags decide |
| See exactly what a client application gets for named keys | evaluate_client_flags |
anectico flags evaluate |
| Download the local-evaluation snapshot | get_local_evaluation_snapshot |
anectico flags snapshot |
| Verify the recorded exposures | verify_flag_integration, verify_integration |
anectico doctor flags, anectico doctor integration |
Flag reads need flags:read and flag writes need flags:write. A flag your agent decides itself
checks Anectico's evaluation, never your application, and it is never evidence that the application
called the flag.
The flag
Your agent reads before it writes. It reuses a flag that exists and creates one only when none fits and you approved the plan. The preview shows the complete proposed definition; after you approve it, the agent repeats the identical arguments with the confirmation token and reads the flag back. A valid definition, a preview and a creation receipt are configuration: none of them shows that your application reads the flag. Changing a flag that already exists is a different write with its own version check and preview.
Credentials and addresses
| Setting | What it is |
|---|---|
| Decision address | The address that serves POST /api/v1/decide and the local-evaluation snapshot. |
| Capture address | The address that serves POST /api/v1/capture, where exposures are sent. |
| Flags key | A project-bound management key with only flags:read, held only in server secret configuration. |
| Capture key | A server_capture key with only analytics:write. It must be a different key from the flags key. |
| Project | Required for local evaluation, which is bound to one project. Remote decisions take it from the key. |
Your agent's own key is a third credential that only the verification uses. See Ask your agent to integrate Anectico and Native intake keys.
A decision uses the person properties your application sends with the request. A key that holds only
flags:read does not read the person's stored profile properties, so the application sends every
property the flag's rules use.
What the application does on every read
- Takes the person from the server's own session, never from the request body.
- Supplies every property the flag's rules use.
- Asks for the decision: with the SDK,
reloadandgetFeatureFlagDetailson a request-scopedFlagsClientfor remote evaluation, orrefreshonce andevaluateon aLocalFlagsClientkept for the process; over HTTP,POST /api/v1/decide. The reference is JavaScript flag-client reference. - Serves the branch from the value. The served value decides the code path, not a log line.
- Sends one exposure to the capture address with the capture key, through the exposure callback. Derive its message ID from the request and the flag so a retry keeps the ID, and pass a test-case ID on the controlled run.
- When no decision can be read, serves the application's safe default and sends no exposure.
The Node example keeps all of this in one file so the integration is the difference between the application before and after.
What a read means
| What happened | What the application serves | Exposure | What it is |
|---|---|---|---|
| Evaluated and matched | The treatment | Yes, evaluated, not a fallback |
A decision |
Evaluated and not matched, value false or a control variant |
The control | Yes, evaluated, not a fallback |
A valid decision. false is a value. |
| The request failed, the answer was not 200, or the flag is missing | The application's default | None | An unavailable decision. It is not false. |
| The server answered with a fallback after an evaluation error | The default value | Remote: yes, with evaluation_error, is_fallback: true and no version |
A fallback, not a decision. The one-verdict job verifies only successful use; check a fallback with anectico doctor flags. |
| Local evaluation with a stale snapshot, an unknown flag, or a cohort, group or saved-audience target | No value | None | Unavailable or unsupported_targeting. Evaluate that flag remotely. |
Local evaluation supports person-property targeting only. The snapshot omits flags that target saved audiences, so a flag omitted from it is not an inactive flag.
The exposure the application records
Each served read records a $feature_flag_called event whose reserved properties say what was used:
the flag key, the value, the exact definition version (only for a successful evaluation, never for
a fallback), the evaluation status, whether the value is a fallback, remote or local, the local
snapshot version, your test-case ID, and an input context. The JavaScript SDK records them for you;
an application without the SDK sends them itself. Every property and the exact form of the input
binding are on Feature-flag exposure verification.
An exposure is application-reported use. It never proves that a person saw the treatment, and it says nothing about a code path that records no exposure.
Versions, inputs and the local and remote pair
- The version is the flag definition's version. It does not version person properties, groups, cohorts or audiences.
- The input context says whether the evaluation used only inputs your application supplied
(
explicit_inputs), also used stored context (hydrated_context), or is unknown (unestablished). The input binding is your application's own declaration of its explicit inputs. Anectico compares two bindings for equality; it never recomputes or authenticates them. - A local and a remote decision are comparable only when exactly one of each was selected, both were
successful non-fallback evaluations under the same version, both used explicit inputs with every
targeting input present, and their bindings are equal. Then the answer says whether the values
agreeordisagree. Otherwise it isnot_comparablewith reasons. A remote decision that used stored context iscontext_not_established: today's context is never reread as proof of the context at evaluation time.not_comparabledoes not mean the treatments differ.
Prove the exact decision
Run the application as a person the flag matches and one it does not, so the run contains a
successful true and a successful false. Keep the exposure message IDs, the served branch, the
version Anectico returns for the flag, and the capture key's source ID. Then ask for the flags job:
anectico doctor integration --file verify-flags-job.json -o json
The request, the checks and the states are in Integration job
verification. The verdict is verified_sample only
when every selected exposure matched the value, version, status, fallback flag, mode and input
context the application reported, under the declared identity. The scopes are query:read,
analytics:read and flags:read, plus persons:read for identity and agents:content:read for the
recorded fields; without those two the checks are withheld.
A verified exposure proves that the application recorded that decision. It does not prove that every flag read records an exposure, that other people were treated the same way, or that anyone saw the change. How long to wait, the bounds and the known gaps are on What integration verification proves and what it does not.
Not covered yet
The server workflow's exact-sample qualification does not cover browser and mobile flag clients, Go and Python flag exposures, or flags that rely on stored person, group or cohort context for a verified local and remote comparison. Use the linked client guides for their implemented APIs and delivery checks. Product experiments need isolated runs of their own.