# Refills — API reference

Source: https://tenergy.me/docs/api/refills
Last updated: 2026-10-09

Restore a receiver's USED energy or bandwidth now (it does not raise the limit). Bought from the
cheapest venue whose size range covers the amount; you pay the venue price plus your routing fee
(the same fee tiers as orders). Charged when created; once the venue reports, the part it did not
restore is refunded at the charged unit price. Uses the `orders.create` / `orders.read` scopes.
Answers `3033 refills_unavailable` while no venue is enabled on the deployment.

| Method | Path | Summary |
|---|---|---|
| `GET` | `/v1/refills` | List refills |
| `POST` | `/v1/refills` | Create a refill |
| `GET` | `/v1/refills/{refillId}` | Refill detail |

Base URL `https://api.tenergy.me/v1`, or `https://api-nile.tenergy.me/v1` on Nile ([Environments](https://tenergy.me/docs/environments)). Every request below is signed as in [Authentication](https://tenergy.me/docs/authentication) unless its **Auth** line says otherwise.

## List refills

`GET /v1/refills` · `listRefills`

**Auth:** API key (HMAC).

Newest first. Filters combine with AND.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `status` | query | string |  | One or more of `paid`, `submitted`, `completed`, `failed`, comma-separated or repeated. |
| `resource` | query | enum: `energy`, `bandwidth` |  |  |
| `receiver` | query | string |  |  |
| `client_order_id` | query | string |  |  |
| `limit` | query | integer |  |  |
| `cursor` | query | string |  |  |

### Responses

| Status | Meaning |
|---|---|
| `200` | OK |
| `400` | Malformed request — bad JSON, unknown field, wrong type. |
| `401` | Missing, malformed or rejected credentials. |
| `429` | Too many requests. |

#### Response fields (`RefillList`)

| Field | Type | Required | Description |
|---|---|---|---|
| `data` | array of object (Refill) | yes |  |
| `data[].id` | string | yes |  |
| `data[].object` | string | yes |  |
| `data[].client_order_id` | string \| null |  |  |
| `data[].status` | enum: `created`, `paid`, `submitted`, `completed`, `failed` | yes |  |
| `data[].resource` | enum: `energy`, `bandwidth` | yes |  |
| `data[].receiver` | string | yes |  |
| `data[].requested_amount` | integer | yes |  |
| `data[].restored_amount` | integer \| null |  | Units the venue restored; set when completed. |
| `data[].price_sun_per_unit` | number \| null |  | Charged SUN per requested unit (venue price + fee). |
| `data[].fee_bps` | integer | yes |  |
| `data[].fee_source` | enum: `tier`, `promo` |  |  |
| `data[].total_sun` | integer | yes | Charged when created. |
| `data[].captured_sun` | integer \| null |  | Kept at settlement: restored x unit price, rounded down. |
| `data[].refunded_sun` | integer | yes |  |
| `data[].delegate_txid` | string \| null |  |  |
| `data[].reclaim_txid` | string \| null |  |  |
| `data[].error_code` | string \| null |  |  |
| `data[].label` | string \| null |  |  |
| `data[].group_id` | string \| null |  |  |
| `data[].created_at` | string (date-time) | yes |  |
| `data[].updated_at` | string (date-time) |  |  |
| `data[].completed_at` | string (date-time) \| null |  |  |
| `next_cursor` | string \| null | yes |  |

## Create a refill

`POST /v1/refills` · `createRefill`

**Auth:** API key (HMAC).

Quotes every enabled venue for `amount`, picks the lowest TOTAL cost (unit price x amount + the
venue's fixed fee) among venues whose size range covers `amount`, charges the balance and places
the order. One refill is one venue; it is never split.

Refused before any charge: `2008 amount_out_of_range` when `amount` is outside the accepted range
for the resource (`details.min_amount`, `details.max_amount`, also published in `GET /v1/prices`
under `refills`) or above what the receiver has used now (`details.restorable_max`);
`3036 nothing_to_refill` when the receiver has used nothing (or less than the smallest refill);
`3035 no_base_resource` when it has no limit at all; `3033 refills_unavailable` when no venue is
enabled or none answered.

`status`: `paid` (charged) -> `submitted` (venue order placed) -> `completed` (venue reported;
`restored_amount` set, the unrestored part refunded in `refunded_sun`) | `failed` (fully refunded).
Webhooks `refill.completed`, `refill.failed`. Idempotent on `client_order_id` / `Idempotency-Key`
like orders: the same body returns `200` and the original.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string |  | Client-chosen key making this mutating request safe to retry, 8–128 characters of `A-Z a-z 0-9 . _ : -`. A repeat with the same key and the same body returns the original result; the same key with a different body is rejected with `3010 idempotency_conflict`. Records live for 24 hours. |

### Request body

JSON (`RefillRequest`), required.

| Field | Type | Required | Description |
|---|---|---|---|
| `client_order_id` | string |  |  |
| `receiver` | string | yes | The address whose used resource is restored. |
| `resource` | enum: `energy`, `bandwidth` |  |  |
| `amount` | integer |  | Units to restore. Required (or its alias `energy`). |
| `energy` | integer |  | Alias of `amount`. |
| `max_price_sun` | integer |  | Refuse with `3006` if the total is higher. |
| `group_id` | string |  |  |
| `label` | string |  |  |

Example request body, from the contract (illustrative values):

```json
{
  "client_order_id": "acme-refill-000001",
  "receiver": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
  "resource": "energy",
  "amount": 300000
}
```

### Responses

| Status | Meaning |
|---|---|
| `200` | Replay of an existing `client_order_id`; nothing charged. |
| `201` | Refill created and charged. |
| `400` | Malformed request — bad JSON, unknown field, wrong type. |
| `401` | Missing, malformed or rejected credentials. |
| `402` | Not enough balance to cover the order. |
| `409` | The request contradicts the current state of the object. |
| `422` | Syntactically valid but semantically impossible. |
| `429` | Too many requests. |
| `500` | Something broke on our side. |
| `503` | Temporarily unable to serve. On order creation this is fail-secure: nothing was stored and nothing was charged, so retrying verbatim with the same `client_order_id` is safe. |

#### Response fields (`Refill`)

| Field | Type | Required | Description |
|---|---|---|---|
| `id` | string | yes |  |
| `object` | string | yes |  |
| `client_order_id` | string \| null |  |  |
| `status` | enum: `created`, `paid`, `submitted`, `completed`, `failed` | yes |  |
| `resource` | enum: `energy`, `bandwidth` | yes |  |
| `receiver` | string | yes |  |
| `requested_amount` | integer | yes |  |
| `restored_amount` | integer \| null |  | Units the venue restored; set when completed. |
| `price_sun_per_unit` | number \| null |  | Charged SUN per requested unit (venue price + fee). |
| `fee_bps` | integer | yes |  |
| `fee_source` | enum: `tier`, `promo` |  |  |
| `total_sun` | integer | yes | Charged when created. |
| `captured_sun` | integer \| null |  | Kept at settlement: restored x unit price, rounded down. |
| `refunded_sun` | integer | yes |  |
| `delegate_txid` | string \| null |  |  |
| `reclaim_txid` | string \| null |  |  |
| `error_code` | string \| null |  |  |
| `label` | string \| null |  |  |
| `group_id` | string \| null |  |  |
| `created_at` | string (date-time) | yes |  |
| `updated_at` | string (date-time) |  |  |
| `completed_at` | string (date-time) \| null |  |  |

## Refill detail

`GET /v1/refills/{refillId}` · `getRefill`

**Auth:** API key (HMAC).

A `submitted` refill is brought up to date with its venue on every read.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `refillId` | path | string | yes | The refill id (`rfl_...`) or `cid:<client_order_id>`. |

### Responses

| Status | Meaning |
|---|---|
| `200` | OK |
| `401` | Missing, malformed or rejected credentials. |
| `404` | No such object, or it belongs to another account. The two are not distinguished. |
| `429` | Too many requests. |

#### Response fields (`Refill`)

| Field | Type | Required | Description |
|---|---|---|---|
| `id` | string | yes |  |
| `object` | string | yes |  |
| `client_order_id` | string \| null |  |  |
| `status` | enum: `created`, `paid`, `submitted`, `completed`, `failed` | yes |  |
| `resource` | enum: `energy`, `bandwidth` | yes |  |
| `receiver` | string | yes |  |
| `requested_amount` | integer | yes |  |
| `restored_amount` | integer \| null |  | Units the venue restored; set when completed. |
| `price_sun_per_unit` | number \| null |  | Charged SUN per requested unit (venue price + fee). |
| `fee_bps` | integer | yes |  |
| `fee_source` | enum: `tier`, `promo` |  |  |
| `total_sun` | integer | yes | Charged when created. |
| `captured_sun` | integer \| null |  | Kept at settlement: restored x unit price, rounded down. |
| `refunded_sun` | integer | yes |  |
| `delegate_txid` | string \| null |  |  |
| `reclaim_txid` | string \| null |  |  |
| `error_code` | string \| null |  |  |
| `label` | string \| null |  |  |
| `group_id` | string \| null |  |  |
| `created_at` | string (date-time) | yes |  |
| `updated_at` | string (date-time) |  |  |
| `completed_at` | string (date-time) \| null |  |  |
