> 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/api-reference/post-v1-orders.md).

# POST /v1/orders

Creates one or more energy orders and charges your balance immediately.

## Request

```bash
POST /v1/orders
Authorization: Bearer sf_live_…
Idempotency-Key: <required>
Content-Type: application/json
```

```json
{
  "items": [
    {
      "toAddress": "T…",
      "amount": 50000,
      "resource": "ENERGY",
      "durationSec": 3600
    }
  ]
}
```

| Field                 | Type    | Required | Rules                                                                                           |
| --------------------- | ------- | -------- | ----------------------------------------------------------------------------------------------- |
| `items`               | array   | yes      | 1–100 objects.                                                                                  |
| `items[].toAddress`   | string  | yes      | Valid TRON address, checksum verified, and an **activated** account. Not a contract.            |
| `items[].amount`      | integer | yes      | 50,000–200,000 inclusive. Integer only.                                                         |
| `items[].resource`    | string  | yes      | `ENERGY`.                                                                                       |
| `items[].durationSec` | integer | yes      | `60`, `300`, `900` or `3600`. Number, not string. The live list is in `GET /v1/public/pricing`. |

## Response `201`

```json
{
  "orders": [
    {
      "orderId": "65f1a2b3c4d5e6f708192a3b",
      "status": "pending",
      "receiver": "T…",
      "resource": "ENERGY",
      "resourceAmount": 50000,
      "remainAmount": 50000,
      "isMatching": true,
      "durationSec": 3600,
      "totalCostSun": 1400000,
      "createdAt": "2026-08-07T03:47:44.439Z"
    }
  ]
}
```

`orders` has one entry per item, in request order. Your balance has already been reduced by the sum of `totalCostSun`. The `totalCostSun` above is illustrative — the real figure is computed from the live price at the moment the order was placed.

## Response `200`

Identical body. Returned when the `Idempotency-Key` matches an earlier request with the same body. Nothing was charged a second time.

{% hint style="warning" %}
The replay lasts **24 hours** after the first request completed. Send the same key after that and it is treated as a new request: a second order is placed and charged. Keep retries inside the window, and reconcile with `GET /v1/orders/{orderId}` rather than resending anything older.
{% endhint %}

## Errors

| Status | `code`                         | Cause                                                             |
| ------ | ------------------------------ | ----------------------------------------------------------------- |
| `400`  | `validation.invalid_field`     | A field is missing or invalid, or `Idempotency-Key` is absent.    |
| `401`  | `api_key.invalid`              | Key missing or invalid.                                           |
| `401`  | `api_key.revoked`              | The key was revoked.                                              |
| `402`  | `wallet.insufficient_balance`  | Balance below the batch total. Carries `requiredSun`.             |
| `403`  | `api_keys.ip_not_allowed`      | The key has an IP allowlist and your source address is not on it. |
| `409`  | `idempotency.in_progress`      | The same key is still being processed. Carries `Retry-After: 2`.  |
| `413`  | `request.invalid`              | Body over 1 MiB.                                                  |
| `422`  | `order.receiver_undeliverable` | A receiver is not an activated account, or is a contract.         |
| `422`  | `idempotency.key_reuse`        | Key reused with a different body.                                 |
| `429`  | `rate_limited`                 | Too many requests. Carries `Retry-After`.                         |

## Behaviour worth knowing

**Batches are atomic.** The total is checked before anything is charged; if it exceeds your balance, no order is created and nothing is debited.

**Guards run in a fixed order:** field validation → receiver deliverability → idempotency reservation → balance.

**A `402` or a receiver `422` does not consume the `Idempotency-Key`.** Fix the cause and retry with the same key.

**Prices are read at order time.** They are not fixed, so use `totalCostSun` from the response for your accounting, and `GET /v1/public/pricing` when you need to quote in advance.
