Trade Mining

Telemetry Report API

The exact trade telemetry payload, node authentication headers, HMAC signature and the complete mining REST API surface of the central hub and local nodes.

⏱️ 10 min read📊 Level: Advanced

The Telemetry API is how a DepthSight node tells the hub about a finished trade. It is write-only and anonymous: there is no public registry of identities, only the machine-level binding between a node_uuid and its secret, verified with an HMAC signature over the exact request body.

The hub API lives in api/hub_router.py under the /api/v1/hub prefix. Node-local mining endpoints live in api/routes/config.py (prefix /api/v1, JWT-authenticated). All timestamps are UTC.


1. Authentication

Node-facing hub requests use the same credential headers, derived from the node's identity (X-Node-UUID / X-Node-Secret / X-Node-Signature / X-Timestamp). Admin endpoints use Authorization: Bearer with HUB_ADMIN_API_KEY or an admin JWT instead, and the promo admin endpoints are additionally restricted to a central-hub deployment (IS_CENTRAL_HUB=true).

HeaderValue
X-Node-UUIDThe node's node_uuid.
X-Node-SecretThe raw telemetry secret (TLS only; the hub stores only its SHA-256).
X-Node-SignatureHex HMAC-SHA256 of the exact body bytes, keyed by the raw secret (required on /telemetry/report and /memory/community/contribute).
X-TimestampEpoch milliseconds; optional but recommended. Outside a ±300 s window the hub answers 400 Stale request timestamp (possible replay). Absent ⇒ legacy behaviour (accepted).

Allowed values are validated against HubNode.secret_hash and the node is checked for the is_banned flag. Endpoints that only read (mining status, referrals, node list) accept the two credential headers without a body signature; the /telemetry/report path requires the signature.

Signing a preamble (schemas)

Sources:

The signature is computed over json.dumps(payload, sort_keys=True) — the exact bytes the hub will hash. telemetry_sync.py signs the same way for offline re-uploads.


2. Telemetry Report Payload

POST /api/v1/hub/telemetry/report accepts a single JSON object (camelCase):

FieldTypeRequiredDescription
symbolstring✓Trading pair, e.g. BTCUSDT
directionstring✓LONG / SHORT
entryPricefloat✓Average entry price
exitPricefloat✓Average exit price
pnlPercentfloat–Net PnL % of the trade
tradeDurationSecfloat–Hold time in seconds (eligibility gate, default ≥ 30)
exitReasonstring–e.g. TP, SL, EXIT
tradeModestring✓Must be LIVE to be eligible
strategyBlocksarray–[{type, params}] used for swarm insights
marketContextobject–{session?, natr?, adx?, volume_ratio?}
exchangeIdstring–e.g. weex, bybit — must be in eligibleExchanges
marketTypestring–spot / futures
brokerTradeIdstring–Unique broker trade id (dedup key)
entryBrokerTradeIdsstring[]–All entry client order ids
closeBrokerTradeIdsstring[]–All close (TP/SL/exit) client order ids
tradeVolumeUsdtfloat–Notional open+close volume (rebate basis)
timeframestring–Strategy timeframe (e.g. 15m)
maxFloatingProfitfloat–Max favourable excursion in USD (MFE)
maxFloatingLossfloat–Max adverse excursion in USD (MAE)
attributionNodeUuidstring–Target miner node (defaults to the authenticated node)
sourceNodeUuidstring–The mining server hosting the miner (commission target)

Response — 201 Created {"status": "success", "message": "Telemetry report submitted successfully."}. Errors: 400 malformed or stale X-Timestamp, 401 no credentials, 403 bad signature / attribution / source / banned node, 404 node unregistered, 409 brokerTradeId already claimed by another node or already verified / epoch-attributed (the row is frozen against overwrite).

Both attributionNodeUuid and sourceNodeUuid are client-supplied but server-validated: attribution to a different user's node is forbidden, and — unless sourceNodeUuid equals the attribution node (self-sourcing is exempt) — the source must be flagged is_mining_server (_verify_attribution, _verify_source_server).


3. Hub Endpoints

MethodPathAuth / accessPurpose
POST/api/v1/hub/nodes/registerNode secret (+ wallet signature for wallet nodes)Register/update a node, bind wallet/referrer
POST/api/v1/hub/nodes/pingNode secretHeartbeat + server reward share
POST/api/v1/hub/nodes/revoke-telemetryWallet signatureRevoke a node's telemetry credential
GET/api/v1/hub/nodesPublicActive network map — non-banned, non-wallet-bound nodes with a ping in the last 5 min
GET/api/v1/hub/mining/configPublicActive mining config (incl. quality gates + exchange multipliers)
POST/api/v1/hub/mining/configAdminUpdate mining config
GET/api/v1/hub/mining/statusNode credentialsNode's live mining status & estimate
GET/api/v1/hub/mining/referralsUser / nodeReferral tree of the account
GET/api/v1/hub/mining/node-tradesNode credentialsPaginated telemetry trades for the node + its referrals
GET/api/v1/hub/mining/analyticsAdminNetwork KPIs, verification funnel, exchange/node breakdown, daily & epoch trends
GET/api/v1/hub/mining/analytics/tradesAdminPaginated trades with date/exchange/status/node/search filters
POST/api/v1/hub/telemetry/reportNode signSubmit a finished-trade telemetry report
GET/api/v1/hub/telemetry/insightsPublicSwarm intelligence aggregates
POST/api/v1/hub/mining/process-epochAdminManually process an epoch (optional past epochDate)
POST/api/v1/hub/nodes/designate-operatorAdminMark a node as the fee-root operator
GET/api/v1/hub/promo/statusUser / nodeActive campaign + per-quest progress
POST/api/v1/hub/promo/claimUser / nodeClaim a completed promo quest reward
GET, POST/api/v1/hub/promo/admin/campaignsAdmin (hub only)Create/update promo campaigns
POST/api/v1/hub/promo/admin/relink-nodeAdmin (hub only)Audit-logged referrer override for a node

