Response telemetry
Response telemetry tells you where the time went on a single API call. When you ask for it, Chargebee adds an X-Chargebee-Telemetry header to the response with a server-side breakdown of the request:
- How long Chargebee took to process the request.
- How much of that time was spent in third-party integrations that you've configured, such as your payment gateway or tax provider.
- How long the request waited for a lock on a resource that another request was using.
Use it to tell latency caused by Chargebee apart from latency caused by your network, your own code, or a third-party provider, without instrumenting Chargebee yourself.
Response telemetry is opt-in and applies per request. Chargebee doesn't send the header unless the request asks for it. Chargebee can add namespaces and keys to the header over time, so write your parser to ignore anything it doesn't recognize.
Quick start with response telemetry
Add the Prefer: chargebee-telemetry=include header to an API request. The following example retrieves a customer and prints the response headers with -i:
The response includes the X-Chargebee-Telemetry header alongside the usual headers. With HTTP/2, status lines and header names may appear in lowercase (for example HTTP/2 200 and x-chargebee-telemetry):
To learn what each part of this value means, see Read an example header.
Request telemetry
| Item | Value |
|---|---|
| Request header | Prefer |
| Header value | chargebee-telemetry=include |
| Scope | Only the request that carries the header. Send it on every request that you want telemetry for. |
| Response header | X-Chargebee-Telemetry |
| Without the request header | The response doesn't contain X-Chargebee-Telemetry. |
If you use the Node.js or Java client library, the library can send the request header and parse the response header for you. See Use the client libraries. In any other integration, set the request header yourself and parse the response header.
Header format
The value of X-Chargebee-Telemetry is a List as defined by RFC 9651: Structured Field Values for HTTP.
- Members are separated by commas. Each member describes one category of telemetry, such as Chargebee's own processing or one third-party integration.
- Namespace: the first item of each member is a token that identifies its category, for example
cbortp-stripe. See Namespaces. - Parameters: the
key=valuepairs that follow the namespace, separated by semicolons, belong to that namespace only.
Value types
Parameter values use RFC 9651 types. The type is identified by how the value is written:
| Type | Written as | Example |
|---|---|---|
| Integer | Digits, with an optional leading - | time_ms=3800 |
| Decimal | Digits with a decimal point | ratio=99.9 |
| Token | An unquoted word | pm=card |
| String | Text in double quotes, with \" and \\ escapes | desc="hello world" |
| Boolean | ?1 for true, ?0 for false | enabled=?1 |
| Date | @ followed by seconds since the Unix epoch, in UTC | start_time=@1781280400 (not used in current cb members; see start_time_epoch) |
Forward compatibility
Chargebee can add namespaces and keys to this header over time. To keep your integration working when that happens:
- Ignore namespaces and keys that you don't recognize.
- Don't depend on the order of members or parameters.
- Don't assume that a namespace or key is present on every response.
Namespaces
Chargebee metrics
The cb member describes how Chargebee processed the request.
| Key | Type | Description |
|---|---|---|
start_time_epoch | Integer (seconds since the Unix epoch, UTC) | When Chargebee started processing the request. The value is whole seconds; use it for correlation with your own timings, not for sub-second timeline alignment. |
time_ms | Integer (milliseconds) | Overall time that Chargebee took to process the request. |
tp_time_ms | Integer (milliseconds) | Overall time spent in third-party integrations during the request, across all tp- members. |
res_wait_time_ms | Integer (milliseconds) | Time the request spent waiting for a lock on a resource, for example because another request was changing the same customer or subscription at the same time. |
Third-party integrations
A tp-<integration_name> member reports time spent in a third-party integration that you've configured for your site, for example tp-stripe, tp-braintree, or tp-avalara. A request that uses more than one integration has more than one tp- member, as in the example header.
Stripe, Braintree, and Avalara are reported today. Chargebee will report more integrations in future releases.
| Key | Type | Description |
|---|---|---|
time_ms | Integer (milliseconds) | Time spent in this integration. |
pm | Token | Present only on payment gateway integrations. The payment method involved, for example card. Uses the same values as payment_source.type. |
Read an example header
| Member | What it tells you |
|---|---|
cb;start_time_epoch=1781280400 | Chargebee started processing the request at 2026-06-12 16:06:40 UTC. |
cb;time_ms=3800 | Chargebee took 3,800 ms to process the request. |
cb;tp_time_ms=1350 | 1,350 ms of the request was spent in third-party integrations. |
cb;res_wait_time_ms=90 | The request waited 90 ms for a lock on a resource. |
tp-avalara;time_ms=730 | 730 ms was spent in Avalara, for example to calculate tax. |
tp-stripe;pm=card;time_ms=620 | 620 ms was spent in Stripe, processing a card payment. |
If your application measured a longer end-to-end time than cb;time_ms, the difference may include network latency, time in your own code, or Chargebee-side queue time before processing started.
Use the client libraries
With cURL, add the header with -H and print the response headers with -i, as shown in Quick start with response telemetry. To see the Node.js or Java setup, switch the language selector at the top of the left navigation to Node.js or Java. In a narrow window, open the selector from the settings icon in the header.
Parse the header yourself
If you aren't using a client library that supports response telemetry, keep the following in mind:
- Use an RFC 9651 parser. Most languages have a library for Structured Field Values. Don't split the value on
,and;yourself: string values can contain both characters inside quotes. - Look the header up case-insensitively. HTTP header names are case-insensitive, and many HTTP clients return them in lowercase, for example
x-chargebee-telemetry. - Treat telemetry as optional. If the header is missing or can't be parsed, log the raw value and carry on. Never fail or retry an API call because of this header.
- Follow the forward compatibility rules. Ignore namespaces and keys that you don't recognize.
In practice Chargebee emits a flat List of members with tokens and integer parameters. Strings and inner lists are uncommon today, but a standards-based parser keeps you safe if the format expands.
Best practices
- Request telemetry when you need it. For example, turn it on for a sample of requests, or while you investigate a latency issue.
- Record it next to your own timings. Compare
cb;time_mswith the latency your application measured alongside the example interpretation. - Use it for diagnostics only. Don't build business logic, such as billing or retry decisions, on telemetry values.
- Watch for lock waits. Sustained high
res_wait_time_msvalues can mean that several requests are changing the same resource, such as the same subscription, at the same time. If those requests come from your integration, serialize them.