> 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/limits-and-enums.md).

# Limits and enums

## Orders

| Field         | Accepted values                                                          |
| ------------- | ------------------------------------------------------------------------ |
| `resource`    | `ENERGY`                                                                 |
| `amount`      | Integer, **50,000 to 200,000 inclusive**                                 |
| `durationSec` | `60` (1 min) · `300` (5 min) · `900` (15 min) · `3600` (60 min)          |
| `items[]`     | 1 to **100** entries                                                     |
| `toAddress`   | Valid TRON address, checksum verified, activated account, not a contract |

## Pricing

SaveFee does not publish a fixed unit price. Energy is priced per unit, and renting it typically costs **65–70% less** than burning TRX for the same resource on-chain.

| `durationSec` | Unit price                    |
| ------------- | ----------------------------- |
| `60`          | Base unit price               |
| `300`         | Base unit price               |
| `900`         | Slightly above the base price |
| `3600`        | The highest of the four       |

```
totalCostSun = amount × unit price
```

{% hint style="info" %}
The base unit price is set by SaveFee and moves with the market. Read the live table from **`GET /v1/public/pricing`**, and take `totalCostSun` in the `201` response as the amount you were charged.
{% endhint %}

Broadcasts are always provisioned at the shortest duration, so they are always billed at the base unit price. The longer-duration rows apply to energy orders only.

## Statuses

**Order**

| Value       | Finished |
| ----------- | -------- |
| `pending`   | no       |
| `matching`  | no       |
| `executing` | no       |
| `fulfilled` | yes      |

**Broadcast**

| Value            | Finished | Balance         |
| ---------------- | -------- | --------------- |
| `pending_energy` | no       | already debited |
| `ready`          | no       | already debited |
| `broadcasting`   | no       | already debited |
| `confirming`     | no       | already debited |
| `confirmed`      | yes      | debit stands    |
| `failed`         | yes      | refunded        |
| `expired`        | yes      | refunded        |

The fee is debited when the broadcast is accepted, not when it confirms, and refunded by a separate entry on `failed` and `expired`.

## Requests

| Limit                     | Value                                    |
| ------------------------- | ---------------------------------------- |
| Request body              | 1 MiB (1,048,576 bytes)                  |
| `Idempotency-Key`         | Up to 128 characters                     |
| Idempotent replay window  | 24 hours after completion                |
| In-flight key reservation | 10 minutes                               |
| `orderId` / `broadcastId` | 24 hexadecimal characters                |
| Amount unit               | `sun` (integer). `1 TRX = 1,000,000 sun` |

`Idempotency-Key` applies to `POST /v1/orders` only. Past the 24-hour replay window a reused key runs again and charges again.

## Deposits

| Deposit         | Minimum    | Purpose                                                        |
| --------------- | ---------- | -------------------------------------------------------------- |
| Account deposit | **10 TRX** | Funds the prepaid balance that pays for orders and broadcasts. |

Send it to your account's own deposit address, which you can read from `GET /v1/balance` or from the deposit screen in the dashboard. A transfer below the minimum is not credited automatically. See **Onboarding**.

## Webhooks

| Item                   | Value                                                                                                   |
| ---------------------- | ------------------------------------------------------------------------------------------------------- |
| Events                 | `order.created` · `order.fulfilled` · `broadcast.accepted` · `broadcast.confirmed` · `broadcast.failed` |
| Acknowledgement budget | 5 seconds                                                                                               |
| Signature tolerance    | 300 seconds                                                                                             |
| Signed string          | `` `${t}.${rawBody}` ``                                                                                 |
| Retry attempts         | Up to 8 on production                                                                                   |
| Retry backoff          | Exponential, starting at 1 second                                                                       |
| Event header           | `X-SaveFee-Event`                                                                                       |
| Delivery id header     | `X-SaveFee-Delivery-Id`                                                                                 |
| Signature headers      | `X-SaveFee-Signature` (changes each attempt) · `X-SaveFee-Delivery-Sig` (stable across retries)         |
| Callback URL scheme    | `https://` only, publicly resolvable                                                                    |

The attempt count differs between environments, so make the handler idempotent rather than counting on a fixed number of retries.

## API keys

| Limit                 | Value            |
| --------------------- | ---------------- |
| IP allowlist          | Up to 32 entries |
| Removing an allowlist | Set it to `null` |

## Broadcasts

| Item                         | Value                                                                    |
| ---------------------------- | ------------------------------------------------------------------------ |
| Endpoint                     | `POST /v1/broadcasts`                                                    |
| What it accepts              | A signed transaction with a single contract call                         |
| Resource provisioned         | `ENERGY` for a contract call · `BANDWIDTH` where that is what it needs   |
| `kind` on the record         | `usdt` for a USDT transfer · `tron` for anything else                    |
| Minimum expiration accepted  | 75 seconds                                                               |
| Recommended expiration       | \~600 seconds                                                            |
| Under 30 seconds left        | `422 broadcast.tx_expired`                                               |
| 30 to 75 seconds left        | `422 broadcast.insufficient_time`                                        |
| Deduplication key            | `txId` (`Idempotency-Key` is not used here)                              |
| Resubmitting the same `txId` | Accepted after `failed` or `expired`; `409` while in flight or confirmed |

For a USDT transfer specifically:

| Item                                | Value     |
| ----------------------------------- | --------- |
| Token decimals                      | 6         |
| Energy burned, repeat recipient     | \~64,000  |
| Energy burned, first-time recipient | \~130,000 |

The fee charged scales with the resource the transaction needs. Read the amount actually debited from `totalCostSun` on the broadcast record rather than assuming a fixed figure.
