Plan and prove product events
Have your agent choose events from your code, send them with stable names, identities and message IDs through an anonymous visit, a login, a logout and a second person, and prove the exact samples arrived.
On this page
Product events record what people do in your application: a checkout completed, a plan upgraded, a job finished. This page is the instrumentation workflow for your agent. It chooses the events from your code, sends them with identifiers a test can find again, and asks Anectico whether the exact samples of a controlled run arrived under the right person and against your tracking plan. The mechanics of one call, sampling declarations and capture quality are in Capture product events; measuring the events later is in Measure product events.
What this covers
| Path | Covered |
|---|---|
| Node.js server with the Anectico JavaScript SDK | Yes |
| A server in any language, over HTTP with no SDK | One tested recipe. See Integrate without an SDK. |
| Browser, Go, Python and mobile applications | Not by this workflow. Their SDK guides still apply. |
Ask your agent
Find where checkout completes in my service and send a
checkout_completedevent with the cart value. Link a login to the earlier anonymous visit, record the account, and run it as two people. Then verify the exact events against tracking plan revision 3.
| Job | MCP tool or action | CLI command |
|---|---|---|
| Read the pinned tracking-plan revision | get_tracking_plan |
anectico analytics tracking-plans get |
| Verify the exact events, in one verdict | verify_integration |
anectico doctor integration |
| Verify the exact events, with the full per-event answer | verify_integration_events |
anectico doctor events |
Sending the events is your application's job, with a server_capture key that holds only
analytics:write. See Native intake keys.
Choose the events from your code
Your agent reads the code and picks the lines where something meaningful really happens: the handler that completes a checkout, not the button that starts it. A good event has:
- a stable name that describes the occurrence in the past tense, such as
checkout_completed, at most 200 bytes, with no identifier or personal data in the name; - property names your team will still understand next year, and values that are not personal data. Email addresses and similar values are redacted on arrival. See What Anectico redacts and withholds;
- one name per kind of occurrence, so a count of the name means something.
If the project already has a tracking plan, the agent reads the revision it will pin and uses its event and property names. It does not change the plan without your approval; a plan is configuration managed as described in Manage tracking plans, and a recipe can start one (start from a recipe).
One person through the journey
Identity comes from the server's own session, never from the request body or a header the browser can set. A Node server answers many people at once, so the example builds one identity and one event client per request. One shared client would put one person's events on another person.
| Moment | What the application sends | What to expect |
|---|---|---|
| Anonymous visit | Events under the visitor ID from the server's session | An anonymous person |
| Login | identify with the stable user ID, the earlier visitor ID as the alias, and the person's properties; then the account with group |
The earlier anonymous events join the person |
| Business action | The event, with the account recorded at event time | The event belongs to the identified person |
| Logout | The next visit gets a new visitor ID | A new anonymous person, not the one who logged out |
| Second person | The same steps under another user ID and account | A second person; the two never merge |
Use an application-owned ID such as a database user ID, not an email address. See Identify customers.
Message IDs, sessions and sources
- Message ID. Choose it before the first send and derive it from something the test controls, such as the request ID plus the event's purpose. An ID the application cannot reproduce selects nothing. A retry keeps the same ID and the same content; reusing an ID with different content refuses that event.
- Session. Send a
session_idwhen the application owns the browsing session. The Node SDK's server events carry one session for the whole process rather than one per request, so the Node example declares no session and its verification checks none. - Source. The admitting source comes from the capture key, never from the event. Verification selects an event by the source that admitted it, so the agent keeps the capture key's source ID.
- Control events.
identifyand$groupidentifyupdate the person and the account and store no event row. They have no message ID a read can select, so their outcome is the acknowledgement or the client's drain. Verify the events that follow them.
What acceptance means
Every capture answers with an acknowledgement per event: queued, rejected or uncertain. Queued means the event was accepted for processing. It does not mean it is stored, readable, or that an identity update has finished. A rejection is final. Uncertain events are retried a bounded number of times with the same bytes and the same message ID. See Capture acknowledgements.
Prove the exact sample
The agent selects only the samples whose delivery was queued: each with the event name, message ID, the capture key's source ID and the declared identity, and optionally the session. With a pinned revision it adds the plan ID and the exact revision; without a plan it can ask for named property checks of type and presence. Then:
anectico doctor integration --file verify-job.json -o json
The request and answer are in Integration job
verification and, for every field of the underlying
read, Integration event verification. A verified sample
means each selected event was stored once under that name, message ID and source, the declared
identity matched and resolved to a person (with persons:read), and the plan revision declares the
event with matching property types (with tracking_plans:read and agents:content:read). The
answer never returns a property value.
It does not mean other events, other people or other code paths are instrumented, and another person's correct events cannot satisfy your sample. An early negative answer is usually delay. Waiting, the bounds and two known gaps are on What integration verification proves and what it does not.
Test traffic is ordinary traffic
Anectico does not yet reserve a population for verification traffic. Test events count in the
project's measurements and event allocation, and are retained, exported and erased like any other
event. Use clearly synthetic identities such as anectico-verification-user-a, tell the person who
owns the project, and never erase a person only to tidy up. A hand-sent event from the command line
is a pipe check, not evidence that your application sends anything.
Not covered yet
Browser and mobile events, Go and Python servers, errors, traces, logs, replay, surveys and product experiments. See Ask your agent to integrate Anectico.