Skip to content
LoginSign up

EnergyTRX API

REST API for the EnergyTRX TRON energy resale platform. Buy energy, manage Smart Energy subscriptions, list transactions, and integrate with your own scripts and bots.

OpenAPI 3.1JSONBearer authHMAC-signed writesIdempotency-Key
Base URL: https://energy-trx.com/api/v1 · openapi.json

Quickstart

  1. Sign in at /dashboard and create an API key on the API keys page.
  2. Save the full key (ek_live_…) and secret (sk_live_…) shown once at creation.
  3. Call the API with a Bearer token:
bash
curl -H "Authorization: Bearer ek_live_…" \
  https://energy-trx.com/api/v1/prices

Public endpoints (e.g. /prices) don't need auth. Read endpoints need the Bearer token. Write endpoints additionally need an HMAC signature — see Authentication.

Authentication

API key

Every request carries Authorization: Bearer ek_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Keys can be revoked at any time from the dashboard — revocation is immediate.

HMAC signing — version 2 (writes)

POST, PATCH and DELETE requests made with an API key must be signed with the key's secret (sk_live_…). Send three headers:

  • X-Signature-Version: 2
  • X-Timestamp — the current unix time in seconds.
  • X-Signature — lowercase hex HMAC-SHA256, keyed with your secret, of the string below.

The string to sign is four lines joined by a single newline (\n, no trailing newline):

string to sign
{timestamp}
{METHOD}
{path+query}
{sha256_hex(body)}
  • METHOD — upper-case HTTP method, e.g. POST.
  • path+query — the request path exactly as sent, starting with /api/v1, without scheme or host, plus ?query if there is one — e.g. /api/v1/smart-energy/clsmart123/pause.
  • sha256_hex(body) — lowercase hex SHA-256 of the exact body bytes you send. For an empty body that is e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.

Because the method and path are signed, a captured signature can't be re-pointed at another endpoint or resource. Serialize the JSON body once and send that same string — re-serializing after signing changes the bytes.

bash
ts=$(date +%s)
method=POST
path=/api/v1/orders
body='{"target_address":"T...","energy_amount":65000}'
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"
Node.js
import crypto from "node:crypto";

function signV2(secret, method, path, body, ts = Math.floor(Date.now() / 1000)) {
  const bodyHash = crypto.createHash("sha256").update(body).digest("hex");
  const signature = crypto
    .createHmac("sha256", secret)
    .update(`${ts}\n${method.toUpperCase()}\n${path}\n${bodyHash}`)
    .digest("hex");
  return {
    "X-Signature-Version": "2",
    "X-Timestamp": String(ts),
    "X-Signature": signature
  };
}

