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/addAuthentication
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
{
"api_key": "your_api_key",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"callback_url": "https://your-server.com/webhook",
"infinity": true
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| api_key | string | Yes* | API key. Can also be sent in the X-API-KEY header. |
| address | string | Yes | TRON (TRC-20) address, must match ^T[1-9A-HJ-NP-Za-km-z]{33}$ (starts with T, 34 characters). |
| callback_url | string | No | Public HTTP/HTTPS URL to notify when energy is delegated to the address. Max 2048 characters. |
| infinity | boolean | No | true — 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/orderor/apiv2/time/infinitystart. - If the address already exists under your account, the call updates its callback URL.
- If
callback_urlis 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
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
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
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)
{
"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)
{
"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
| Field | Type | Description |
|---|---|---|
| code | integer | 0 = success, negative = error |
| msg | string | Human-readable message |
| data.address | string | The address that was added/updated |
| data.callback_url | string | null | The registered callback URL (null if none) |
| data.timestamp | string | ISO timestamp of the operation |
Error Responses
All errors use code = -1 and describe the problem in msg:
| msg | Cause |
|---|---|
API key required in X-API-KEY header or request body | No API key provided |
Invalid API key or IP not in whitelist | Authentication failed |
Invalid TRC-20 address format | Address does not match the required format |
Invalid callback URL. Only public HTTP/HTTPS URLs are allowed | Callback URL rejected by validation |
Address belongs to another user | The address is registered under a different account |
Database error adding/updating address | Temporary server-side error — retry |
Internal server error | Unexpected error — retry or contact support |
{ "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:
| HTTP | Body | Cause |
|---|---|---|
| 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.0000A 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| Parameter | Description |
|---|---|
| address | The TRON address that received the energy delegation |
| order_id | Delegation identifier (T + internal delegation id) — unique per delegation |
| hash | On-chain transaction hash of the energy delegation |
| balance_after | Your account balance in TRX right after this charge (snapshot at charge time; it may have changed by the moment the callback arrives) |
| idle_cycle | 1 — this delegation was issued after 24 hours with no transfer (idle re-delegation), 0 — a regular cycle born from your transfer or activation |
| energy_used | Tariff 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 |
| charged | Amount 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)
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"}), 200Delivery 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/statusand make your handler idempotent.
Updating / removing the callback
- Update: call
/apiv2/time/addagain with the same address and a newcallback_url. - Remove: call
/apiv2/time/deleteto remove the address (this also removes its callback); re-add withoutcallback_urlif needed.
Related Endpoints
- POST /apiv2/time/order — buy cycles (activates the address)
- POST /apiv2/time/infinitystart — enable infinity mode
- POST /apiv2/time/status — check status and cycles
- POST /apiv2/time/stop — stop Host Mode
- POST /apiv2/time/delete — remove the address
Notes
- New addresses start inactive; activate them with an order, with infinity start, or by passing
"infinity": truehere. - The same address cannot be registered under two different accounts.
- The address should be activated on the TRON network before adding it.