# Costs

> Read cloud spend from the SDKs: summaries, daily and monthly series, breakdowns you can filter and export, growth, forecasts, unit costs, tag allocation and invoice months.

Source: https://docs.levelfour.ai/resources/costs


The costs methods read what your organization spends: an overall summary, per-day and per-month series, and a per-service breakdown you can page, sort, filter and export as CSV. Others rank what is growing, forecast the month, price each usage type per unit, and measure how much spend your tags cover. Some cover the whole organization. The rest take a provider ID and answer the same questions for one cloud.

## Organization-wide

### Get cost summary

Returns an overall cost summary: total costs, forecast, savings, and a breakdown by provider.

**Python**

```python  
summary = client.costs.get_summary()
```

**TypeScript**

```typescript  
const summary = await client.costs.getSummary();
```

**Go**

```go  
summary, err := client.Costs.GetSummary(ctx, &levelfour.GetSummaryCostsRequest{})
```

### List costs

Returns a cost breakdown in one of these formats: `table` (paginated), `chart` (aggregated for stacked bar charts), `csv` (export), or `raw` (all records). Format scopes some of the parameters below: `page` and `page_size` apply to `table`, `granularity` to `chart`.

**Python**

```python  
breakdown = client.costs.list(
    format="table",
    period="2026-03",
    provider_id="aws",
    page=1,
    page_size=50,
    sort_by="cost",
    sort_order="desc",
)
```

**TypeScript**

```typescript  
const breakdown = await client.costs.list({
    format: "table",
    period: "2026-03",
    provider_id: "aws",
    page: 1,
    page_size: 50,
    sort_by: "cost",
    sort_order: "desc",
});
```

**Go**

```go  
breakdown, err := client.Costs.List(ctx, &levelfour.ListCostsRequest{
    Format:     levelfour.String("table"),
    Period:     levelfour.String("2026-03"),
    ProviderID: levelfour.String("aws"),
    Page:       levelfour.Int(1),
    PageSize:   levelfour.Int(50),
    SortBy:     levelfour.String("cost"),
    SortOrder:  levelfour.ListCostsRequestSortOrder("desc").Ptr(),
})
```

#### List costs parameters

| Parameter     | Type     | Description                                                                |
| ------------- | -------- | -------------------------------------------------------------------------- |
| `format`      | `string` | Response format: `table`, `chart`, `csv`, `raw`                            |
| `period`      | `string` | Period in `YYYY-MM` format (defaults to current month)                     |
| `provider_id` | `string` | Filter by provider: `aws`, `gcp`, `azure`, `k8s`                           |
| `granularity` | `string` | `daily` or `monthly` (for chart format)                                    |
| `group_by`    | `string` | Grouping dimension: `provider` or `account_id`                             |
| `start`       | `string` | Start date (ISO 8601)                                                      |
| `end`         | `string` | End date (ISO 8601)                                                        |
| `page`        | `int`    | Page number (table format only)                                            |
| `page_size`   | `int`    | Items per page (table format only)                                         |
| `sort_by`     | `string` | Sort field: `cost`, `service`, `region`, `account_id`, `change_percentage` |
| `sort_order`  | `string` | `asc` or `desc`                                                            |

> **Warning**
>
> `period` defaults to the current month, and the current month is still running. Pass a completed `YYYY-MM` when the number has to hold still.

### Get daily costs

Returns costs aggregated per day for a given date range.

**Python**

```python  
daily = client.costs.get_daily_costs(
    start="2026-03-01T00:00:00.000Z",
    end="2026-03-31T00:00:00.000Z",
)
```

**TypeScript**

```typescript  
const daily = await client.costs.getDailyCosts({
    start: "2026-03-01",
    end: "2026-03-31",
});
```

**Go**

```go  
daily, err := client.Costs.GetDailyCosts(ctx, &levelfour.GetDailyCostsCostsRequest{
    Start: levelfour.String("2026-03-01T00:00:00.000Z"),
    End:   levelfour.String("2026-03-31T00:00:00.000Z"),
})
```