const path = "/api/v1/orders";
const body = JSON.stringify({ target_address: "T...", energy_amount: 65000 });
const res = await fetch(`https://energy-trx.com${path}`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ENERGYTRX_API_KEY}`,
    "Content-Type": "application/json",
    ...signV2(process.env.ENERGYTRX_API_SECRET, "POST", path, body)
  },
  body // the exact string that was signed
});
Python
import hashlib, hmac, json, os, time, requests

def sign_v2(secret: str, method: str, path: str, body: bytes) -> dict:
    ts = str(int(time.time()))
    body_hash = hashlib.sha256(body).hexdigest()
    message = f"{ts}\n{method.upper()}\n{path}\n{body_hash}".encode()
    return {
        "X-Signature-Version": "2",
        "X-Timestamp": ts,
        "X-Signature": hmac.new(secret.encode(), message, hashlib.sha256).hexdigest(),
    }

path = "/api/v1/orders"
body = json.dumps({"target_address": "T...", "energy_amount": 65000}).encode()
r = requests.post(
    "https://energy-trx.com" + path,
    data=body,  # the exact bytes that were signed
    headers={
        "Authorization": f"Bearer {os.environ['ENERGYTRX_API_KEY']}",
        "Content-Type": "application/json",
        **sign_v2(os.environ["ENERGYTRX_API_SECRET"], "POST", path, body),
    },
)

Timestamps & replay protection

  • X-Timestamp must be within 5 minutes of the server clock, otherwise 401 TIMESTAMP_INVALID.
  • Each signature is accepted once per API key, method and path. Sending the same signed request again inside the 5-minute window returns 401 SIGNATURE_REPLAYED — sign every request, including retries, with the current time.
  • Two byte-identical requests to the same endpoint signed in the same second have the same signature, so the second is rejected. If you get SIGNATURE_REPLAYED for a request you really want to send twice, re-sign it a second later — and use an Idempotency-Key to make retries of money-moving calls safe.
  • Exception: on endpoints that accept Idempotency-Key, re-sending a byte-identical signed request with the same key (what HTTP retry middleware does) returns the stored result — or 409 while the first attempt is still running. It is never executed twice.

Version 1 (deprecated)

Requests without X-Signature-Version (or with 1) are verified with the original scheme: hex HMAC-SHA256 of ${timestamp}.${body}. It keeps working, but it does not cover the method or path — a v1 signature of an empty-body request is the same for every empty-body endpoint. Responses to v1-signed requests carry Deprecation: true, a Link header with rel="deprecation" pointing here, and a Warning: 299 header. Replay protection applies to v1 as well. Please migrate to version 2.

Idempotency

The money-moving endpoints accept an optional Idempotency-Key header so a request can be retried after a timeout or network error without running twice:

  • POST /orders
  • POST /smart-energy
  • POST /smart-energy/{id}/topup

Use a new unique value (a UUID is recommended; 1–255 visible ASCII characters) for each operation and send the same value when retrying it. Keys are kept for 24 hours and are scoped to your account (all of its API keys).

SituationResponse
First request with a keyRuns normally; its status and body are stored for 24 hours.
Same key, same request, after it finishedThe stored response, byte for byte, with Idempotent-Replayed: true. Nothing runs again.
Same key while the first request is still running409 IDEMPOTENCY_KEY_IN_PROGRESS with Retry-After: 1.
Same key, different method, path or body422 IDEMPOTENCY_KEY_REUSED.
No Idempotency-Key headerEvery request runs (previous behaviour).

"The same request" means the same method, path (incl. query) and body bytes. The stored result is replayed whether it was a success or an error (for example 402 INSUFFICIENT_BALANCE): to try again after fixing the cause, use a new key. Requests rejected before they run — authentication, signature, rate limit or body validation errors — are not stored, so you can fix them and retry with the same key. If a first attempt never finishes (e.g. a server restart mid-request) its key stays "in progress" until it expires; check the resource (e.g. GET /orders) before retrying with a new key.

Node.js — retry with the same key
// signV2() as in the Authentication section.
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function createOrder(targetAddress, energyAmount) {
  const idempotencyKey = crypto.randomUUID(); // one key per operation, reused on every retry
  const path = "/api/v1/orders";
  const body = JSON.stringify({ target_address: targetAddress, energy_amount: energyAmount });

  for (let attempt = 1; attempt <= 5; attempt++) {
    let res;
    try {
      res = await fetch(`https://energy-trx.com${path}`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.ENERGYTRX_API_KEY}`,
          "Content-Type": "application/json",
          "Idempotency-Key": idempotencyKey,
          ...signV2(process.env.ENERGYTRX_API_SECRET, "POST", path, body) // fresh signature per attempt
        },
        body
      });
    } catch {
      await sleep(1000 * attempt); // network error or timeout: retry with the same key
      continue;
    }
    const json = await res.json();
    if (json.error?.code === "IDEMPOTENCY_KEY_IN_PROGRESS") {
      await sleep(1000); // the first attempt is still running
      continue;
    }
    // Idempotent-Replayed: true → this is the stored result of an earlier attempt.
    return json;
  }
  throw new Error("Order request did not complete — check GET /orders before trying again.");
}

Rate limits

API-key callers are limited to 180 requests / 60 seconds per key. Every response includes:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset (unix seconds)

On 429 a Retry-After header tells you exactly how many seconds to wait before retrying.

The public /prices endpoint is limited to 120 requests per minute per client IP.

Errors

Every error response shares one shape:

json
{
  "error": { "code": "RESOURCE_NOT_FOUND", "message": "Order not found." },
  "meta":  { "request_id": "ab12cd34ef56gh78" }
}

Body validation failures (INVALID_REQUEST) list every problem in details.issues as { field, message } entries.

