Skip to content
WarpStream Documentation
Start Free

Chargebacks

Chargebacks help you understand how your WarpStream bill maps back to the teams, applications, and datasets that generated usage.

A standard invoice shows charges at the account, workspace, and cluster level. That is usually enough for accounting, but it can be too coarse for internal cost allocation. A single Kafka cluster may contain hundreds or thousands of topics owned by different teams. A Schema Registry cluster may contain subjects for many applications. A Tableflow cluster may contain tables with very different storage and write patterns.

Chargebacks break supported cluster-level invoice line items down by entity:

Cluster type Chargeback entity
Kafka clusters Topic
Schema Registry clusters Subject
Tableflow clusters Table

The result is a showback-style view of billing data. You can use it to answer questions like:

  • Which topics contributed the most to this month’s Kafka bill?
  • Which tables are responsible for most Tableflow storage charges
  • How should a shared cluster’s costs be allocated across teams?
  • Which small entities can be ignored when building an internal chargeback report?

Chargebacks are derived from invoice data combined with per-entity usage rollups. The invoice remains the source of truth for billing; chargebacks provide a best-effort allocation of covered cluster-level charges across the entities inside each cluster.

Chargeback calculations start with the monthly invoice for the requested billing period. For each cluster on the invoice, WarpStream loads a per-entity usage rollup for the same period and uses that rollup to apportion supported invoice line items across topics, subjects, or tables.

The chargebacks response preserves the same high-level hierarchy as the invoice:

tenant
workspace
cluster
entity
line item chargebacks

Each entity receives one or more line-item-level chargebacks. Each line item chargeback includes the name, unit price, apportioned quantity, and apportioned total.

Chargebacks currently apportion the following line item types:

Line item Allocation method
Cluster minutes Allocated by how long each entity existed during the billing period.
Uncompressed GiB written Allocated by each entity’s share of uncompressed write bytes.
GiB minutes Allocated by storage attribution. Kafka topics use write bytes weighted by retention. Tableflow tables use measured time-integrated stored bytes.
Network ingress (Serverless clusters only) Allocated by each entity’s share of write bytes.
Network egress (Serverless clusters only) Allocated by each entity’s share of write bytes.

The response includes a covers_products field so callers can see which invoice line items are included in the chargeback calculation.

Storage charges need special handling because different cluster types have different methods for measuring storage volume.

For Kafka topics, WarpStream uses:

write bytes × retention

This is reported in the response as:

"storage_attribution_method": "write_bytes_times_retention"

For Tableflow tables, WarpStream uses measured stored bytes over time. This is reported as:

"storage_attribution_method": "bytes_seconds_stored"

The storage_attribution_method field only appears on clusters where storage charges were apportioned.

Sometimes a cluster appears on the invoice but cannot be broken down into per-entity chargebacks. In that case, the cluster is still returned, but with an excluded_reason instead of an entities list.

Possible exclusion reasons are:

Reason Meaning
no_rollup We could not find a usable per-entity rollup for the requested period. This can happen for a new cluster, a new billing period, or a cluster whose rollup data has not been produced yet.
cluster_not_found The invoice references a cluster that no longer exists in the control plane.

When a cluster is excluded, its charges are not apportioned across entities in the chargebacks response.

There are two chargebacks endpoints:

Endpoint Use when
POST /api/v1/billing/chargebacks/get_pending You want chargebacks for the current in-progress billing month.
POST /api/v1/billing/chargebacks/get_past You want chargebacks for a specific billing month.

Use pending chargebacks for ongoing monitoring and internal dashboards. Use past chargebacks when producing a final monthly report after the invoice period has closed. Note that because WarpStream uses a tiered pricing model for writes and storage, pending Chargebacks may show unexpectedly lopsided values early in a monthly billing period.

curl https://api.warpstream.com/api/v1/billing/chargebacks/get_pending \
-H 'warpstream-api-key: XXXXXXXXXX' \
-H 'Content-Type: application/json' \
-d '{
"entity_kind": "topic",
"max_entities_per_cluster": 500,
"min_total": 1
}'

get_pending does not require a date. It always returns the current billing month.

curl https://api.warpstream.com/api/v1/billing/chargebacks/get_past \
-H 'warpstream-api-key: XXXXXXXXXX' \
-H 'Content-Type: application/json' \
-d '{
"date_start": "2026-05-01",
"entity_kind": "topic",
"max_entities_per_cluster": 500,
"min_total": 1
}'

For get_past, pass any date inside the billing month you want to retrieve. For example, 2026-05-01, 2026-05-15, and 2026-05-31 all select the May 2026 billing period.

Both endpoints support filters that make the response easier to work with for cases with many clusters, many topics, etc.

Field Required Description
date_start Required for get_past; not used for get_pending Selects the billing month to retrieve. Pass any date in the desired month, formatted as YYYY-MM-DD.
entity_kind No Filters the response by entity type. Allowed values are topic, subject, and table. If omitted, all supported entity kinds are returned.
virtual_cluster_id No Filters the response to a single virtual cluster. This is useful when drilling into a large cluster or requesting a higher entity limit.
max_entities_per_cluster No Limits the number of entities returned per cluster. Defaults to 500. The maximum allowed value is 5000.
min_total No Omits entities whose total chargeback amount is less than this USD value. Use this to remove very small rows from reports.
{
"date_from": "2026-05-01",
"date_to": "2026-06-01",
"covers_products": [
"Cluster minutes",
"Uncompressed GiB written",
"GiB minutes",
"Network ingress",
"Network egress"
],
"tenants": [
{
"tenant_id": "ti_xxx",
"workspaces": [
{
"workspace_id": "wi_xxx",
"workspace_name": "Production",
"clusters": [
{
"virtual_cluster_id": "vci_xxx",
"cluster_name": "prod-kafka",
"cluster_regions": [
"us-east-1"
],
"cluster_type": "byoc",
"entity_kind": "topic",
"storage_attribution_method": "write_bytes_times_retention",
"entities": [
{
"name": "orders",
"chargebacks": [
{
"product": "Cluster minutes",
"unit_price": 0.23148,
"quantity": 2340,
"total": 5.42
},
{
"product": "Uncompressed GiB written",
"unit_price": 1,
"quantity": 110.25601800903678,
"total": 1.1
},
{
"product": "GiB minutes",
"unit_price": 0.00000463,
"quantity": 1343.727466603741,
"total": 0
}
],
"total": 6.52
}
]
}
]
}
]
}
]
}

Each entity has a total field equal to the sum of its line item-level chargebacks. To build an internal chargeback report, group entities however you prefer, for example by naming convention, team ownership, or cluster.

Chargebacks are designed for internal allocation and cost analysis. A few details are worth keeping in mind:

  • Chargebacks only include products listed in covers_products.
  • Small rounding differences can occur when summing apportioned charges. Chargebacks are for analytical estimations, and total rollups may not match your invoiced charges.
  • Network ingress and egress (for Serverless clusters only) are approximated by write-byte share.
  • Storage attribution depends on cluster type and is reported per cluster.
  • If truncated is true on a cluster, more entities matched the request than were returned. Increase max_entities_per_cluster, filter to a single virtual_cluster_id, or raise min_total.
  • If excluded_reason is present, that cluster’s invoice charges were not apportioned into entities for the requested period.