Rewards & History
My Subscription Records
Query all subscription records for the authenticated user.
Authentication Required
Authorization: Bearer <JWT_TOKEN>
GET /earn/subscriptions
Response
Returns an array of UserSubscriptionDetail objects. Returns empty array [] if the user has no subscriptions.
[
{
"id": "a1b2c3d4-...",
"product_id": "123204f6-...",
"product_name": "USDT Earn 900% APY",
"chain_product_id": 1769524310,
"amount": "100000000",
"nft_amount": "100000000",
"expected_return": "855",
"actual_return": "855",
"total_return": "100000855",
"nft_status": "matured",
"claimed": false,
"product_status": "settled",
"annual_rate": "900.00%",
"period_rate": "0.00%",
"subscribed_at": "2026-01-27T14:35:00Z",
"settle_time": "2026-01-27T14:43:00Z",
"settled_at": "2026-01-27T14:43:12Z",
"claimed_at": null,
"subscribe_tx_hash": "0xabc...",
"claim_tx_hash": null
}
]
Subscription Fields (UserSubscriptionDetail)
| Field | Type | Description |
|---|---|---|
id | string | Subscription record UUID |
product_id | string | Product UUID |
product_name | string | Product name |
chain_product_id | number | On-chain product ID |
amount | string | Subscription amount (Wei) |
nft_amount | string | NFT holding amount |
expected_return | string | Expected interest (Wei) |
actual_return | string | null | Actual interest (available after settlement) |
total_return | string | Total claimable amount: principal + interest (Wei) |
nft_status | string | NFT status: created / active / matured / redeemed |
claimed | boolean | Whether claimed |
product_status | string | Parent product status |
annual_rate | string | Annual rate at subscription time |
period_rate | string | Period rate |
subscribed_at | string | Subscription time (ISO 8601) |
settle_time | string | Expected settlement time (ISO 8601) |
settled_at | string | null | Actual settlement time |
claimed_at | string | null | Claim time |
subscribe_tx_hash | string | null | On-chain subscription tx hash |
claim_tx_hash | string | null | On-chain claim tx hash |
Interpreting Subscription Status
Use the combination of nft_status, claimed, and product_status to determine actionable state:
nft_status | claimed | product_status | User Action |
|---|---|---|---|
active | false | active | Waiting — funds locked |
matured | false | settled | Can claim — call claim(productId) |
redeemed | true | settled / ended | Completed — already claimed |
active | false | cancelled | Can emergency refund — call emergencyClaim(productId) |
Historical Performance
Get historical performance data for ended products. Useful for displaying platform track record.
GET /earn/performance
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Number of results, default 10 |
Response
Returns an array of HistoricalPerformance objects, sorted from most recent to oldest. Returns empty array [] if no historical data exists.
[
{
"product_name": "USDT Earn 50% APY",
"duration_seconds": 2592000,
"annual_rate": "50.00%",
"period_rate": "4.11%",
"total_subscribed": "10000000000",
"total_interest_paid": "411000000",
"subscriber_count": 256,
"settled_at": "2026-01-15T00:00:00Z"
}
]
Performance Fields (HistoricalPerformance)
| Field | Type | Description |
|---|---|---|
product_name | string | Product name |
duration_seconds | number | Lock duration in seconds |
annual_rate | string | Annual yield rate |
period_rate | string | Actual period yield rate |
total_subscribed | string | Total subscribed amount (Wei) |
total_interest_paid | string | Total interest distributed (Wei) |
subscriber_count | number | Number of participants |
settled_at | string | Settlement time (ISO 8601) |
tip
Performance data is cached server-side for 60 seconds. Repeated requests within this window return cached results.
Display Conversion
Code Examples
Python — My Subscriptions (JWT Required)
import requests
BASE_URL = "https://api.ztdx.io"
JWT_TOKEN = "your_jwt_token"
resp = requests.get(
f"{BASE_URL}/earn/subscriptions",
headers={"Authorization": f"Bearer {JWT_TOKEN}"},
)
for sub in resp.json():
status = f"{sub['nft_status']}, claimed={sub['claimed']}"
amount_usdt = int(sub['amount']) / 1e6
print(f" {sub['product_name']} — {amount_usdt:.2f} USDT, status={status}")
if sub['nft_status'] == 'matured' and not sub['claimed']:
print(f" ↳ Ready to claim! call earnContract.claim({sub['chain_product_id']})")
Python — Historical Performance (Public)
import requests
BASE_URL = "https://api.ztdx.io"
resp = requests.get(f"{BASE_URL}/earn/performance", params={"limit": 5})
for perf in resp.json():
total = int(perf['total_subscribed']) / 1e6
interest = int(perf['total_interest_paid']) / 1e6
days = perf['duration_seconds'] / 86400
print(f" {perf['product_name']} — APY: {perf['annual_rate']}, {days:.0f}d, "
f"Subscribed: {total:.2f} USDT, Interest: {interest:.2f} USDT")
Display Conversion
// Convert Wei amounts for display
const totalSubscribedUSDT = (parseInt(total_subscribed) / 1_000_000).toFixed(2);
const totalInterestUSDT = (parseInt(total_interest_paid) / 1_000_000).toFixed(2);
// Convert duration to human-readable
const durationDays = (duration_seconds / 86400).toFixed(0);
// Example:
// total_subscribed: "10000000000" → "10000.00 USDT"
// total_interest_paid: "411000000" → "411.00 USDT"
// duration_seconds: 2592000 → "30 days"