CodeHTTPMeaning
AUTH_REQUIRED401No credentials supplied.
INVALID_API_KEY401Key not found, revoked, or expired.
INVALID_SIGNATURE401HMAC mismatch, missing signature headers, or unsupported X-Signature-Version on a write.
TIMESTAMP_INVALID401X-Timestamp outside the 5-minute skew window.
SIGNATURE_REPLAYED401This signature was already used. Re-sign with the current X-Timestamp.
RATE_LIMIT_EXCEEDED429Rate limit hit (per key, or per IP on /prices). See Retry-After.
INVALID_REQUEST400Validation failed — see `details.issues`.
INSUFFICIENT_BALANCE402Not enough TRX for this operation.
RESOURCE_NOT_FOUND404The requested resource doesn't exist or isn't yours.
RESOURCE_CONFLICT409Conflicting state — e.g. cancelling a non-pending order.
IDEMPOTENCY_KEY_IN_PROGRESS409A request with this Idempotency-Key is still running. Retry shortly.
IDEMPOTENCY_KEY_REUSED422The Idempotency-Key was already used for a different request.
SERVICE_UNAVAILABLE503Service temporarily unavailable. Safe to retry.
INTERNAL_ERROR500Unexpected server error. Cite the `request_id` if reporting.

Webhooks

Subscribe an HTTPS endpoint to events on the webhooks page of your dashboard (creating, editing and deleting subscriptions is dashboard-only; GET /webhooks lists them). The signing secret (whsec_…) is shown once at creation. Events you can subscribe to:

order.createdorder.completedorder.failedorder.cancelledorder.expireddeposit.receivedsmart_energy.activatedsmart_energy.pausedsmart_energy.resumedsmart_energy.topped_upsmart_energy.depleted

Each delivery is a POST with a JSON body shaped { id, event, user_id, created, data }.

Delivery

  • Only a 2xx response within 10 seconds counts as delivered.
  • Redirects are not followed: a 3xx response is a failed attempt. Point the webhook at the final URL.
  • Failed attempts are retried after 1 min, 5 min, 30 min, 2 h and 12 h. Webhooks whose deliveries keep failing are disabled automatically — re-enable them from the dashboard once fixed.
  • Only the first 2 KB of your response body is read (for delivery diagnostics); keep responses short.
  • Delivery is at-least-once: use X-Energytrx-Delivery to ignore duplicates. It stays the same across retries of one delivery.

Headers

HeaderValue
X-Energytrx-EventEvent type, e.g. order.completed.
X-Energytrx-DeliveryDelivery id — stable across retries; use it to drop duplicates.
X-Energytrx-TimestampUnix seconds when this attempt was signed.
X-Energytrx-Signature-V2t=<timestamp>,v1=<hex HMAC-SHA256(secret, "<timestamp>.<raw body>")> — verify this one.
X-Energytrx-SignatureLegacy: hex HMAC-SHA256(secret, raw body). Unchanged; no replay protection.

Verifying deliveries

  1. Read the raw request body before parsing JSON, and the t and v1 values from X-Energytrx-Signature-V2.
  2. Compute hex HMAC-SHA256 of ${t}.${rawBody} with your webhook secret and compare it with v1 in constant time.
  3. Reject the delivery if t is more than 5 minutes from your clock — this stops replays.
  4. Ignore deliveries whose X-Energytrx-Delivery you have already processed.

Every retry is signed again with a fresh t. The legacy X-Energytrx-Signature header (HMAC of the body only) is still sent unchanged for existing integrations, but it can't detect replays — prefer the v2 header.

Node.js
import crypto from "node:crypto";

// rawBody: the request body exactly as received (string or Buffer), not re-serialized JSON.
export function verifyEnergyTrxWebhook(rawBody, headers, secret, toleranceSec = 300) {
  const header = headers["x-energytrx-signature-v2"] ?? "";
  const parts = Object.fromEntries(
    header.split(",").map((kv) => {
      const i = kv.indexOf("=");
      return [kv.slice(0, i).trim(), kv.slice(i + 1).trim()];
    })
  );
  const t = Number(parts.t);
  if (!Number.isInteger(t) || !parts.v1) return false;
  if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSec) return false; // stale or replayed

  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Python
import hashlib, hmac, time

