Suppose you ask Codex to inspect your checkout code. It finds a failure branch that might swallow an error. Then you ask: "Did the payment at 16:20 on November 5 go through?" Now you need a record of that attempt. The code shows what might happen after a click; it cannot tell you whether a request was sent or what the provider returned.
Pasting logs or a CSV into the chat works once in a while. With several engineers handing off the investigation, somebody must keep checking which extract covered which hours, in which time zone, and whether the backend logs were included. A queryable event record gives Codex a more reliable place to start.
From a frontend event to a Codex query
Reporting and retrieval take separate paths:
Frontend click --trusted backend reports with write token--> External data store Codex --calls an MCP query tool-------> Authorized records The frontend passes the click to a trusted business backend, which submits it with a write token. The data service validates and acknowledges the event before asynchronous loading; a scoped read credential in Codex's MCP connection retrieves it later. The connection cannot collect a payment outcome the application never reported. The Codex MCP documentation covers the connection itself.
An existing event platform can serve the same purpose if it exposes properly scoped queries. A separate reporting layer is more useful when small apps and scripts produce scattered events and you do not want to grant an agent arbitrary SQL access to production systems. The next Codex session can query the record again instead of relying on a chat summary.
What the click record actually says
The event below is invented; it is not a customer transaction. At 16:20 Singapore time on November 5, 2026, a frontend observes a pay-button click. A trusted business backend submits the event under an active, authorized default_behavior_events v1 schema:
{ "schema_id": "default_behavior_events", "schema_version": 1, "data": { "report_source": "fe", "client_time": "2026-11-05T08:20:00Z", "scene_type": "checkout", "trace_id": "trace-example-001", "action_type": "click", "target_type": "button", "target_id": "pay" } } The business backend holds the write token; the browser never embeds a long-lived credential. The trusted MCP connection environment holds a separate read token. In this example, we use report_source=fe for a frontend-origin click even though the backend submits it; agree on that convention with whoever collects and reports events. Server-side credentials determine the tenant and project, regardless of client-supplied event fields. A trace_id can connect frontend and backend records only if the request really carries it through. The click observation alone does not prove a subsequent payment request reached the backend endpoint that handles payment.
To answer "did the payment succeed?" the services that own later steps must report them: the backend receiving the request, the gateway responding, and the order state changing. A frontend cannot report a gateway outcome it never saw. A provider transaction ID might have to be verified in a separate authorized system; card details and payment secrets do not belong in this behavior event. These observations form a trail only when each reporting service knows what it actually observed.
Give a checkout attempt its own trace_id, distinct from a user's session ID. Two quick clicks might produce two frontend events and one backend request. Or the backend might receive two requests while an idempotency rule ensures only one order is charged. Counting clicks answers neither "how many requests reached the backend?" nor "how many charges occurred?" Those questions need evidence from the relevant stages and the final business state.
The ingestion API responds with HTTP 202, event_id, and server_time once the message is acknowledged. The record still needs to load into queryable storage. Suppose the receipt's server_time is 2026-11-05T08:20:02Z, two seconds after client_time. Save those returned values and query a server-time window after ingestion. If the clocks differ by hours, check device time and late reporting before interpreting the business event.
The awkward case is a trusted backend that loses its connection after reporting and never sees the 202. That does not prove the event was rejected. A second send cannot be presumed idempotent, either. Check whether the backend retained a request identifier and whether the service received the event; otherwise mark its status unknown. Event-reporting retries and payment idempotency are separate concerns.
Query the attempt
With a read-only MCP connection configured, you might ask Codex:
Find events for
trace-example-001from 08:00 to 09:00 UTC on November 5, 2026. Check which fields I can query first. If you only find a frontend click, tell me where to look for the payment result; don't call an empty result a failed payment.
Call list_schemas -> describe_schema -> query_schema to confirm the readable schema and fields before filtering on trace_id. The query arguments could be:
{ "schema_id": "default_behavior_events", "schema_version": 1, "start_time": "2026-11-05T08:00:00Z", "end_time": "2026-11-05T09:00:00Z", "filters": { "trace_id": "trace-example-001" }, "limit": 20 } Check whether the tool call succeeded before interpreting the record count. A tool error needs investigation; an empty result may need a different time window. If only the frontend click appears, Codex can cite its ID and time, then inspect the code paths that should follow. The payment outcome might not have been reported, might still be loading, might be outside this window, or might live elsewhere. Even a backend event with the same trace_id has to be read for what it actually reports.
A backend record saying "sent a request to the gateway" still leaves two gaps: the gateway's response and the persisted order state. A callback may arrive after the customer closes the page, so the frontend trail may naturally stop there. An agent should name the missing step and the identifier needed to check it with the owning service. That is more useful than guessing "payment timeout" from a frontend trace.
For example: "This query found a frontend click at 08:20 UTC, but no payment outcome. Check whether the request reached the backend with this trace_id, then look for the backend and gateway results." This is an investigation path, not a real payment verdict.
Run one test event through the whole path
In a test project, report an event with a known trace_id and keep the ID and server time from the 202 receipt. Wait for the read credential to retrieve it by ID, then confirm another project's read credential gets no match. That small exercise checks authorization, time boundaries, and ingestion delay.
Protect the connection itself: do not paste read tokens into public frontend code, sample repositories, or ordinary agent prompts. If the available endpoint does not yet offer trustworthy encrypted transport or controlled network access, arrange that before demonstrating the workflow with real data. A query example in an article is not a credential-delivery plan.
Detail queries have time and result bounds. The current production default is 31 days at most and 100 rows per page; limit also caps the total requested by a query. The example asks for 20 rows. If exactly 20 return, narrow the time range or increase that total within your policy; if a next_cursor appears, continue with the same filters. Each page consumes a read call. Finding one event is useful, but it is not a payment-funnel report.
Project website: https://d2ggep2t73r4ny.cloudfront.net/
Technical and business discussion: lorry@antlertec.com