Autenticazione
Tutte le richieste API all'API TRXUp richiedono l'autenticazione utilizzando un token Bearer e una firma. Questo garantisce la sicurezza e l'integrità delle tue richieste API.
Ottenere le Credenziali API
Per iniziare con l'API TRXUp, dovrai ottenere le tue credenziali API dal dashboard:
- Accedi all'area clienti TRXUp
- Apri Accesso API, sotto Account nella barra laterale
- Premi Crea credenziali
Il token e il segreto di firma vengono mostrati una sola volta, nel momento in cui sono creati. Il segreto non viene mai più visualizzato — né in parte, né su quella schermata. Se lo perdi, emetti una nuova coppia.

La stessa schermata permette di limitare la coppia agli indirizzi IP da cui chiamano i tuoi server. Una richiesta firmata correttamente ma proveniente da altrove viene rifiutata.
TIP
Mantieni le tue credenziali API sicure e non condividerle mai pubblicamente. Il tuo segreto API dovrebbe essere trattato come una password.
Header Richiesti
| Header | Descrizione |
|---|---|
Authorization: Bearer YOUR_API_TOKEN | Il tuo token API |
X-Signature: YOUR_SIGNATURE | Firma della richiesta |
Content-Type: application/json | Il tipo di contenuto deve essere JSON |
Calcolo della Firma
La firma viene calcolata utilizzando l'hash SHA256 del corpo della richiesta concatenato con il tuo segreto API.
signature=$(echo -n "$requestBody$apiSecret" | sha256sum | cut -d' ' -f1)Esempio in Diversi Linguaggi
#!/bin/bash
API_TOKEN="your_api_token"
API_SECRET="your_api_secret"
REQUEST_BODY='{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}'
# Calcola la firma
SIGNATURE=$(echo -n "${REQUEST_BODY}${API_SECRET}" | sha256sum | cut -d' ' -f1)
# Effettua la richiesta API
curl -X POST "https://api.trxup.com/v1/transaction/new" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "X-Signature: ${SIGNATURE}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}"const crypto = require('crypto');
const axios = require('axios');
const apiToken = 'your_api_token';
const apiSecret = 'your_api_secret';
const requestBody = JSON.stringify({
service: 'energy',
params: {
address: 'TRX_ADDRESS',
energy_amount: 65000,
duration: 1
}
});
// Calcola la firma
const signature = crypto
.createHash('sha256')
.update(requestBody + apiSecret)
.digest('hex');
// Effettua la richiesta API
axios({
method: 'post',
url: 'https://api.trxup.com/v1/transaction/new',
headers: {
'Authorization': `Bearer ${apiToken}`,
'X-Signature': signature,
'Content-Type': 'application/json'
},
data: requestBody
})
.then(response => console.log(response.data))
.catch(error => console.error(error));<?php
$apiToken = 'your_api_token';
$apiSecret = 'your_api_secret';
$requestBody = json_encode([
'service' => 'energy',
'params' => [
'address' => 'TRX_ADDRESS',
'energy_amount' => 65000,
'duration' => 1
]
]);
// Calcola la firma
$signature = hash('sha256', $requestBody . $apiSecret);
// Effettua la richiesta API
$ch = curl_init('https://api.trxup.com/v1/transaction/new');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiToken,
'X-Signature: ' . $signature,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>import hashlib
import json
import requests
api_token = 'your_api_token'
api_secret = 'your_api_secret'
request_body = json.dumps({
'service': 'energy',
'params': {
'address': 'TRX_ADDRESS',
'energy_amount': 65000,
'duration': 1
}
})
# Calcola la firma
signature = hashlib.sha256((request_body + api_secret).encode()).hexdigest()
# Effettua la richiesta API
headers = {
'Authorization': f'Bearer {api_token}',
'X-Signature': signature,
'Content-Type': 'application/json'
}
response = requests.post(
'https://api.trxup.com/v1/transaction/new',
headers=headers,
data=request_body
)
print(response.json())Firma versione 2 (opzionale)
La versione 2 della firma è un modo opzionale e più robusto di firmare le stesse richieste. La attivi per singola richiesta inviando l'header X-Signature-Version: 2. Una richiesta senza questo header, o con X-Signature-Version: 1, viene verificata esattamente come descritto sopra, quindi le integrazioni esistenti non richiedono alcuna modifica. La versione 1 continua a funzionare e non c'è alcuna scadenza per il passaggio; per le nuove integrazioni consigliamo la versione 2.
Cosa aggiunge la versione 2:
- La firma è legata all'endpoint. Il metodo e il percorso fanno parte di ciò che viene firmato, quindi una richiesta firmata per
/v1/subscription/checknon può essere riprodotta verso/v1/subscription/stop. - Scade dopo 5 minuti. Il timestamp firmato deve discostarsi di non più di 300 secondi dall'orologio del server.
- Ogni richiesta firmata viene accettata una sola volta. Il nonce firmato non può essere riutilizzato, quindi una richiesta intercettata non può essere riprodotta.
Header Richiesti (versione 2)
| Header | Descrizione |
|---|---|
Authorization: Bearer YOUR_API_TOKEN | Il tuo token API, come nella versione 1 |
X-Signature-Version: 2 | Seleziona la versione 2 della firma per questa richiesta |
X-Timestamp: 1761040800 | Ora Unix corrente in secondi, come intero decimale |
X-Nonce: 7f3c9a12b4e8d05c | Un valore univoco per ogni richiesta: da 8 a 128 caratteri tra A–Z a–z 0–9 . _ ~ - (va bene un UUID o almeno 16 caratteri esadecimali casuali). Non riutilizzare mai un nonce |
X-Signature: YOUR_SIGNATURE | Firma della richiesta, calcolata come indicato sotto |
Content-Type: application/json | Il tipo di contenuto deve essere JSON |
Calcolo della Firma (versione 2)
X-Signature è l'HMAC-SHA256, in esadecimale minuscolo, della stringa seguente, con il tuo segreto API come chiave:
METHOD + "\n" + PATH + "\n" + X-Timestamp + "\n" + X-Nonce + "\n" + BODYMETHODèPOST(tutti gli endpoint/v1usano POST).PATHè il percorso della richiesta esattamente come inviato, senza host e senza query string, ad es./v1/transaction/new.X-TimestampeX-Noncesono esattamente i valori degli header che invii.BODYsono i byte grezzi esatti del corpo della richiesta (una stringa vuota se il corpo è vuoto). Firma i byte che invii: se il JSON viene serializzato di nuovo dopo la firma, la firma non corrisponderà."\n"è un singolo carattere di nuova riga (0x0A). Dopo il corpo non c'è alcuna nuova riga.
Il server verifica prima la firma, poi che X-Timestamp non si discosti di più di 300 secondi (5 minuti) dal proprio orologio in nessuna delle due direzioni e infine che il tuo account non abbia già usato quel nonce (i nonce vengono ricordati per circa 11 minuti). Mantieni l'orologio del tuo server sincronizzato con NTP. Un nuovo tentativo è una nuova richiesta: servono un nuovo timestamp, un nuovo nonce e una nuova firma.
Vettore di Test
Verifica il tuo codice con questi valori prima di chiamare l'API:
| Input | Valore |
|---|---|
| Segreto API | your_api_secret |
| Metodo | POST |
| Percorso | /v1/transaction/new |
X-Timestamp | 1761040800 |
X-Nonce | 7f3c9a12b4e8d05c |
| Corpo | {"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}} |
La stringa da firmare (cinque righe, nessuna nuova riga dopo l'ultima):
POST
/v1/transaction/new
1761040800
7f3c9a12b4e8d05c
{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}X-Signature attesa:
56576e1faecaca2b2533bee6124e7ece2b023665addb2f2e79b8ac83bf8104e8Errori (versione 2)
Una verifica non riuscita restituisce la stessa risposta HTTP 401 della versione 1, con "code": 1. Una firma, un timestamp o un nonce errati o mancanti, oppure un X-Signature-Version diverso da 1 o 2, ricevono il consueto Incorrect token or signature. Solo dopo una firma valida possono comparire due messaggi più specifici:
X-Timestamp is N seconds from this server's clock; at most 300 either way is accepted— il tuo orologio non è corretto: sincronizzalo con NTP.This X-Nonce was already used; every request needs a new one— genera un nuovo nonce per ogni richiesta, compresi i nuovi tentativi.
Esempi della Versione 2 in Diversi Linguaggi
#!/bin/bash
API_TOKEN="your_api_token"
API_SECRET="your_api_secret"
REQUEST_PATH="/v1/transaction/new"
REQUEST_BODY='{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}'
# A new timestamp and nonce for every request
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)
# Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY, no trailing newline
SIGNATURE=$(printf '%s\n%s\n%s\n%s\n%s' "POST" "$REQUEST_PATH" "$TIMESTAMP" "$NONCE" "$REQUEST_BODY" \
| openssl dgst -sha256 -hmac "$API_SECRET" | awk '{print $NF}')
# Make API request
curl -X POST "https://api.trxup.com${REQUEST_PATH}" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "X-Signature-Version: 2" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}"const crypto = require('crypto');
const axios = require('axios');
const apiToken = 'your_api_token';
const apiSecret = 'your_api_secret';
const requestPath = '/v1/transaction/new';
const requestBody = JSON.stringify({
service: 'energy',
params: {
address: 'TRX_ADDRESS',
energy_amount: 65000,
duration: 1
}
});
// A new timestamp and nonce for every request
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID();
// Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
const payload = ['POST', requestPath, timestamp, nonce, requestBody].join('\n');
const signature = crypto
.createHmac('sha256', apiSecret)
.update(payload)
.digest('hex');
// Make API request (send exactly the body that was signed)
axios({
method: 'post',
url: 'https://api.trxup.com' + requestPath,
headers: {
'Authorization': `Bearer ${apiToken}`,
'X-Signature-Version': '2',
'X-Timestamp': timestamp,
'X-Nonce': nonce,
'X-Signature': signature,
'Content-Type': 'application/json'
},
data: requestBody
})
.then(response => console.log(response.data))
.catch(error => console.error(error));<?php
$apiToken = 'your_api_token';
$apiSecret = 'your_api_secret';
$requestPath = '/v1/transaction/new';
$requestBody = json_encode([
'service' => 'energy',
'params' => [
'address' => 'TRX_ADDRESS',
'energy_amount' => 65000,
'duration' => 1
]
]);
// A new timestamp and nonce for every request
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
// Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
$payload = implode("\n", ['POST', $requestPath, $timestamp, $nonce, $requestBody]);
$signature = hash_hmac('sha256', $payload, $apiSecret);
// Make API request (send exactly the body that was signed)
$ch = curl_init('https://api.trxup.com' . $requestPath);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiToken,
'X-Signature-Version: 2',
'X-Timestamp: ' . $timestamp,
'X-Nonce: ' . $nonce,
'X-Signature: ' . $signature,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>import hashlib
import hmac
import json
import time
import uuid
import requests
api_token = 'your_api_token'
api_secret = 'your_api_secret'
request_path = '/v1/transaction/new'
# Compact separators: the same bytes as the test vector and the other examples
request_body = json.dumps({
'service': 'energy',
'params': {
'address': 'TRX_ADDRESS',
'energy_amount': 65000,
'duration': 1
}
}, separators=(',', ':'))
# A new timestamp and nonce for every request
timestamp = str(int(time.time()))
nonce = uuid.uuid4().hex
# Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
payload = '\n'.join(['POST', request_path, timestamp, nonce, request_body])
signature = hmac.new(api_secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
# Make API request (send exactly the bytes that were signed)
headers = {
'Authorization': f'Bearer {api_token}',
'X-Signature-Version': '2',
'X-Timestamp': timestamp,
'X-Nonce': nonce,
'X-Signature': signature,
'Content-Type': 'application/json'
}
response = requests.post(
'https://api.trxup.com' + request_path,
headers=headers,
data=request_body.encode()
)
print(response.json())