def verify_energytrx_webhook(raw_body: bytes, headers, secret: str, tolerance: int = 300) -> bool:
    header = headers.get("X-Energytrx-Signature-V2", "")
    parts = dict(p.strip().split("=", 1) for p in header.split(",") if "=" in p)
    try:
        t = int(parts["t"])
    except (KeyError, ValueError):
        return False
    if abs(time.time() - t) > tolerance:
        return False  # stale or replayed
    expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))
bash — manual check
# t and v1 from X-Energytrx-Signature-V2, body saved byte-for-byte to body.json
t=1760000000
expected=$( { printf "%s." "$t"; cat body.json; } | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $NF}')
echo "$expected"   # must equal v1

Endpoint reference

Auto-generated from the OpenAPI spec. All paths are relative to https://energy-trx.com/api/v1.

GET/pricesPublic

Get current energy prices

Public endpoint — no authentication required. Returns live per-package pricing in TRX. Rate-limited to 120 requests per minute per client IP.

curl https://energy-trx.com/api/v1/prices

Response

200 Current pricing
json
{
  "data": {
    "currency": "TRX",
    "price_per_package_trx": 3.14,
    "package_units": 65000,
    "min_order_units": 65000,
    "max_order_units": 1000000,
    "default_duration_hours": 1,
    "enabled_packages": [
      65000,
      131000,
      650000,
      1000000
    ],
    "quotes": {
      "65000": 3.14,
      "131000": 6.28,
      "650000": 31.4,
      "1000000": 48.3
    },
    "updated_at": "2026-05-27T10:00:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
429RATE_LIMIT_EXCEEDED — per-IP limit; see Retry-After
GET/account

Get the authenticated user's account

Returns the caller's profile, balances, and deposit address.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/account

Response

200 Account info
json
{
  "data": {
    "user_id": "clu0a1b2c3d4e5f6g7h8i9",
    "email": "you@example.com",
    "balance_trx": "1234.567890",
    "balance_usdt": "456.78",
    "deposit_address": "TXyZabc1234567890ABCDEF",
    "deposit_network": "TRC-20",
    "created_at": "2026-04-15T09:30:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/orders

List your orders

Paginated list, newest first. Optional `status` filter accepts any OrderStatus.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/orders?page=1&per_page=50&status=completed&from=2026-10-01T00%3A00%3A00.000Z&to=2026-10-31

Parameters

NameInTypeRequiredDescription
pagequeryintegerno
Page number, 1-indexed.
e.g. 1
per_pagequeryintegerno
Page size (max 100).
e.g. 50
statusquerystringno
Filter to one status value (e.g. `pending`).
e.g. completed
fromquerystringno
Inclusive lower bound on created_at: an ISO 8601 date-time, or a date (start of that UTC day).
e.g. 2026-10-01T00:00:00.000Z
toquerystringno
Inclusive upper bound on created_at: an ISO 8601 date-time, or a date (end of that UTC day). INVALID_REQUEST when earlier than `from`.
e.g. 2026-10-31

Response

200 Paginated orders
json
{
  "data": [
    {
      "id": "clord1234567890",
      "status": "completed",
      "energy_amount": "65000",
      "duration_hours": 1,
      "target_address": "TXyZrecipient1234567890ABCDEF",
      "cost_trx": "3.140000",
      "tx_id": "2c1d3e9b...",
      "created_at": "2026-05-27T10:15:22.000Z",
      "updated_at": "2026-05-27T10:16:01.000Z",
      "expires_at": "2026-05-27T11:15:22.000Z",
      "cancellable": false
    }
  ],
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "page": 1,
    "per_page": 50,
    "total": 1,
    "has_more": false
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
POST/orders

Create an Energy Transfer order

Delegates energy to `target_address` for 1 hour. Debits `cost_trx` from your TRX balance. Send an `Idempotency-Key` to make retries safe.

# HMAC-signed write (signature v2)
ts=$(date +%s)
method=POST
path=/api/v1/orders
body='{ "target_address": "TXyZrecipient1234567890ABCDEF", "energy_amount": 65000 }'
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')
idempotency_key=$(uuidgen)   # reuse the same key when retrying this operation

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Idempotency-Key: $idempotency_key" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"

Parameters

NameInTypeRequiredDescription
Idempotency-Keyheaderstringno
Optional. A unique value per operation (a UUID is recommended, 1-255 visible ASCII chars). Retrying with the same key within 24 h returns the stored result (header `Idempotent-Replayed: true`) instead of executing again.
e.g. 0f8fad5b-d9cb-469f-a165-70867728950e

Request body

Content-Type: application/json

json
{
  "target_address": "TXyZrecipient1234567890ABCDEF",
  "energy_amount": 65000
}

Response

201 Order created
json
{
  "data": {
    "id": "clord1234567890",
    "status": "completed",
    "energy_amount": "65000",
    "duration_hours": 1,
    "target_address": "TXyZrecipient1234567890ABCDEF",
    "cost_trx": "3.140000",
    "tx_id": "2c1d3e9b...",
    "created_at": "2026-05-27T10:15:22.000Z",
    "updated_at": "2026-05-27T10:16:01.000Z",
    "expires_at": "2026-05-27T11:15:22.000Z",
    "cancellable": false
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
400INVALID_REQUEST
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
402INSUFFICIENT_BALANCE
409IDEMPOTENCY_KEY_IN_PROGRESS — the first request with this Idempotency-Key is still running (Retry-After: 1)
422IDEMPOTENCY_KEY_REUSED — the Idempotency-Key was already used for a different request
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/orders/{id}

Get an order

Single-order lookup scoped to the caller.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/orders/clord1234567890

Parameters

NameInTypeRequiredDescription
idpathstringyes
Order id.
e.g. clord1234567890

Response

200 Order
json
{
  "data": {
    "id": "clord1234567890",
    "status": "completed",
    "energy_amount": "65000",
    "duration_hours": 1,
    "target_address": "TXyZrecipient1234567890ABCDEF",
    "cost_trx": "3.140000",
    "tx_id": "2c1d3e9b...",
    "created_at": "2026-05-27T10:15:22.000Z",
    "updated_at": "2026-05-27T10:16:01.000Z",
    "expires_at": "2026-05-27T11:15:22.000Z",
    "cancellable": false
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
POST/orders/{id}/cancel

Cancel a pending order

Refunds the order cost to your TRX balance. Only an order that was never dispatched for delivery can be cancelled (see the order's `cancellable` field); dispatched orders return 409.

# HMAC-signed write (signature v2)
ts=$(date +%s)
method=POST
path=/api/v1/orders/clord1234567890/cancel
body=''
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"

Parameters

NameInTypeRequiredDescription
idpathstringyes
Order id.
e.g. clord1234567890

Response

200 Order cancelled
json
{
  "data": {
    "id": "clord1234567890",
    "status": "completed",
    "energy_amount": "65000",
    "duration_hours": 1,
    "target_address": "TXyZrecipient1234567890ABCDEF",
    "cost_trx": "3.140000",
    "tx_id": "2c1d3e9b...",
    "created_at": "2026-05-27T10:15:22.000Z",
    "updated_at": "2026-05-27T10:16:01.000Z",
    "expires_at": "2026-05-27T11:15:22.000Z",
    "cancellable": false
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
409RESOURCE_CONFLICT — order is not pending
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/smart-energy

List Smart Energy subscriptions

Your active subscriptions. Pass `include_deleted=1` to include soft-deleted rows.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/smart-energy?include_deleted=0

Parameters

NameInTypeRequiredDescription
include_deletedquerystringno
Include soft-deleted subs.
e.g. 0

Response

200 Array of subscriptions
json
{
  "data": [
    {
      "id": "clsmart1234567890",
      "address": "TXyZrecipient1234567890ABCDEF",
      "product_slug": "smart-delegation-65k",
      "product_name": "Smart Energy 65k",
      "status": "active",
      "balance_trx": "100.000000",
      "total_delegations": 42,
      "deleted_at": null,
      "refund_amount_trx": null,
      "created_at": "2026-05-20T08:00:00.000Z"
    }
  ],
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "count": 1
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
POST/smart-energy

Create a Smart Energy subscription

Locks `top_up_trx` from your balance and auto-delivers energy to `address` whenever it needs it. Send an `Idempotency-Key` to make retries safe.

# HMAC-signed write (signature v2)
ts=$(date +%s)
method=POST
path=/api/v1/smart-energy
body='{ "address": "TXyZrecipient1234567890ABCDEF", "top_up_trx": 100, "product_slug": "smart-delegation-65k" }'
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')
idempotency_key=$(uuidgen)   # reuse the same key when retrying this operation

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Idempotency-Key: $idempotency_key" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"

Parameters

NameInTypeRequiredDescription
Idempotency-Keyheaderstringno
Optional. A unique value per operation (a UUID is recommended, 1-255 visible ASCII chars). Retrying with the same key within 24 h returns the stored result (header `Idempotent-Replayed: true`) instead of executing again.
e.g. 0f8fad5b-d9cb-469f-a165-70867728950e

Request body

Content-Type: application/json

json
{
  "address": "TXyZrecipient1234567890ABCDEF",
  "top_up_trx": 100,
  "product_slug": "smart-delegation-65k"
}

Response

201 Subscription created
json
{
  "data": {
    "id": "clsmart1234567890",
    "address": "TXyZrecipient1234567890ABCDEF",
    "product_slug": "smart-delegation-65k",
    "product_name": "Smart Energy 65k",
    "status": "active",
    "balance_trx": "100.000000",
    "total_delegations": 42,
    "deleted_at": null,
    "refund_amount_trx": null,
    "created_at": "2026-05-20T08:00:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
400INVALID_REQUEST
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
402INSUFFICIENT_BALANCE
409RESOURCE_CONFLICT — duplicate active subscription for this address / IDEMPOTENCY_KEY_IN_PROGRESS
422IDEMPOTENCY_KEY_REUSED — the Idempotency-Key was already used for a different request
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/smart-energy/{id}

Get a subscription

Single-subscription lookup scoped to the caller.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/smart-energy/clsmart1234567890

Parameters

NameInTypeRequiredDescription
idpathstringyes
Subscription id.
e.g. clsmart1234567890
refreshquerystringno
`1` re-reads the live delivery state before responding (at most once per 30 s per subscription; otherwise the stored state is returned).

Response

200 Subscription
json
{
  "data": {
    "id": "clsmart1234567890",
    "address": "TXyZrecipient1234567890ABCDEF",
    "product_slug": "smart-delegation-65k",
    "product_name": "Smart Energy 65k",
    "status": "active",
    "balance_trx": "100.000000",
    "total_delegations": 42,
    "deleted_at": null,
    "refund_amount_trx": null,
    "created_at": "2026-05-20T08:00:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
POST/smart-energy/{id}/pause

Pause a subscription

Halts auto-delegation. Balance is preserved; resume any time.

# HMAC-signed write (signature v2)
ts=$(date +%s)
method=POST
path=/api/v1/smart-energy/clsmart1234567890/pause
body=''
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"

Parameters

NameInTypeRequiredDescription
idpathstringyes
Subscription id.
e.g. clsmart1234567890

Response

200 Paused
json
{
  "data": {
    "id": "clsmart1234567890",
    "address": "TXyZrecipient1234567890ABCDEF",
    "product_slug": "smart-delegation-65k",
    "product_name": "Smart Energy 65k",
    "status": "active",
    "balance_trx": "100.000000",
    "total_delegations": 42,
    "deleted_at": null,
    "refund_amount_trx": null,
    "created_at": "2026-05-20T08:00:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
409RESOURCE_CONFLICT — not in active state
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
POST/smart-energy/{id}/resume

Resume a paused subscription

Returns the subscription to active state.

# HMAC-signed write (signature v2)
ts=$(date +%s)
method=POST
path=/api/v1/smart-energy/clsmart1234567890/resume
body=''
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"

Parameters

NameInTypeRequiredDescription
idpathstringyes
Subscription id.
e.g. clsmart1234567890

Response

200 Resumed
json
{
  "data": {
    "id": "clsmart1234567890",
    "address": "TXyZrecipient1234567890ABCDEF",
    "product_slug": "smart-delegation-65k",
    "product_name": "Smart Energy 65k",
    "status": "active",
    "balance_trx": "100.000000",
    "total_delegations": 42,
    "deleted_at": null,
    "refund_amount_trx": null,
    "created_at": "2026-05-20T08:00:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
409RESOURCE_CONFLICT — not in paused state
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
POST/smart-energy/{id}/topup

Top up a subscription's balance

Adds TRX to an active subscription. Send an `Idempotency-Key` to make retries safe.

# HMAC-signed write (signature v2)
ts=$(date +%s)
method=POST
path=/api/v1/smart-energy/clsmart1234567890/topup
body='{ "top_up_trx": 50 }'
body_hash=$(printf "%s" "$body" | openssl dgst -sha256 | awk '{print $NF}')
sig=$(printf "%s\n%s\n%s\n%s" "$ts" "$method" "$path" "$body_hash" \
  | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')
idempotency_key=$(uuidgen)   # reuse the same key when retrying this operation

curl -X "$method" \
  -H "Authorization: Bearer $KEY" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: $ts" \
  -H "X-Signature: $sig" \
  -H "Idempotency-Key: $idempotency_key" \
  -H "Content-Type: application/json" \
  -d "$body" \
  "https://energy-trx.com$path"

Parameters

NameInTypeRequiredDescription
idpathstringyes
Subscription id.
e.g. clsmart1234567890
Idempotency-Keyheaderstringno
Optional. A unique value per operation (a UUID is recommended, 1-255 visible ASCII chars). Retrying with the same key within 24 h returns the stored result (header `Idempotent-Replayed: true`) instead of executing again.
e.g. 0f8fad5b-d9cb-469f-a165-70867728950e

Request body

Content-Type: application/json

json
{
  "top_up_trx": 50
}

Response

200 Topped up
json
{
  "data": {
    "id": "clsmart1234567890",
    "address": "TXyZrecipient1234567890ABCDEF",
    "product_slug": "smart-delegation-65k",
    "product_name": "Smart Energy 65k",
    "status": "active",
    "balance_trx": "100.000000",
    "total_delegations": 42,
    "deleted_at": null,
    "refund_amount_trx": null,
    "created_at": "2026-05-20T08:00:00.000Z"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
400INVALID_REQUEST
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
402INSUFFICIENT_BALANCE
404RESOURCE_NOT_FOUND
409RESOURCE_CONFLICT — subscription not active / IDEMPOTENCY_KEY_IN_PROGRESS
422IDEMPOTENCY_KEY_REUSED — the Idempotency-Key was already used for a different request
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/smart-energy/{id}/history

Get a subscription's activity feed

Top-ups and pause / resume / delete / withdraw events for one subscription, newest first, up to 200 entries.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/smart-energy/clsmart1234567890/history

Parameters

NameInTypeRequiredDescription
idpathstringyes
Subscription id.
e.g. clsmart1234567890

Response

200 Activity entries
json
{
  "data": [
    {
      "id": "clact1234567890",
      "type": "topped_up",
      "created_at": "2026-10-01T12:00:00.000Z",
      "refunded_trx": null
    }
  ],
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "count": 1
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/transactions

List your transactions

Your transaction ledger, newest first. Some non-customer system entries are excluded, as are below-minimum deposits unless `include_uncredited=1`. `meta.summary` carries totals over the whole filtered set.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/transactions?page=1&per_page=50&type=deposit&from=2026-10-01T00%3A00%3A00.000Z&to=2026-10-31

Parameters

NameInTypeRequiredDescription
pagequeryintegerno
Page number.
e.g. 1
per_pagequeryintegerno
Page size (max 100).
e.g. 50
typequerystringno
Filter by ledger type.
e.g. deposit
fromquerystringno
Inclusive lower bound on created_at: an ISO 8601 date-time, or a date (start of that UTC day).
e.g. 2026-10-01T00:00:00.000Z
toquerystringno
Inclusive upper bound on created_at: an ISO 8601 date-time, or a date (end of that UTC day). INVALID_REQUEST when earlier than `from`.
e.g. 2026-10-31
include_uncreditedquerystringno
`1` also returns below-minimum deposits (credited: false, signed_amount "0").

Response

200 Paginated transactions
json
{
  "data": [
    {
      "id": "cltx1234567890",
      "type": "deposit",
      "amount": "100",
      "currency": "TRX",
      "status": "confirmed",
      "tx_hash": "9f8e7d6c5b4a3210...",
      "created_at": "2026-05-26T14:22:11.000Z",
      "signed_amount": "100",
      "credited": true,
      "subscription_id": null,
      "target_address": null,
      "running_balance": "1234.56789"
    }
  ],
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "page": 1,
    "per_page": 50,
    "total": 1,
    "has_more": false,
    "summary": [
      {
        "currency": "TRX",
        "total_credits": "100",
        "total_debits": "0",
        "net": "100"
      }
    ]
  }
}

Errors

StatusDescription
400INVALID_REQUEST — malformed or reversed from / to
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/transactions/{id}

Get a transaction

Single-transaction lookup. Returns 404 if the transaction isn't part of your visible ledger.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/transactions/cltx1234567890

Parameters

NameInTypeRequiredDescription
idpathstringyes
Transaction id.
e.g. cltx1234567890

Response

200 Transaction
json
{
  "data": {
    "id": "cltx1234567890",
    "type": "deposit",
    "amount": "100",
    "currency": "TRX",
    "status": "confirmed",
    "tx_hash": "9f8e7d6c5b4a3210...",
    "created_at": "2026-05-26T14:22:11.000Z",
    "signed_amount": "100",
    "credited": true,
    "subscription_id": null,
    "target_address": null,
    "running_balance": "1234.56789"
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78"
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
404RESOURCE_NOT_FOUND
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/webhooks

List your webhook subscriptions

Returns the public projection — never the signing secret. Read-only on this surface; create / edit / delete / test live behind the dashboard at /dashboard/webhooks (session-authenticated). Outbound deliveries are signed: `X-Energytrx-Timestamp` + `X-Energytrx-Signature-V2` (timestamped, recommended) and the legacy `X-Energytrx-Signature` — see `x-events.signatures`.

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/webhooks

Response

200 Array of webhooks
json
{
  "data": [
    {
      "id": "clwh1234567890",
      "url": "https://your-server.example.com/webhook",
      "events": [
        "order.created",
        "deposit.received"
      ],
      "active": true,
      "failure_count": 0,
      "last_delivery_at": "2026-05-27T10:00:00.000Z",
      "last_failure_at": null,
      "created_at": "2026-05-20T08:00:00.000Z",
      "updated_at": "2026-05-20T08:00:00.000Z"
    }
  ],
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "count": 1
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/api-keys

List your API keys

Returns the public projection — never the full key or secret. Read-only on this surface; key creation + revocation live behind the dashboard at /dashboard/api-keys (session-authenticated).

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/api-keys

Response

200 Array of keys
json
{
  "data": [
    {
      "id": "clkey1234567890",
      "name": "Production server",
      "prefix": "a1b2c3d4",
      "scopes": [
        "read",
        "write"
      ],
      "lastUsedAt": "2026-05-27T09:00:00.000Z",
      "lastUsedIp": "203.0.113.42",
      "expiresAt": null,
      "revokedAt": null,
      "createdAt": "2026-05-01T12:00:00.000Z"
    }
  ],
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "count": 1
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry
GET/api-usage

Aggregate your recent API traffic

Returns daily request counts, top endpoints, per-key breakdown, and overall error rate for the last `days` days (default 7, max 90).

curl -H "Authorization: Bearer $KEY" https://energy-trx.com/api/v1/api-usage?days=7

Parameters

NameInTypeRequiredDescription
daysqueryintegerno
Window length in days (1..90).
e.g. 7
api_key_idquerystringno
Narrow to a single API key.

Response

200 Aggregated usage
json
{
  "data": {
    "total_requests": 1247,
    "total_errors": 12,
    "error_rate": 0.0096,
    "unique_endpoints": 8,
    "daily": [
      {
        "date": "2026-05-27",
        "total": 247,
        "errors": 1
      }
    ],
    "top_endpoints": [
      {
        "method": "GET",
        "path": "/api/v1/prices",
        "count": 612,
        "error_count": 0
      }
    ],
    "per_key": [
      {
        "api_key_id": "clkey1234567890",
        "count": 1247,
        "error_count": 12
      }
    ]
  },
  "meta": {
    "request_id": "ab12cd34ef56gh78",
    "window_days": 7
  }
}

Errors

StatusDescription
401AUTH_REQUIRED / INVALID_API_KEY / INVALID_SIGNATURE / TIMESTAMP_INVALID / SIGNATURE_REPLAYED
429RATE_LIMIT_EXCEEDED — see X-RateLimit-Reset + Retry-After
500INTERNAL_ERROR — server fault, include the request_id when reporting
503SERVICE_UNAVAILABLE — service temporarily unavailable, safe to retry