Install
openclaw skills install gate-exchange-affiliateGate partner affiliate data and application skill. Use when the user asks about partner commissions, referral volume, or applying for the affiliate program. Triggers on 'my affiliate data', 'partner earnings', 'apply for affiliate', 'commission'.
openclaw skills install gate-exchange-affiliateQuery and manage Gate Exchange affiliate/partner program data, including commission tracking, team performance analysis, and application guidance.
⚠️ STOP — You MUST read and strictly follow the shared runtime rules before proceeding.
Do NOT select or call any tool until all rules are read. These rules have the highest priority.
→ Read ./references/gate-runtime-rules.md
| MCP Server | Status |
|---|---|
| Gate (main) | ✅ Required |
Query Operations (Read-only)
GATE_API_KEY, GATE_API_SECRET)Read and strictly follow references/mcp.md, then execute this skill's affiliate workflow.
SKILL.md keeps routing and reporting policy.references/mcp.md is the authoritative MCP execution layer for eligibility/application/commission query flow and degraded handling.X-Gate-User-Id) are supplied by that session, not pasted by the user.commission_history and transaction_history APIs, the user_id parameter filters by "trader/trading user" NOT "commission receiver". Only use this parameter when explicitly querying a specific trader's contribution. For general commission queries, DO NOT use user_id parameter.All query windows use the user's current calendar date in UTC+8. For relative phrases ("last 7 days", "last 30 days", "this week", "last month"): compute the start date by subtracting the requested span from today, convert start and end to UTC+8 00:00:00 and 23:59:59 respectively, then to Unix timestamps. NEVER use future timestamps as query bounds. The to parameter must always be ≤ current Unix time. If the user specifies a future date, reject the query and explain that only historical data is available.
| API Endpoint | Description | Time Limit |
|---|---|---|
GET /rebate/partner/transaction_history | Get referred users' trading records | ≤30 days per request |
GET /rebate/partner/commission_history | Get referred users' commission records | ≤30 days per request |
GET /rebate/partner/sub_list | Get subordinate list (for customer count) | No time parameter |
GET /rebate/partner/eligibility | Check if user is eligible to apply for partner | No time parameter |
GET /rebate/partner/applications/recent | Get user's recent partner application record (last 30 days) | No time parameter |
Note: Agency APIs (/rebate/agency/*) are deprecated and not used in this skill.
user_id parameter for general commission queriesuser_id parameter in both commission_history and transaction_history APIs filters by TRADER/TRADING USER, not commission receiveruser_id when explicitly querying a specific trader's contribution (e.g., "UID 123456's trading volume")to must be ≤ current Unix time; reject user-specified future dates.user_id parameter only when the user explicitly asks about a specific trader's contribution (e.g. "UID 123456's volume"). Do not use user_id for "my commission" or "my earnings"—those are the partner's own totals across all referred users.commission_historytransaction_historytransaction_historysub_listtransaction_historyeligible and, when not eligible, block_reasons and block_reason_codes (e.g. sub_account, already_agent, kyc_incomplete).Identify the query type and extract parameters.
Key data to extract:
query_type: overview | time_specific | metric_specific | user_specific | team_report | application | application_eligibility | application_statustime_range: default 7 days or user-specified periodmetric: commission | volume | fees | customers | trading_users (if metric-specific)user_id: specific user ID (if user-specific query)Check if the requested time range is valid and determine if splitting is needed.
Key data to extract:
needs_splitting: boolean (true if >30 days)segments: array of time segments if splitting needederror: string if time range >180 daysBased on query type, call the appropriate Partner APIs.
When MCP is configured with Gate rebate tools, call the corresponding MCP tools by name (e.g. Call cex_rebate_partner_transaction_history, Call cex_rebate_partner_commissions_history, Call cex_rebate_partner_sub_list, Call cex_rebate_get_partner_eligibility, Call cex_rebate_get_partner_application_recent) with the parameters described in API Parameter Reference. When MCP is not available, use the API paths below.
CRITICAL REMINDER:
user_id parameter unless explicitly querying a specific trader's contributionuser_id in API responses represents the TRADER, not the commission receiverFor overview or time-specific queries:
/rebate/partner/transaction_history with time parameters (NO user_id)/rebate/partner/commission_history with time parameters (NO user_id)/rebate/partner/sub_list for customer countFor metric-specific queries:
For user-specific queries:
user_id parameter (this shows that specific trader's contribution)For application-related queries:
GET /rebate/partner/eligibility (returns eligible, block_reasons, block_reason_codes)GET /rebate/partner/applications/recent (returns last 30 days application record with audit_status, apply_msg, etc.)Key data to extract:
transactions: array of trading recordscommissions: array of commission recordssubordinates: array of team memberstotal_count: total records for paginationeligibility: { eligible, block_reasons, block_reason_codes } (for application_eligibility)application_recent: application record or empty (for application_status)If total > limit, implement pagination to retrieve all data.
Key data to extract:
all_data: complete dataset after paginationpages_fetched: number of API calls madeCalculate the requested metrics from the raw API responses.
IMPORTANT: Use custom aggregation logic based on business rules. DO NOT simply sum all values.
Key data to extract:
commission_amount: aggregated commission amount with proper business logictrading_volume: aggregated trading amount with proper calculationsnet_fees: aggregated fees with appropriate rulescustomer_count: total from sub_listtrading_users: count of unique user_idsGenerate the appropriate response based on query type using the templates.
| Condition | Status | Action |
|---|---|---|
| Query type = overview | ✅ | Use default 7 days, call all 3 APIs |
| Query type = time_specific | ✅ | Parse time range, check if splitting needed |
| Query type = metric_specific | ✅ | Call only required API(s) for the metric |
| Query type = user_specific | ✅ | Add user_id filter to API calls (NOTE: user_id = trader, not receiver) |
| Query type = team_report | ✅ | Call all APIs, generate comprehensive report |
| Query type = application | ✅ | Return application guidance; optionally call eligibility or applications/recent when user asks "can I apply?" or "my application status?" |
| Query type = application_eligibility | ✅ | Call GET /rebate/partner/eligibility, return eligible status and block_reasons |
| Query type = application_status | ✅ | Call GET /rebate/partner/applications/recent, return recent application record and audit_status |
| Time range ≤30 days | ✅ | Single API call per endpoint |
| Time range >30 days and ≤180 days | ✅ | Split into multiple 30-day segments |
| Time range >180 days | ❌ | Return error "Only supports queries within last 180 days" |
| Relative time description (e.g., "last 7 days") | ✅ | Calculate from current UTC+8 date, convert to 00:00:00-23:59:59 UTC+8, then to Unix timestamps |
| User specifies future date | ❌ | Reject query - only historical data available |
to parameter > current timestamp | ❌ | Reject query - adjust to current time or earlier |
| API returns 403 | ❌ | Return "No affiliate privileges" error |
| API returns empty data | ⚠️ | Show metrics as 0, not error |
| Total > limit in response | ✅ | Implement pagination |
| User_id not in sub_list | ❌ | Return "User not in referral network" |
| Invalid UID format | ❌ | Return format error message |
| User asks for "my commission" | ✅ | DO NOT use user_id parameter - query all commissions |
| User specifies trader UID | ✅ | Use user_id parameter to filter by that trader |
# Affiliate Data Report
**Query Type**: {query_type}
**Time Range**: {from_date} to {to_date}
**Generated**: {timestamp}
## Metrics Summary
| Metric | Value |
|--------|-------|
| Commission Amount | {commission_amount} USDT |
| Trading Volume | {trading_volume} USDT |
| Net Fees | {net_fees} USDT |
| Customer Count | {customer_count} |
| Trading Users | {trading_users} |
## Details
{Additional details based on query type:
- For user-specific: User type, join date
- For team report: Top contributors, composition breakdown
- For comparison: Period-over-period changes}
## Notes
{Any relevant notes:
- Data retrieved in X segments (if split)
- Pagination: X pages fetched
- Warnings or limitations}
---
*For more details, visit the affiliate dashboard: https://www.gate.com/referral/affiliate*
Triggers: "my affiliate data", "show my partner stats", "affiliate dashboard"
Default: Last 7 days
Output Template:
Your affiliate data overview (last 7 days):
- Commission Amount: XXX USDT
- Trading Volume: XXX USDT
- Net Fees: XXX USDT
- Customer Count: XXX
- Trading Users: XXX
For detailed data, visit the affiliate dashboard: {dashboard_url}
Triggers: "commission this week", "last month's rebate", "earnings for March"
Time Handling:
Agent Splitting Logic (for >30 days):
Example: User requests 60 days (2026-01-01 to 2026-03-01 in UTC+8)
Convert to UTC+8 00:00:00 and 23:59:59, then to Unix timestamps:
1. 2026-01-01 00:00:00 UTC+8 to 2026-01-31 23:59:59 UTC+8 (31 days -> adjust to 30)
2. 2026-01-31 00:00:00 UTC+8 to 2026-03-01 23:59:59 UTC+8 (29 days)
Call each segment separately with converted timestamps, then merge results.
Output Template:
Your affiliate data for {time_range}:
- Commission Amount: XXX USDT
- Trading Volume: XXX USDT
- Net Fees: XXX USDT
- Customer Count: XXX
- Trading Users: XXX
Triggers:
Output Template:
Your {metric_name} for the last 7 days: XXX {unit}
For detailed data, visit the affiliate dashboard: {dashboard_url}
Triggers: "UID 123456 contribution", "user 123456 trading volume", "how much commission from 123456"
IMPORTANT: The user_id parameter filters by "trader" not "commission receiver". This shows the trading activity and commission generated BY that specific trader, not commissions received by them.
Parameters:
user_id (the trader's UID whose contribution you want to check)Output Template:
UID {user_id} contribution (last 7 days):
- Commission Amount: XXX USDT (commission generated from this trader's activity)
- Trading Volume: XXX USDT (this trader's trading volume)
- Fees: XXX USDT (fees from this trader's trades)
Triggers: "team performance", "affiliate report", "partner analytics"
Process:
sub_list to get team memberstransaction_history for trading datacommission_history for commission dataOutput Template:
=== Team Performance Report ({time_range}) ===
📊 Team Overview
- Total Members: XXX (Sub-agents: X, Direct: X, Indirect: X)
- Active Users: XXX (XX.X%)
- New Members: XXX
💰 Trading Data
- Total Volume: XXX,XXX.XX USDT
- Total Fees: X,XXX.XX USDT
- Average Volume per User: XX,XXX.XX USDT
🏆 Commission Data
- Total Commission: XXX.XX USDT
- Spot Commission: XXX.XX USDT (XX%)
- Futures Commission: XXX.XX USDT (XX%)
👑 Top 5 Contributors
1. UID XXXXX - Volume XXX,XXX USDT / Commission XX.X USDT
2. ...
Triggers: "apply for affiliate", "become a partner", "join affiliate program", "can I apply?", "am I eligible?", "my application status", "recent application", "application result"
When to call APIs:
GET /rebate/partner/eligibility. If eligible, return application steps; if not, return block_reasons and guidance.GET /rebate/partner/applications/recent. Return audit_status (0=pending, 1=approved, 2=rejected), apply_msg, and jump_url.Eligibility response template (after calling eligibility API):
Eligibility check: {eligible ? "You are eligible to apply." : "You are not eligible at this time."}
{If not eligible:}
Block reasons: {block_reasons}
Please address the above before applying.
Application Portal: https://www.gate.com/referral/affiliate
Application status template (after calling applications/recent API):
Your recent partner application (last 30 days):
Status: {audit_status: 0=Pending, 1=Approved, 2=Rejected}
{apply_msg}
{jump_url if provided}
Generic guidance (no API or after API response):
You can apply to become a Gate Exchange affiliate and earn commission from referred users' trading.
Application Process:
1. Open the affiliate application page
2. Fill in application information
3. Submit application
4. Wait for platform review
Application Portal: https://www.gate.com/referral/affiliate
Benefits:
- Earn commission from referred users
- Access to marketing materials
- Dedicated support team
- Performance analytics dashboard
Your account does not have affiliate privileges.
To become an affiliate, please apply at: https://www.gate.com/referral/affiliate
Query supports maximum 180 days of historical data.
Please adjust your time range.
No data found for the specified time range.
Please check if you have referred users with trading activity during this period.
UID {user_id} not found in your referral network.
Please verify the user ID.
UID {user_id} is not part of your referral network.
You can only query data for users you've referred.
Sub-accounts cannot query affiliate data.
Please use your main account.
Parameters:
- currency_pair: string (optional) - e.g., "BTC_USDT"
- user_id: integer (optional) - IMPORTANT: This is the TRADER's ID, not commission receiver
- from: integer (required) - start timestamp (unix seconds)
- to: integer (required) - end timestamp (unix seconds)
- limit: integer (default 100) - max records per page
- offset: integer (default 0) - pagination offset
Response: {
total: number,
list: [{
transaction_time, user_id (trader), group_name,
fee, fee_asset, currency_pair,
amount, amount_asset, source
}]
}
Parameters:
- currency: string (optional) - e.g., "USDT"
- user_id: integer (optional) - IMPORTANT: This is the TRADER's ID who generated the commission
- from: integer (required) - start timestamp
- to: integer (required) - end timestamp
- limit: integer (default 100)
- offset: integer (default 0)
Response: {
total: number,
list: [{
commission_time, user_id (trader), group_name,
commission_amount, commission_asset, source
}]
}
Parameters:
- user_id: integer (optional) - filter by user ID
- limit: integer (default 100)
- offset: integer (default 0)
Response: {
total: number,
list: [{
user_id, user_join_time, type
}]
}
Type: 1=Sub-agent, 2=Indirect customer, 3=Direct customer
GET /rebate/partner/eligibility
Parameters: none (uses authenticated user)
Response: {
data: {
eligible: boolean,
block_reasons: string[],
block_reason_codes: string[]
}
}
block_reason_codes may include: user_not_exist, user_blacked, sub_account, already_agent, kyc_incomplete, in_agent_tree, ch_code_conflict
GET /rebate/partner/applications/recent
Parameters: none (returns current user's recent application in last 30 days)
Response: {
data: {
id, uid, audit_status, apply_msg, create_timest, update_timest,
proof_url, jump_url, proof_images_url_list, ...
} or empty
}
audit_status: 0=Pending, 1=Approved, 2=Rejected
For complete data retrieval when total > limit:
offset = 0
all_data = []
while True:
result = call_api(limit=100, offset=offset)
all_data.extend(result['list'])
if len(result['list']) < 100 or offset + 100 >= result['total']:
break
offset += 100
# IMPORTANT: Apply custom aggregation logic after collecting all data
# DO NOT simply sum values - consider business rules and data relationships
API accepts Unix timestamps in seconds (not milliseconds)
⚠️ CRITICAL TIME CALCULATION RULES:
to parameter must always be ≤ current Unix timestampTime Conversion Examples (assuming current date is 2026-03-13 in UTC+8):
Maximum 30 days per API request, split if needed
Basic Overview
Time Range
Specific Metric
User Contribution
Error Case
Application