> For the complete documentation index, see [llms.txt](https://savefee.gitbook.io/savefee/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://savefee.gitbook.io/savefee/broadcast/overview-and-flow.md).

# Overview and flow

## The problem this solves

Every transaction on TRON costs resources: bandwidth to carry it, and energy when it calls a contract. An account holding neither pays for them in burned TRX, which is the expensive way to do it. Provisioning them yourself means estimating what a transaction will need before you send it — and for a token transfer the answer even changes with the recipient.

The broadcast endpoint removes that estimate. You sign the transaction, SaveFee provisions what it needs, and broadcasts it.

```
1. you build and sign a transaction         (your key never leaves your side)
2. you POST the signed transaction          → 202, status pending_energy
3. SaveFee validates and simulates it
4. SaveFee provisions the resource it needs → ready
5. SaveFee broadcasts to TRON               → broadcasting, then confirming
6. the transaction confirms on-chain        → confirmed
```

## What you can send

A signed transaction with a single contract call — a TRC20 transfer, a contract call such as an approval, or a transfer that only needs bandwidth. SaveFee simulates what you sent, provisions energy or bandwidth accordingly, and broadcasts it.

{% hint style="warning" %}
Submit only transactions you intend to pay for. Every accepted transaction is charged, and the resource is provisioned from the simulation of exactly what you sent — so send exactly the transaction you mean to make.
{% endhint %}

## Who pays

The `Authorization` header decides which account is charged. **Send your API key**: your account pays, even for a transaction signed by another address, which is what lets you broadcast on behalf of your users. Without a key, the request falls back to charging the signing address's own SaveFee account — and an address that does not have one is refused with `422 wallet.not_registered`. See **POST /v1/broadcasts**.

{% hint style="warning" %}
**Send the header as `Authorization: Bearer sf_live_…`, exactly.** Authentication is optional here, so a header in another scheme — or with an empty token after `Bearer` — is read as no key rather than refused with `401`. The request then takes the anonymous path: your account is not charged, the webhooks tied to your key are not sent, and the broadcast is most likely rejected outright. It is worth one assertion in your own test suite.

A well-formed header with a bad key behaves the other way round: an invalid, revoked or IP-blocked key is refused with `401` or `403`, so revoking a key really does stop it.
{% endhint %}

## What it costs

The fee comes out of the paying balance and scales with the resource SaveFee provisions for your transaction, which it works out by simulating it. Two transactions of the same shape can cost different amounts.

A broadcast only holds the resource for as long as it takes to send the transaction, so it is always provisioned at the shortest duration — which means it is always billed at the **base unit price**, the cheapest rate there is. The longer-duration prices on **Limits and enums** apply to energy orders, not to broadcasts. In practice that works out **65–70% cheaper** than letting the sender burn TRX for the same transaction.

```
totalCostSun ≈ resourceRequired × base unit price
```

What varies between two broadcasts is therefore the **amount of resource** the transaction needs, not the price of a unit.

{% hint style="warning" %}
**The fee leaves the balance when the broadcast is accepted**, not when the transaction confirms. A `202` debits the paying account immediately, and `GET /v1/balance` reflects it right away. It is a real debit rather than a hold or an authorisation.
{% endhint %}

{% hint style="warning" %}
**Read `totalCostSun` from the broadcast record for what you were actually charged.** The base price is set by SaveFee and moves with the market — read it live from **`GET /v1/public/pricing`** — and the amount a transaction needs depends on what it does and on the state it touches. Do not hard-code a fee into your accounting.
{% endhint %}

### Worked example: a USDT transfer

For a USDT transfer the dominant factor is whether the **recipient already holds USDT**:

| Recipient           | Energy burned on-chain |
| ------------------- | ---------------------- |
| Already holds USDT  | \~64,000               |
| Has never held USDT | \~130,000              |

A first-time recipient costs roughly **twice** as much, because writing a token balance from zero to non-zero is more expensive on-chain than updating an existing one. If you send to many first-time recipients — payouts to new users, for example — size your balance for the higher figure rather than the average.

## If it is not delivered

A broadcast that ends in `failed` or `expired` is refunded: the debit taken at acceptance is reversed by a separate refund entry. You are charged for delivery, not for the attempt.

After either of those, the same `txId` can be submitted again — that is the supported way to retry. See **Track and troubleshoot**.

## What SaveFee never sees

Your private key. You sign locally; only the signed transaction is sent. SaveFee cannot alter it either — any change would invalidate the signature, and the signature is verified against `fromAddress` before broadcast.
