> ## Documentation Index
> Fetch the complete documentation index at: https://docs.foglamp.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK overview

> The foglamp() collector and its integration methods.

The `foglamp` package has two entry points, one per AI SDK generation. Both
batch spans and send them to your ingest endpoint, and both share the same
context fields, configuration, and flushing. They only differ in how they
attach to your calls.

<CardGroup cols={2}>
  <Card title="wrap() for AI SDK v4 to v6" icon="package" href="/sdk/wrap">
    Wraps the `ai` module. Use this on v4, v5, and v6.
  </Card>

  <Card title="foglamp() for AI SDK v7" icon="bolt" href="#foglampconfig">
    Uses v7's built-in telemetry API. Documented below.
  </Card>
</CardGroup>

This page covers the v7 `foglamp()` collector. The v4 to v6 `wrap()` API has
its own [page](/sdk/wrap).

```ts theme={null}
import { foglamp } from "foglamp";

const fog = foglamp();
```

<Note>
  The SDK has one small runtime dependency (`uuidv7`) and does not require any
  particular version of `zod`. Its only required peer dependency is `ai`
  (`ai@^4 || ^5 || ^6 || ^7.0.0-beta.1`).
</Note>

## `foglamp(config?)`

Creates a collector. All options are optional; if there is no API key, the
collector silently does nothing. See [Configuration](/sdk/configuration) for
the full option table.

```ts theme={null}
const fog = foglamp({
  apiKey: process.env.FOGLAMP_API_KEY,
  endpoint: process.env.FOGLAMP_INGEST_URL,
  flushIntervalMs: 5000,
});
```

## Collector methods

### `fog.integration(context)`

Returns a telemetry integration to pass into a call's
`telemetry.integrations` array (v7 also accepts the older
`experimental_telemetry` name). The context labels every span the call
produces. It must include a `traceName` or an `agentName`; if it has neither,
`integration()` throws right away.

```ts theme={null}
fog.integration({
  agentName: "summarizer",
  workflowName: "deploy-digest",
  workflowRunId: run.id,
  sessionId: user.threadId,
  customer: { id: account.id, name: account.name, imageUrl: account.logoUrl },
  metadata: { environment: "production", region: "us-east-1" },
});

// A one-off call that isn't an agent: name it instead.
fog.integration({ traceName: "classify-email" });
```

| Context field   | Type                                               | Notes                                                                           |
| --------------- | -------------------------------------------------- | ------------------------------------------------------------------------------- |
| `traceName`     | string                                             | Label for a one-off call. Required if `agentName` is absent.                    |
| `agentName`     | string                                             | The agent making the call. Required if `traceName` is absent.                   |
| `workflowName`  | string                                             | The named process. Pass with `workflowRunId`.                                   |
| `workflowRunId` | string                                             | Groups traces into one run. Pass with `workflowName`.                           |
| `sessionId`     | string                                             | Ties traces to one conversation.                                                |
| `customer`      | `{ id: string; name?: string; imageUrl?: string }` | The customer this call serves. Powers per-customer cost. Only `id` is required. |
| `metadata`      | `Record<string, string \| number \| boolean>`      | Free-form labels. Values are stored as strings.                                 |

<Note>
  Two rules, checked at compile time and again at ingest: every call needs a
  `traceName` or an `agentName` (both is fine; the display label is
  `traceName ?? agentName`), and `workflowName` and `workflowRunId` must be
  passed together.
</Note>

### `fog.flush()`

Sends any buffered spans right away and resolves when done. Call this before a
serverless function returns. Safe to call when the collector is disabled; it
resolves immediately.

```ts theme={null}
await fog.flush();
```

### `fog.shutdown()`

Stops the flush timer and sends everything left, including traces added while a
send was already in progress. Use this when a long-running server shuts down.

```ts theme={null}
process.on("SIGTERM", async () => {
  await fog.shutdown();
});
```

<Note>
  `flush()` keeps the collector running; use it at the end of a serverless
  handler. `shutdown()` is final; use it once when the process exits. Calling
  only `flush()` at exit can leave behind traces that were added mid-send.
</Note>

## Two ways to register

<CardGroup cols={2}>
  <Card title="Per call" icon="crosshairs">
    Pass `fog.integration(...)` into one call's telemetry. Fully typed, and
    takes priority over global registration.
  </Card>

  <Card title="Global" icon="globe">
    `registerTelemetry(foglamp())` traces every call. It reads `functionId` as
    the `agentName` and known keys from `telemetry.metadata`.
  </Card>
</CardGroup>

## Nested calls inside tools

When a tool's `execute` function makes its own AI SDK call (for example a
sub-agent), the v7 collector automatically passes the parent call's grouping
context (`workflowName`, `workflowRunId`, `sessionId`, `customer`, `metadata`)
into that nested call. The inner call lands in the same workflow run with no
extra code.

```ts theme={null}
const fog = foglamp();

await generateText({
  model,
  tools: { researchAgent },          // its execute() calls generateText again
  telemetry: {
    integrations: [
      fog.integration({
        agentName: "planner",
        workflowName: "deep-research",
        workflowRunId: run.id,        // the nested call inherits this
      }),
    ],
  },
});
// The sub-agent's trace joins workflow run `run.id` automatically.
```

Only grouping context is inherited. The inner call keeps its own name
(`agentName` / `traceName`), and it is its own trace in the run, not a child
span of the tool. A more specific inner `fog.run()` or `fog.integration()`
still wins. This only works on the v7 collector; on v4 to v6 use
[`fog.run()`](/sdk/wrap) to share context across nested calls.

Next: tune batching and text capture in [Configuration](/sdk/configuration),
and make sure spans leave serverless functions in
[Runtimes and flushing](/sdk/runtimes).
