Skip to content

POST /apiv2/time/add

Add a TRON address to Host Mode and, optionally, register a callback URL for delegation notifications.

Endpoint URL

POST https://netts.io/apiv2/time/add

Authentication

Provide your API key in the request body (api_key) or the X-API-KEY header. The request IP must be in the whitelist configured for your API key.

Request Body

json
{
    "api_key": "your_api_key",
    "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "callback_url": "https://your-server.com/webhook",
    "infinity": true
}

Parameters

ParameterTypeRequiredDescription
api_keystringYes*API key. Can also be sent in the X-API-KEY header.
addressstringYesTRON (TRC-20) address, must match ^T[1-9A-HJ-NP-Za-km-z]{33}$ (starts with T, 34 characters).
callback_urlstringNoPublic HTTP/HTTPS URL to notify when energy is delegated to the address. Max 2048 characters.
infinitybooleanNotrue — also switch the address straight into infinity mode, saving a separate call to /apiv2/time/infinitystart. Defaults to false.

* Required in the body unless the X-API-KEY header is used.

callback_url validation: must be http/https, a public host only (localhost, private RFC1918 ranges, link-local 169.254.0.0/16, IPv6 private/link-local, reserved and multicast addresses are rejected), and at most 2048 characters.

Behaviour

  • If the address is new, it is added to Host Mode with status inactive (status = 0, cycle_set = 0). Activate it later with /apiv2/time/order or /apiv2/time/infinitystart.
  • If the address already exists under your account, the call updates its callback URL.
  • If callback_url is provided, it is stored (or updated) for that address.

infinity

With "infinity": true the address is added and activated in infinity mode in one call — the same result as calling /apiv2/time/add and then /apiv2/time/infinitystart. Billing is identical to the separate call: nothing is charged at this point, and cycles are charged one by one as energy is delegated. See Host Mode → Cycles and Pricing.

Adding the address and switching it on are two separate steps, and only the first one is guaranteed. The response reports the result of adding. If the address was added but could not be switched on, the call still returns code: 0 with the usual message — the address is simply left inactive, exactly as if you had not passed the flag. Switching on is skipped when:

  • your balance does not cover one cycle at the current price;
  • the address is already active;
  • the address already has an open order.

The response is the same with and without the flag — no extra fields, no extra error codes, and it does not tell you whether infinity mode was actually switched on. Confirm it with Time Status: the address reports status: "active" and mode: "infinity", and the order id is in that response. Do not treat code: 0 from this endpoint as proof that the mode is running.

Example Requests

cURL

bash
curl -X POST https://netts.io/apiv2/time/add \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "YOUR_API_KEY_HERE",
    "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "callback_url": "https://your-server.com/webhook"
  }'

Python

python
import requests

url = "https://netts.io/apiv2/time/add"
data = {
    "api_key": "YOUR_API_KEY_HERE",
    "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
    "callback_url": "https://your-server.com/webhook",  # optional
    # "infinity": True,  # optional: also switch the address into infinity mode
}

resp = requests.post(url, json=data, timeout=30)
result = resp.json()

if result["code"] == 0:
    print("Added:", result["data"]["address"])
else:
    print("Error:", result["msg"])

Node.js

javascript
const axios = require('axios');

const data = {
    api_key: 'YOUR_API_KEY_HERE',
    address: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
    // callback_url: 'https://your-server.com/webhook', // optional
    // infinity: true, // optional: also switch the address into infinity mode
};

axios.post('https://netts.io/apiv2/time/add', data)
    .then(({ data: result }) => {
        if (result.code === 0) console.log('Added:', result.data.address);
        else console.error('Error:', result.msg);
    })
    .catch(err => console.error('Request failed:', err.response?.data || err.message));

Response

Success (new address)

json
{
    "code": 0,
    "msg": "Address added to Host Mode successfully",
    "data": {
        "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
        "callback_url": "https://your-server.com/webhook",
        "timestamp": "2026-07-13T05:30:15.123456"
    }
}

Success (callback URL updated for an existing address)

json
{
    "code": 0,
    "msg": "Address callback URL updated successfully",
    "data": {
        "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
        "callback_url": "https://new-webhook.com/endpoint",
        "timestamp": "2026-07-13T05:35:20.789012"
    }
}

Response Fields

FieldTypeDescription
codeinteger0 = success, negative = error
msgstringHuman-readable message
data.addressstringThe address that was added/updated
data.callback_urlstring | nullThe registered callback URL (null if none)
data.timestampstringISO timestamp of the operation

Error Responses

All errors use code = -1 and describe the problem in msg:

