# OpenTelemetry integration

> For the complete machine-readable documentation index, see [llms.txt](https://apidocs.chargebee.com/llms.txt).


All Chargebee [client libraries](/docs/sdks) — [Node.js](/docs/sdks/nodejs), [Java](/docs/sdks/java), [Python](/docs/sdks/python), [PHP](/docs/sdks/php), [Ruby](/docs/sdks/ruby), [.NET](/docs/sdks/dotnet), and [Go](/docs/sdks/go) — can emit **standardized request spans** into your observability stack via OpenTelemetry.

Telemetry is **optional**. OpenTelemetry is not bundled with Chargebee SDKs. Install and configure OTel in your application, implement a small telemetry adapter, and pass it when configuring the client.

## How it works

When a telemetry adapter is configured:

1.  **Span start** — Before each API call, the SDK calls `onRequestStart` with a request context (span name, resource, operation, and start attributes). Your adapter typically creates an OTel client span and injects W3C `traceparent` / `tracestate` headers on the outgoing request.
2.  **Span end** — After the response (or error), the SDK calls `onRequestEnd` with a result object (HTTP status, duration, error details, and end attributes). Your adapter records final attributes, sets span status, and ends the span.
3.  **One span per SDK call** — Retries reuse the same span; they do not create a new root trace.
4.  **Fail-safe** — Telemetry errors never break the API call.

Spans are named `chargebee.{resource}.{operation}` — for example `chargebee.subscription.create`. The span name, attribute keys, and error mapping are **identical across all SDK languages**.

## Span attributes

The SDK builds attributes following stable [OpenTelemetry HTTP semantic conventions](https://opentelemetry.io/docs/specs/semconv/http/http-spans/) plus Chargebee-specific `chargebee.*` keys. Forward them as-is to your exporter.

**Recorded at span start:**

Attribute

Description

`url.full`

Request URL (without sensitive query params)

`http.request.method`

HTTP method

`server.address`

Chargebee API hostname

`chargebee.site`

Your Chargebee site name

`chargebee.api_version`

`v1` or `v2`

`chargebee.resource`

API resource (e.g. `subscription`)

`chargebee.operation`

API operation (e.g. `create`)

`chargebee.sdk.name`

SDK identifier (e.g. `chargebee-java`, `chargebee-node`)

`chargebee.sdk.version`

Installed SDK version

`http.request.header.chargebee-*`

Outgoing `chargebee-*` request headers (except `chargebee-request-origin-*`, which carries PII and is excluded)

**Recorded at span end:**

Attribute

Description

`http.response.status_code`

HTTP status code

`error.type`

Chargebee error type on 4xx/5xx (when available)

`chargebee.error.code`

Chargebee error code

`chargebee.error.type`

Chargebee error classification

`chargebee.error.param`

API parameter associated with the error

## Examples

Configure OpenTelemetry in your application (OTLP exporter, service name, and so on), then pass a telemetry adapter when initializing the Chargebee client. Use the **Library** dropdown at the top of the page to switch between language-specific examples below.

The Node.js SDK ships a ready-to-use OpenTelemetry adapter at `chargebee/telemetry/otel`. It uses the globally registered OpenTelemetry tracer from `@opentelemetry/api` (install that package separately). Exporting (endpoint, service name, credentials) is configured by your OpenTelemetry runtime via standard `OTEL_*` environment variables — the adapter only creates spans and propagates W3C trace context.

**Default adapter (recommended)** — import the pre-built singleton and pass it directly:

**Custom instance** — import `OtelTelemetryAdapter` if you need a separate instance (uncommon for most apps):

For custom tracer behavior or a non-OpenTelemetry backend, implement `TelemetryAdapter` yourself instead. See the [chargebee-node README](https://github.com/chargebee/chargebee-node#telemetry-opentelemetry) for instrumentation setup and a custom adapter example.

Implement `com.chargebee.v4.telemetry.TelemetryAdapter` (or reuse an `OtelTelemetryAdapter` from your application) and pass it on the client builder:

See the [chargebee-java README](https://github.com/chargebee/chargebee-java#telemetry-opentelemetry) for a full `OtelTelemetryAdapter` example.

Implement `chargebee.telemetry.TelemetryAdapter` and pass it when creating the client:

You can also call `cb.update_telemetry_adapter(my_otel_adapter)` after initialization.

Implement `Chargebee\Telemetry\TelemetryAdapter` and pass it in the client options:

Implement `ChargeBee::Telemetry::TelemetryAdapter` and register it when configuring the SDK:

Implement `ChargeBee.Telemetry.ITelemetryAdapter` and pass it when configuring the client:

Your adapter receives `RequestTelemetryContext` at start and `RequestTelemetryResult` at end, with prebuilt `chargebee.*` attributes. See the [chargebee-dotnet README](https://github.com/chargebee/chargebee-dotnet#telemetry-opentelemetry) for a full example.

Implement `telemetry.TelemetryAdapter` and pass it on the client config:

## Next steps

-   Browse [Client Libraries](/docs/sdks) for installation and quick-start guides per language.
-   Configure an OTLP exporter in your OpenTelemetry SDK.
-   Spans are exported by your OpenTelemetry setup — refer to the [OpenTelemetry documentation](https://opentelemetry.io/docs/) for exporter configuration.