### Get monthly costs

Returns costs aggregated per month across all time.

**Python**

```python  
monthly = client.costs.get_monthly_costs()
```

**TypeScript**

```typescript  
const monthly = await client.costs.getMonthlyCosts();
```

**Go**

```go  
monthly, err := client.Costs.GetMonthlyCosts(ctx)
```

### Get top growing services

Returns the services whose spend grew the most, by percentage, between two windows. `previous_period` compares the last 30 days with the 30 before them. `previous_month` compares this month so far with the whole of last month.

**Go**

```go  
growing, err := client.Costs.GetTopGrowing(ctx, &levelfour.GetTopGrowingAPIV1CostsTopGrowingGetRequest{
    Provider:  levelfour.String("aws"),
    CompareTo: levelfour.String("previous_month"),
    Limit:     levelfour.Int(5),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/top-growing?provider=aws&compare_to=previous_month&limit=5" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

| Parameter    | Type     | Description                                                                      |
| ------------ | -------- | -------------------------------------------------------------------------------- |
| `provider`   | `string` | Provider ID (defaults to `aws`)                                                  |
| `compare_to` | `string` | `previous_period` (default) or `previous_month`                                  |
| `limit`      | `int`    | Services to return, 1 to 100 (defaults to 10)                                    |
| `credits`    | `string` | `after` (default) or `before`. See [Google Cloud credits](#google-cloud-credits) |

### Get a spend forecast

Returns the projected spend to the end of the current month, with lower and upper bounds, and a 60-point series: the last 30 days of actual spend followed by the next 30 days of forecast.

**Go**

```go  
forecast, err := client.Costs.GetForecast(ctx, &levelfour.GetForecastAPIV1CostsForecastGetRequest{
    Provider: levelfour.String("all"),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/forecast?provider=all" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

`provider` takes a provider ID or `all`, and defaults to `aws`. A provider with no costs returns an empty forecast rather than an error.

### Get usage and unit costs

Returns spend, billable quantity, unit and cost per unit for each usage type. Use it to track a unit price over time, not only the total.

**Go**

```go  
usage, err := client.Costs.GetUsage(ctx, &levelfour.GetUsageAPIV1CostsUsageGetRequest{
    Provider: levelfour.String("aws"),
    Start:    levelfour.String("2026-08-01"),
    End:      levelfour.String("2026-08-31"),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/usage?provider=aws&start=2026-08-01&end=2026-08-31" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

| Parameter      | Type       | Description                                                                                          |
| -------------- | ---------- | ---------------------------------------------------------------------------------------------------- |
| `provider`     | `string`   | Provider ID (defaults to `aws`)                                                                      |
| `start`, `end` | `string`   | Date range                                                                                           |
| `service`      | `string[]` | Google Cloud only: limit to these services                                                           |
| `family`       | `string`   | Google Cloud only: one SKU family, `bigquery`, `network`, `compute` or `other`, returned by category |
| `credits`      | `string`   | `after` (default) or `before`                                                                        |

### Cost by tag

Two reads answer "who spends what" from your tags. The first lists the keys you can group by: the tag keys in your bill plus every [virtual tag](/guides/virtual-tags) key. A bill key that a virtual tag of the same name replaces is left out.

**Go**

```go  
keys, err := client.Costs.GetTagKeys(ctx, &levelfour.GetTagKeysAPIV1CostsByTagKeysGetRequest{
    Provider: levelfour.String("aws"),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/by-tag/keys?provider=aws" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

The second groups spend by the values of one key, such as `team` or `cost-center`, and splits each value's spend by category.

**Go**

```go  
byTeam, err := client.Costs.GetCostByTag(ctx, &levelfour.GetCostByTagAPIV1CostsByTagGetRequest{
    Provider: levelfour.String("aws"),
    TagKey:   levelfour.String("team"),
    Start:    levelfour.String("2026-08-01"),
    End:      levelfour.String("2026-08-31"),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/by-tag?provider=aws&tag_key=team&start=2026-08-01&end=2026-08-31" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

`tag_key` defaults to `team`. Both reads take `provider`, and the grouped one also takes `start`, `end` and `credits`.

### Get allocation coverage

Returns how much of your spend carries a tag key: total, tagged and untagged spend, the coverage percentage, and spend per value. Track it to see whether a tagging policy is landing.

**Go**

```go  
coverage, err := client.Costs.GetAllocation(ctx, &levelfour.GetAllocationAPIV1CostsAllocationGetRequest{
    Provider: levelfour.String("aws"),
    TagKey:   levelfour.String("team"),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/allocation?provider=aws&tag_key=team" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

| Parameter                | Type     | Description                                                                        |
| ------------------------ | -------- | ---------------------------------------------------------------------------------- |
| `provider`               | `string` | Provider ID (defaults to `aws`)                                                    |
| `tag_key`                | `string` | The key to measure. Google Cloud may leave it out to measure coverage by any label |
| `start`, `end`           | `string` | Date range                                                                         |
| `exclude_system`         | `bool`   | Google Cloud only: ignore `goog-` and `k8s-` labels (defaults to `true`)           |
| `include_project_labels` | `bool`   | Google Cloud only: count labels set on the project (defaults to `true`)            |
| `credits`                | `string` | `after` (default) or `before`                                                      |

### Google Cloud cost by labels

Returns Google Cloud spend grouped by up to three label keys at once, in the order you pass them, for example cluster, then namespace, then workload. A label set on a resource wins over the same key set on its project.

**Go**

```go  
tree, err := client.Costs.GetCostByLabels(ctx, &levelfour.GetCostByLabelsAPIV1CostsByLabelsGetRequest{
    Provider: levelfour.String("gcp"),
    Key:      []*string{levelfour.String("cluster"), levelfour.String("namespace")},
    Filter:   []string{"env=production"},
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/costs/by-labels?provider=gcp&key=cluster&key=namespace&filter=env%3Dproduction" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

`key` is required and repeats once per level. `filter` takes `key=value` pairs to narrow the result, and `limit` caps the rows (defaults to 50).

## One provider

Each of these takes a provider ID. [Providers](/resources/providers) has the IDs, and what a provider-scoped call returns for one your organization has not connected.

### Get provider summary

Returns a per-provider cost summary with monthly costs, forecast, potential savings, and the top 3 services for that provider.

**Python**

```python  
summary = client.costs.get_provider_summary("aws")
```

**TypeScript**

```typescript  
const summary = await client.costs.getProviderSummary("aws");
```

**Go**

```go  
summary, err := client.Costs.GetProviderSummary(ctx, "aws", &levelfour.GetProviderSummaryCostsRequest{})
```

### List by provider

Returns a paginated per-provider cost breakdown. Every row carries its previous-period cost and change percentage, and the response carries per-date totals across all pages, not just the page you asked for.

**Python**

```python  
breakdown = client.costs.list_by_provider(
    "aws",
    preset="30D",
    granularity="daily",
    group_by=["service", "region"],
    service=["EC2", "RDS"],
    region=["us-east-1"],
    page=1,
    page_size=20,
    sort_by="cost",
    sort_order="desc",
)
```

**TypeScript**

```typescript  
const breakdown = await client.costs.listByProvider("aws", {
    preset: "30D",
    granularity: "daily",
    group_by: ["service", "region"],
    service: ["EC2", "RDS"],
    region: ["us-east-1"],
    page: 1,
    page_size: 20,
    sort_by: "cost",
    sort_order: "desc",
});
```

**Go**

```go  
breakdown, err := client.Costs.ListByProvider(ctx, "aws", &levelfour.ListByProviderCostsRequest{
    Preset:      levelfour.String("30D"),
    Granularity: levelfour.String("daily"),
    GroupBy:     []string{"service", "region"},
    Service:     []string{"EC2", "RDS"},
    Region:      []string{"us-east-1"},
    Page:        levelfour.Int(1),
    PageSize:    levelfour.Int(20),
    SortBy:      levelfour.String("cost"),
    SortOrder:   levelfour.ListByProviderCostsRequestSortOrder("desc").Ptr(),
})
```

#### List by provider parameters

| Parameter                | Type       | Description                                                                                                |
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------- |
| `format`                 | `string`   | `table`, `chart`, `csv`, or `raw` (defaults to `table`)                                                    |
| `start`                  | `string`   | Start date (ISO 8601)                                                                                      |
| `end`                    | `string`   | End date (ISO 8601)                                                                                        |
| `preset`                 | `string`   | Date preset: `30D`, `6M`, or `12M` (overrides `start`/`end`)                                               |
| `granularity`            | `string`   | `daily` or `monthly`                                                                                       |
| `page`                   | `int`      | Page number (1-indexed)                                                                                    |
| `page_size`              | `int`      | Items per page                                                                                             |
| `sort_by`                | `string`   | Sort field: `service`, `environment`, `region`, `account_id`, `cost`, `previous_cost`, `change_percentage` |
| `sort_by_date`           | `string`   | Sort by a specific date column (`YYYY-MM-DD` or `YYYY-MM`, overrides `sort_by`)                            |
| `sort_order`             | `string`   | `asc` or `desc`                                                                                            |
| `group_by`               | `string[]` | Multi-dimension grouping: `service`, `account_id`, `region`, `tag`, `virtual_tag`                          |
| `service`                | `string[]` | Filter by service                                                                                          |
| `environment`            | `string[]` | Filter by environment                                                                                      |
| `account_id`             | `string[]` | Filter by account ID                                                                                       |
| `region`                 | `string[]` | Filter by region                                                                                           |
| `tag_key`                | `string[]` | Filter by tag key (required when `group_by` includes `tag`)                                                |
| `tag_value`              | `string[]` | Filter by tag value                                                                                        |
| `virtual_tag_key`        | `string`   | A virtual tag's name or id (required when `group_by` includes `virtual_tag`). One key per request          |
| `virtual_tag_value`      | `string[]` | Filter by value of `virtual_tag_key`. `__unallocated__` matches the cost no config assigned                |
| `virtual_tag_value_mode` | `string`   | `include` or `exclude`                                                                                     |

`tag_key` and `tag_value` read tags as your bill carries them. `virtual_tag_key` reads a key LevelFour assigns from your own rules, and [Virtual tags](/guides/virtual-tags) covers how those rules work. Beside a `virtual_tag_key`, grouping is limited to `virtual_tag`, `service`, `region`, `account_id` and `charge_type`, and filtering to `service`, `account_id`, `region`, `charge_type` and `payer_account`. Anything else is a 422.

> **Warning**
>
> `preset` overrides `start` and `end`. Send all three and the window you get is the preset's, not your dates.

[Filtering and sorting](/guides/filtering-and-sorting) turns these parameters into ready-to-run recipes, mostly for the `l4` CLI, with the SDK equivalents at the end.

### Get provider filters

Returns distinct values available for filtering the per-provider cost breakdown (services, regions, accounts, tag keys, tag values, and the `virtual_tag_keys` and `virtual_tag_values` your own rules define) within a date range. Populate an autocomplete with them, or check a user-supplied filter value before you query with it.

**Python**

```python  
filters = client.costs.get_provider_filters(
    "aws",
    start="2026-01-01T00:00:00.000Z",
    end="2026-01-31T00:00:00.000Z",
)
```

**TypeScript**

```typescript  
const filters = await client.costs.getProviderFilters("aws", {
    start: "2026-01-01T00:00:00.000Z",
    end: "2026-01-31T00:00:00.000Z",
});
```

**Go**

```go  
filters, err := client.Costs.GetProviderFilters(ctx, "aws", &levelfour.GetProviderFiltersCostsRequest{
    Start: levelfour.String("2026-01-01T00:00:00.000Z"),
    End:   levelfour.String("2026-01-31T00:00:00.000Z"),
})
```

### Get provider timeline

Returns a per-provider cost timeline at the requested granularity. Plot it as a trend chart of one provider's cost over time.

**Python**

```python  
timeline = client.costs.get_provider_timeline(
    "aws",
    start="2026-01-01T00:00:00.000Z",
    end="2026-03-31T00:00:00.000Z",
    granularity="daily",
)
```

**TypeScript**

```typescript  
const timeline = await client.costs.getProviderTimeline("aws", {
    start: "2026-01-01T00:00:00.000Z",
    end: "2026-03-31T00:00:00.000Z",
    granularity: "daily",
});
```

**Go**

```go  
timeline, err := client.Costs.GetProviderTimeline(ctx, "aws", &levelfour.GetProviderTimelineCostsRequest{
    Start:       levelfour.String("2026-01-01T00:00:00.000Z"),
    End:         levelfour.String("2026-03-31T00:00:00.000Z"),
    Granularity: levelfour.String("daily"),
})
```

### Get invoice months

Returns spend per invoice month, newest first, split by cost type: regular usage, tax, adjustments and rounding. The months match the invoices Google Cloud sends you. Google Cloud only; any other provider returns no months.

**Go**

```go  
invoices, err := client.Providers.GetProviderInvoices(ctx, "gcp", &levelfour.GetProviderInvoicesAPIV1ProvidersProviderIDCostsInvoicesGetRequest{
    Months: levelfour.Int(12),
})
```

**HTTP**

```bash  
curl -s "https://api.levelfour.ai/api/v1/providers/gcp/costs/invoices?months=12" \
  -H "Authorization: Bearer $LEVELFOUR_API_KEY"
```

`months` defaults to 6.

## Google Cloud credits

A Google Cloud bill can carry large credits: promotions, free tier, committed use and sustained use discounts. The cost endpoints take a `credits` query parameter to pick which figure you read:

| Value             | Returns                         |
| ----------------- | ------------------------------- |
| `after` (default) | What you pay once credits apply |
| `before`          | Gross cost, before any credit   |

Every response that takes `credits` echoes the value it used. AWS figures stay the same under either value. The dashboard's **Before credits / After credits** toggle sets the same parameter, and the per-provider summary for `gcp` adds a `credits_summary` with gross cost, credits and net cost for this month and last.

## Example: export costs to CSV

**Python**

```python  
from levelfour import LevelFour

client = LevelFour()

csv_data = client.costs.list(
    format="csv",
    start="2026-01-01T00:00:00.000Z",
    end="2026-03-31T00:00:00.000Z",
)
print(csv_data)
```

**TypeScript**

```typescript  
import { LevelFourClient } from "levelfour";

const client = new LevelFourClient();

const csvData = await client.costs.list({
    format: "csv",
    start: "2026-01-01T00:00:00.000Z",
    end: "2026-03-31T00:00:00.000Z",
});
console.log(csvData);
```

**Go**

```go  
csvData, err := client.Costs.List(ctx, &levelfour.ListCostsRequest{
    Format: levelfour.String("csv"),
    Start:  levelfour.String("2026-01-01T00:00:00.000Z"),
    End:    levelfour.String("2026-03-31T00:00:00.000Z"),
})
```

## Next

* [Providers](/resources/providers) has the provider IDs and the rest of the provider-scoped surface
* [Pagination](/pagination) has the defaults behind `page` and `page_size`, and the iterators that page for you
* [API reference](/api-reference/costs) is generated from the schema: every parameter, enum and response field
