> For the complete documentation index, see [llms.txt](https://andrewkimjoseph.gitbook.io/celina-sdk/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://andrewkimjoseph.gitbook.io/celina-sdk/guides/telemetry.md).

# Telemetry

On **Node.js**, the SDK sends usage counts for **read** operations. Each Amplitude event uses the same name as the corresponding Celina MCP tool (for example `get_stablecoin_balances`, `verify_self_agent`).

## What is sent

* Event name (MCP tool name)
* A `device_id` identifying the **npm package** that called `createCelinaClient()` (auto-detected from its `package.json` `name`, sanitized for Amplitude: strip leading `@`, replace `/` and `-` with `_`, e.g. `celeste_ai`, `andrewkimjoseph_celina_mcp`). Falls back to `celina-sdk` when detection fails.
* Amplitude **`user_id`** set to the lowercase wallet `0x…` address when the read is wallet-scoped (no `event_properties` — wallet is only on `user_id`)
* No tool arguments or private keys

Wallet resolution order:

1. Wallet address extracted from the read call args (catalog-driven)
2. `runWithAnalyticsWallet(address, fn)` request scope (singleton SDK clients)
3. `analyticsWalletAddress` on `createCelinaClient()` (e.g. MCP session signer)

Writes and `prepare*` flows are not tracked (dual on-chain Celina attribution covers those — see [On-chain attribution](/celina-sdk/guides/on-chain-attribution.md)). Custom `attributionTags` from client config appear in the calldata suffix on-chain, not in Amplitude events.

## Default behavior

Telemetry is **on** for server-side use (MCP, your app's API routes, scripts) unless you opt out.

Browser bundles that import the SDK do not load the Amplitude Node client and do not send events.

On **serverless** hosts (Vercel, AWS Lambda, Cloudflare Workers), do **not** await Amplitude on the request path — that adds ingest RTT (or a hung timeout) to every read. Track is fire-and-forget; keep the isolate alive with `waitUntil(drainCelinaAnalytics())` (Workers) or `waitUntil` / `after(() => drainCelinaAnalytics())` (Vercel / Next). `flushCelinaAnalytics()` alone no-ops if init has not finished yet.

### Singleton clients (e.g. Next.js API routes)

When one shared `createCelinaClient()` serves many users, wrap the handler:

```ts
import { runWithAnalyticsWallet, drainCelinaAnalytics } from "@andrewkimjoseph/celina-sdk";
import { after } from "next/server";

export async function POST(req: Request) {
  after(() => drainCelinaAnalytics());
  const { address } = await req.json();
  return runWithAnalyticsWallet(address, () => {
    // SDK reads inside this scope attach address as Amplitude user_id
  });
}
```

## Opt out

```ts
const celina = createCelinaClient({
  analyticsEnabled: false,
});
```

## Overrides

| Option                                             | Purpose                                                 |
| -------------------------------------------------- | ------------------------------------------------------- |
| `AMPLITUDE_API_KEY`                                | Replace the bundled project key                         |
| `amplitudeApiKey` in `createCelinaClient()`        | Same, in code                                           |
| `analyticsDeviceId` in `createCelinaClient()`      | Override auto-detected Amplitude `device_id`            |
| `analyticsWalletAddress` in `createCelinaClient()` | Default wallet for `user_id` when reads omit an address |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://andrewkimjoseph.gitbook.io/celina-sdk/guides/telemetry.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