GET /api/v1/hub/mining/status

Returns (MiningStatusResponse):

{
  isMiningEnabled, eligibleExchanges, rebateRates, exchangeMultipliers,
  currentEpochDate, dailyEmission,          // halving-adjusted
  yourTotalMined, yourEpochReward,          // live estimate
  epochTotalRebates, participatingNodes,
  nodeReferralCode, referrerNodeUuid, referrerReferralCode, hasWelcomeBonus,
  totalOperatorFeeCollected,
  yourTotalVolume, serverTotalVolume, yourVolumeShare,
  yourDailyVolume, serverDailyVolume, yourEpochRebates, yourCumulativeRebates,
  totalDistributed, serverTotalMined,
  dailyHistory[14],                         // date/reward/rebates/tradesCount
  epochNumber, launchDate
}

yourEpochReward is a live intraday estimate of MiningLedger for the current day and mirrors the exact epoch math (estimate_live_epoch_reward).

GET /api/v1/hub/mining/node-trades

Paginated view of a node's own telemetry plus that of directly referred nodes, filtered to LIVE trades only (paper/sandbox rows are hidden), with statusFilter (PENDING/VERIFIED/SKIPPED/REJECTED/ALL), exchange, search (symbol / broker trade id) and scope (my/referrals/all, default all) filters. Each item carries tradeVolumeUsdt, brokerTradeId, entryBrokerTradeIds, closeBrokerTradeIds, verificationStatus, verificationError, verifiedVolumeUsdt, isMiningEligible, score, rewardTokens, username, isOwnTrade, createdAt.

GET /api/v1/hub/telemetry/insights

Swarm-intelligence insights aggregated over the last days (default 30, clamped to 1–90, newest 20 000 reports; optional symbol): groups reports by the sorted strategy-block type list, requires at least 5 trades per combo, and returns comboKey, winRate, totalTrades, avgPnlPercent and the top 3 bestExitReasons, sorted by win rate.

POST /api/v1/hub/mining/process-epoch

Optional body { "epochDate": "YYYY-MM-DD" }; today's or future dates are rejected with 400, default is today − MINING_EPOCH_LAG_DAYS (1).


4. Local Node Mining API

These endpoints run on every DepthSight instance (JWT auth, config_router, prefix /api/v1). Non-hub nodes proxy hub data transparently when possible.

MethodPathDescription
GET/api/v1/config/mining/statusLocal node mining status (LocalMiningStatusResponse)
POST/api/v1/config/mining/activateEnable mining for the user, link referral, register the node
POST/api/v1/config/mining/deactivateStop mining + telemetry for the user
GET / PUT/api/v1/config/mining/node-configNode-wide mining config (admin)
GET/api/v1/config/mining/tradesPaginated local telemetry trades list (proxies /hub/mining/node-trades on non-hub; on the hub it queries locally and hides paper/sandbox rows)
GET/api/v1/config/mining/referralsMining referrals list (proxies /hub/mining/referrals on non-hub)
POST/api/v1/config/mining/admin/import-bybit-xlsxImport a Bybit broker-cabinet .xlsx/.csv export as VERIFIED (hub + admin; optional dryRun)
POST/api/v1/config/mining/admin/import-weex-xlsxImport a Weex broker-cabinet .xlsx/.csv export as VERIFIED (hub + admin; optional dryRun)
POST/api/v1/config/node/wallet/nonceCreate a SIWE ownership message for a wallet address
POST/api/v1/config/node/wallet/verifyVerify wallet signature, bind deterministic node_uuid
GET/api/v1/config/node/wallet/statusCurrent wallet / node binding
POST/api/v1/config/node/wallet/disconnectUnbind the wallet (keeps node history)

POST /api/v1/config/mining/activate

Body: { "referrerCode": "..." }. Requires a bound wallet (WALLET_REQUIRED otherwise). Activates is_mining_enabled = true, turns on shareTelemetry, registers the deterministic wallet node with the hub and returns the same LocalMiningStatusResponse as the status endpoint.

Mining status payload (LocalMiningStatusResponse)

{
  isMiningEnabled, nodeUuid, nodeName, registeredOnHub,
  nodeReferralCode, referrerNodeUuid, referrerReferralCode,
  hasWelcomeBonus, totalMined, totalDistributed, config, stats,
  isGlobalMiningEnabled, userRewardSharePercent,
  userTradeVolume, userDailyVolume, userEstimatedRebate, userCumulativeRebate,
  dailyHistory[], epochNumber, launchDate
}

5. Idempotency & Offline Sync

  • brokerTradeId is the dedup key. Re-submitting a row that already belongs to another node, or one that is already verified / epoch-attributed, is a 409 the client treats as success (the local row is marked SENT). Re-submitting your own LOCAL_ONLY/PENDING row simply updates it and returns 201 (fresh score/gate applied; the status is only upgraded from LOCAL_ONLY).
  • Reports saved locally while offline get verification_status = LOCAL_ONLY, then telemetry_sync.resync_pending_telemetry_reports() (or the Celery sync_pending_telemetry_task) uploads them in FIFO batches of 50, each report signed with the identity of the node it is attributed to (legacy file/env identity as fallback) so a wallet re-key can no longer loop on 403; a single report's failure never breaks the batch. Resync is skipped automatically when IS_CENTRAL_HUB=true; a local node without identity is skipped gracefully.
  • The X-Node-Signature must be recomputed for every re-upload because it binds the exact request bytes, and the hub enforces the current hash of the secret.