msgCause
API key required in X-API-KEY header or request bodyNo API key provided
Invalid API key or IP not in whitelistAuthentication failed
Invalid TRC-20 address formatAddress does not match the required format
Invalid callback URL. Only public HTTP/HTTPS URLs are allowedCallback URL rejected by validation
Address belongs to another userThe address is registered under a different account
Database error adding/updating addressTemporary server-side error — retry
Internal server errorUnexpected error — retry or contact support
json
{ "code": -1, "msg": "Invalid API key or IP not in whitelist", "data": null }

HTTP status codes

Endpoint errors are returned with HTTP 200 and a negative code — check code, not the HTTP status. Error bodies always include "data": null.

Some errors are returned before the request reaches the endpoint. They use a non-200 status and a different body shape:

HTTPBodyCause
402{"detail": {"code": 1004, "msg": "Insufficient funds. Minimum balance is 4 TRX. Please top up your account."}}Account balance is too low
403{"detail": {"code": 1005, "msg": "API key is blocked. Contact support."}}The API key is blocked — contact support
422{"detail": [ … ]}Request body failed validation: a required field is missing or has the wrong type. Note there is no code field in this response

Callbacks (webhooks)

If you registered a callback_url, the system calls it each time energy is delegated to the address (i.e. once per delegation cycle as it is processed).

Request format

The system sends an HTTP GET request with query parameters:

A cycle born from a USDT transfer — energy_used present:

GET https://your-server.com/webhook?address=TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE&order_id=T149936&hash=97b4eb0257088aefcb286229aa42ec750f27554390dd4e186f55efe273666577&balance_after=142.3500&idle_cycle=0&energy_used=65k&charged=2.0000

A cycle with no preceding transfer — energy_used omitted:

GET https://your-server.com/webhook?address=TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE&order_id=T149937&hash=97b4eb0257088aefcb286229aa42ec750f27554390dd4e186f55efe273666577&balance_after=138.3500&idle_cycle=0&charged=4.0000
ParameterDescription
addressThe TRON address that received the energy delegation
order_idDelegation identifier (T + internal delegation id) — unique per delegation
hashOn-chain transaction hash of the energy delegation
balance_afterYour account balance in TRX right after this charge (snapshot at charge time; it may have changed by the moment the callback arrives)
idle_cycle1 — this delegation was issued after 24 hours with no transfer (idle re-delegation), 0 — a regular cycle born from your transfer or activation
energy_usedTariff band of the energy consumed by the transfer that produced this cycle: 65k (65,000 energy or less → 2 TRX) or 131k (more than 65,000 → 4 TRX). Optional — the key is omitted from the query string entirely (not sent empty) when there was no preceding transfer to measure: the first delegation of an activation, every idle re-delegation, and an address with no consumption history yet. All of those are charged at the 4 TRX rate
chargedAmount in TRX charged for this cycle — 2.0000 or 4.0000, matching the tariff in energy_used. Always present, including when energy_used is omitted. See Host Mode → Cycles and Pricing

Use order_id and hash to distinguish one delegation from another and to reconcile with your own records — two callbacks for the same address differ by these values. Use charged to track spend per cycle without polling /apiv2/time/status, and energy_used to see which tariff the previous transfer fell into. Read energy_used as an optional parameter — a missing key means "no transfer to measure", not an error, and never assume a default value for it.

Example handler (Python / Flask)

python
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/webhook', methods=['GET'])
def energy_delegation_webhook():
    address = request.args.get('address')
    order_id = request.args.get('order_id')
    tx_hash = request.args.get('hash')
    charged = request.args.get('charged')          # TRX charged for this cycle
    energy_used = request.args.get('energy_used')  # '65k' | '131k' | None (key may be absent)

    if not address:
        return jsonify({"error": "Missing address parameter"}), 400

    # Your business logic (idempotent by order_id / hash)
    print(f"Energy delegated: address={address} order_id={order_id} hash={tx_hash} "
          f"charged={charged} energy_used={energy_used}")
    return jsonify({"status": "success"}), 200

Delivery behaviour

  • Method: GET, timeout ~10 seconds. Return HTTP 200 to acknowledge.
  • Retries: up to 3 attempts are made if the request fails; if all fail, the callback is dropped (energy delegation still happens regardless).
  • No signature: the request is not signed by Netts. The secret (if any) is whatever you embedded in your own callback_url.
  • Reconciliation: because callbacks can be missed, also poll /apiv2/time/status and make your handler idempotent.

Updating / removing the callback

  • Update: call /apiv2/time/add again with the same address and a new callback_url.
  • Remove: call /apiv2/time/delete to remove the address (this also removes its callback); re-add without callback_url if needed.

Notes

  • New addresses start inactive; activate them with an order, with infinity start, or by passing "infinity": true here.
  • The same address cannot be registered under two different accounts.
  • The address should be activated on the TRON network before adding it.