Documentazione API
Tutte le richieste sono GET e vogliono una chiave nel header Authorization. Le risposte sono JSON UTF-8. La versione fa parte dell'indirizzo: dentro v1 non togliamo né rinominiamo campi, possiamo solo aggiungerne.
Tre comandi e hai il primo evento in mano. La chiave si crea nell'area account.
# 1. la chiave funziona? e da dove ripartire?
curl -H "Authorization: Bearer $KEY" https://trumptruthpulse.it/api/v1/stato
# 2. il primo blocco di eventi (dall'inizio dello storico)
curl -H "Authorization: Bearer $KEY" "https://trumptruthpulse.it/api/v1/eventi?dopo=0&limite=50"
# 3. da qui in avanti: rimanda il cursore che hai ricevuto
curl -H "Authorization: Bearer $KEY" "https://trumptruthpulse.it/api/v1/eventi?dopo=<prossimo_cursore>"Per partire da ADESSO invece che dallo storico, leggi cursore_attuale da /stato e usalo come primo "dopo". In produzione conviene comunque il webhook: ti chiamiamo noi, e il polling resta la rete di sicurezza.
La chiave si crea nell'area account e si vede una volta sola. Se la perdi, revocala e creane un'altra: non possiamo rimostrartela perché conserviamo solo la sua impronta.
curl -H "Authorization: Bearer ttp_live_..." \
https://trumptruthpulse.it/api/v1/statoDue errori diversi che è importante non confondere: 401 significa chiave assente, sbagliata o revocata; 402 significa che la chiave è valida ma l'abbonamento non è attivo. Il primo si risolve nel codice, il secondo in amministrazione.
{"errore":{"codice":"abbonamento_non_attivo","messaggio":"...","message":"..."}}GET /api/v1/eventi?dopo=<cursore>&limite=<1..500>
GET /api/v1/eventi/<evento_id>
GET /api/v1/post/<id>
GET /api/v1/statoGli eventi arrivano in ordine cronologico crescente. Conserva "prossimo_cursore" e rimandalo in "dopo": ripeti finché "altri" è false. Il cursore è monotono, quindi anche restando fermo per ore non perdi nulla.
curl -H "Authorization: Bearer $KEY" \
"https://trumptruthpulse.it/api/v1/eventi?dopo=0&limite=100"
{
"eventi": [ ... ],
"prossimo_cursore": "1842",
"altri": false,
"sorgente_ok": true,
"ultimo_controllo": "2026-07-23T12:37:02+00:00"
}Per partire da adesso senza scaricare lo storico, leggi "cursore_attuale" da /api/v1/stato e usalo come primo "dopo". Lo stesso endpoint dice se il rilevatore sta girando: sorgente_ok false significa che la sorgente è momentaneamente giù e quindi non stanno arrivando eventi nuovi.
| tipo | quando | cosa contiene |
|---|---|---|
| post.rilevato | appena vediamo il post | misure: assente · segnale: null |
| misure.ampiezza | a reazione fissata | misure: 17 · segnale: presente (azione e mercati) |
| misure.chiuse | a misure concluse | misure: 17 · segnale: presente · esito: se c'è un'operazione |
Tre eventi per ogni post RILEVANTE, non uno per mercato: post.rilevato appena il post viene visto, misure.ampiezza quando la prima reazione è fissata sui 17 mercati, misure.chiuse quando le misure sono concluse. I post che il filtro scarta non producono nessun evento: li vediamo e li misuriamo per contesto, ma non te li mandiamo. Su post.rilevato il campo misure è null: non c'è ancora niente da leggere.
{
"evento_id": "evt_1842_ampiezza",
"tipo": "misure.ampiezza",
"creato": "2026-07-23T12:32:10+00:00",
"post": {
"id": 1842,
"sorgente_id": "3ktz...",
"autore": "trump",
"url": "https://...",
"pubblicato": "2026-07-23T12:29:00+00:00",
"rilevato": "2026-07-23T12:32:08+00:00",
"testo_en": "...",
"testo_it": "...",
"rilevante": true
},
"misure": [
{ "asset": "XAG", "etichetta": "Argento", "prezzo_t0": 58.91,
"ampiezza_pct": 0.42, "variazione_pct": -0.42, "insolito": 3.4,
"rientro_min": 18, "stato": "completa", "nota": null }
],
"segnale": {
"azione": "vendi", "verso": "giu",
"misurati": 17, "concordi": 11, "insolito_medio": 3.2,
"concordi_asset": ["BTC", "XAG", "WTI", "QQQ", "SPY"],
"contro_asset": ["XAU"],
"avvertenza": "..."
},
"concorrenza": { "quanti": 1, "voci": { "fed": 1 } },
"esito": null
}Le date. Sono tutte ISO-8601 in UTC (+00:00). pubblicato è l'ora che dichiara la fonte da cui prendiamo il post: quando lo stesso post ci arriva da tutte e due le fonti teniamo la più vecchia delle due, se sono lontane almeno mezzo minuto; quando ne arriva una sola vale la sua, e può essere di qualche minuto più tardi. rilevato è quando l'abbiamo visto noi, e la differenza fra i due non è la nostra latenza.
Due campi che vale la pena guardare. concorrenza conta gli ALTRI POST usciti nella finestra della misura (da un minuto prima del post a cinque minuti dopo): `quanti` è il totale, `voci` li raggruppa per autore. Se è più di zero il movimento è conteso e la causa non è solo quel post - lo diciamo noi per primi, perché senza ti venderemmo una causa che non abbiamo dimostrato. Conta anche altri post dello stesso autore e i post che il filtro ha scartato: è un contesto, non un giudizio. esito compare solo su misure.chiuse e porta l'operazione conclusa: rendimento teorico medio, lo stesso nel verso opposto, il minuto in cui è uscito l'ultimo mercato e la riga per mercato. È null sugli altri due eventi e su ogni post uscito neutro, perché non è stata aperta nessuna operazione.
// dentro misure.chiuse
"esito": {
"azione": "compra", "chiusa": true,
"rendimento": -0.089, "rendimento_contrario": 0.089,
"minuto_uscita": 6,
"mercati": [ { "asset": "DIA", "nome": "Dow Jones",
"nome_en": "Dow Jones", "rendimento": 0.062 } ],
"avvertenza": "...", "avvertenza_en": "..."
}ampiezza_pct è la massima escursione percentuale nei 5 minuti dopo il post. rientro_min è il primo minuto in cui il prezzo riassorbe più della metà di quella escursione: null se non è ancora successo o se non è successo entro due ore (stato "timeout"). I 17 mercati: BTC, EUR/USD, Oro, Argento, S&P 500, Nasdaq, Dow Jones, Petrolio, Gas, Rame, Yuan, Peso, Treasury, Volatilità, Borsa italiana, Germania, Euro Stoxx. Oro, argento e petrolio sono lo strumento vero; le tre borse americane sono misurate tramite ETF, perché gli indici ufficiali richiedono una licenza: lo diciamo perché il numero sia interpretabile, non è un dettaglio nascosto.
Il blocco segnale (assente su post.rilevato, presente sugli eventi di misura) riassume i mercati, campo per campo.
azione - "vendi", "compra" o "neutro".
concordi_asset - l'oggetto dell'azione, dal più mosso al meno mosso. Quando c'è un'azione contiene SOLO i mercati che superano da soli la soglia di movimento, cioè quelli su cui l'operazione ha senso.
concordi_tutti - tutti quelli che vanno nel verso prevalente, anche i quasi fermi.
sopra_soglia - gli stessi mercati dell'azione, con la loro ampiezza.
contro_asset - quelli che vanno nella direzione opposta.
Attenzione ai mercati INVERSI per costruzione: yuan, peso messicano, titoli di Stato e volatilità salgono quando le borse scendono. Contano nella concordanza col segno girato, quindi un loro rialzo conferma un "vendi", ma non entrano mai in concordi_asset, perché l'oggetto dell'azione deve poter essere eseguito così com'è scritto.
È un calcolo automatico sui dati di mercato, non una raccomandazione di investimento: l'avvertenza viaggia dentro il payload.
Registri un indirizzo https nell'area account e ti mandiamo ogni evento con una POST, prima che parta la notifica sui canali umani. Devi rispondere 2xx entro 3 secondi. Se non rispondi ritentiamo dopo 1 minuto, 5, 15, un'ora e 6 ore: nel frattempo gli eventi restano leggibili via polling, quindi non si perde nulla.
POST /il-tuo-endpoint
Content-Type: application/json
X-TTP-Evento: evt_1842_rilevato
X-TTP-Tentativo: 1
X-TTP-Signature: t=1753280000,v1=<hmac_sha256("{t}.{corpo}", secret)>Verifica sempre la firma prima di fidarti del contenuto, e rifiuta i messaggi con t più vecchio di 5 minuti. Il confronto va fatto in tempo costante.
# Python
import hmac, hashlib, time
t, v1 = dict(p.split('=', 1) for p in firma.split(',')).values()
atteso = hmac.new(secret.encode(), f"{t}.{corpo}".encode(), hashlib.sha256).hexdigest()
assert hmac.compare_digest(atteso, v1) and abs(time.time() - int(t)) <= 300Lo stesso evento può arrivare più di una volta (un ritentativo dopo una tua risposta persa, per esempio). evento_id è stabile: usalo per scartare i doppioni. Non seguiamo redirect: l'indirizzo che registri è quello che chiamiamo.
Ogni risposta autenticata porta X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset (sulle risposte 401 e 402 non ci sono: la chiave non e' ancora nota). Superato il limite rispondiamo 429 con Retry-After: aspetta quel tempo invece di insistere. I limiti sono per chiave, quindi piu' chiavi moltiplicano il tetto.
A pagamento 600 req/min per chiave nessuna quota mensile tempo reale, 3 webhook storico completoUn evento nasce quando il nostro rilevatore vede il post, e viene spedito subito dopo. Quanto tempo passa fra la pubblicazione e l'evento lo decide la sorgente, non noi: ne sorvegliamo più di una in parallelo e vince quella che arriva prima. Nella nostra sequenza il webhook parte PRIMA dei canali umani: l'evento esce, poi si traduce il post e solo dopo partono Telegram e ntfy. Il vantaggio è di qualche secondo, e non è garantito: non è su quello che si compra l'API, ma sul fatto che l'evento arrivi a un programma invece che a una persona. Non c'è nessuno SLA sulla latenza e non promettiamo continuità della sorgente: se cade, sorgente_ok diventa false e gli eventi già rilevati restano leggibili. I piani a uso interno non comprendono il diritto di ridistribuire gli eventi ai tuoi utenti finali: per quello serve un accordo dedicato.