# Fees

Read effective, reserve, and post-only reserve spot fee rates with the Rust FeeService.

`client.fees` reads the spot fee rates of the account target, per listed Pair. The call is authenticated. These are the live effective rates, not a guaranteed quote of every future fill: the completed [user trade](https://testnet.polyester.com/docs/sdk/rust/reference/trades) record owns the exact charge.

## Methods

| Method               | Summary                                           |
| -------------------- | ------------------------------------------------- |
| `get_spot_fee_rates` | Fee rates per Pair (`subaccount_id`, `symbol_id`) |

### Get spot fee rates

```rust
let rates = client.fees.get_spot_fee_rates(None, vec![]).await?;
for rate in &rates.fee_rates {
    println!(
        "{} maker={} taker={} reserve={} post_only_reserve={}",
        rate.symbol,
        rate.maker_fee_rate_percent,
        rate.taker_fee_rate_percent,
        rate.reserve_fee_rate_percent,
        rate.post_only_reserve_fee_rate_percent,
    );
    if let Some(next_change_at) = &rate.next_change_at {
        println!("refetch at {}", next_change_at.seconds);
    }
    if let Some(breakdown) = &rate.breakdown {
        println!(
            "tier maker={} taker={} discounts={}",
            breakdown.tier_maker_fee_rate_percent,
            breakdown.tier_taker_fee_rate_percent,
            breakdown.account_discounts.len(),
        );
    }
}
```

Pass `None` for the client's default scope, or a subaccount ID. An empty `symbol_id` list returns every listed Pair; pass IDs from `client.catalogs.symbol_id_for_symbol` to filter.

## SpotFeeRate fields

Rates are decimal percentage strings without a percent sign.

| Field                                | Meaning                                 |
| ------------------------------------ | --------------------------------------- |
| `symbol_id` / `symbol`               | The Pair                                |
| `maker_fee_rate_percent`             | Effective maker rate; applies to fills  |
| `taker_fee_rate_percent`             | Effective taker rate; applies to fills  |
| `vip_tier`                           | VIP tier used to resolve these rates    |
| `reserve_fee_rate_percent`           | Rate a new order reserves its fee at    |
| `post_only_reserve_fee_rate_percent` | Rate a new post-only order reserves at  |
| `next_change_at`                     | Earliest scheduled change; may be unset |
| `breakdown`                          | Components of the effective rates       |

When `next_change_at` is present, refetch the rates at that time. The rates can change then, or stay the same. Omitted when no change is scheduled.

`breakdown` is an optional `SpotFeeRateBreakdown` with `tier_maker_fee_rate_percent`, `tier_taker_fee_rate_percent`, an optional `market_multiplier` (`SpotFeeMultiplier`), `account_discounts` (`Vec<SpotFeeDiscount>`), and an optional `referral_discount`. Optional components and times may be `None`, and absent account discounts decode as an empty list.

## Sizing rule

A buy limit order that pays its fee in the quote Asset is sized with `reserve_fee_rate_percent`, or `post_only_reserve_fee_rate_percent` for a post-only order. A buy sized by a quote amount reserves at the lower of `reserve_fee_rate_percent` and `taker_fee_rate_percent`.

Fills charge the effective rate, and the rest of the reserve is released as the order fills or ends. Compare in exact integer or `Decimal` arithmetic, never binary floats.

## Related

- [Orders](https://testnet.polyester.com/docs/sdk/rust/reference/orders)
- [User trades](https://testnet.polyester.com/docs/sdk/rust/reference/trades)
- [Balances](https://testnet.polyester.com/docs/sdk/rust/reference/balances)
- [Fees and VIP](https://testnet.polyester.com/docs/developer-docs/account/fees-and-vip)
