Skip to main content

Admin Endpoints

Endpoints available to the Admin role only (role JWT with role = "admin" required).


Create BD Account

POST /api/v1/broker/admin/bd
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Request Body

{
"username": "alice_bd",
"display_name": "Alice",
"initial_password": "s3cur3pass"
}
FieldTypeRequiredDescription
usernamestringYesMust be unique
display_namestringNo
initial_passwordstringYesPlaintext — bcrypt-hashed server-side

Response

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "alice_bd",
"display_name": "Alice",
"role": "bd",
"status": "active"
}

Errors

HTTPDescription
400Username already exists

List BD Accounts

GET /api/v1/broker/admin/bds
Authorization: Bearer <admin_jwt>

Returns array of BD account objects (same schema as Create BD Account response), ordered by created_at DESC.


Edit BD Account

Update a BD's display_name and/or status.

PUT /api/v1/broker/admin/bd/:id
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Path Parameters

ParameterTypeDescription
idstring (UUID)BD account ID

Request Body

{
"display_name": "Alice (updated)",
"status": "disabled"
}
FieldTypeRequiredDescription
display_namestringNoNew display name
statusstringNo"active" or "disabled"

Response

{ "id": "550e8400-..." }

Admin Dashboard

Global platform summary.

GET /api/v1/broker/admin/dashboard
Authorization: Bearer <admin_jwt>

Response

{
"bd_count": 5,
"kol_count": 120,
"total_fee": "50000.00",
"total_nominal_rebate": "35000.00",
"total_kol_rebate": "30000.00",
"platform_net_retention": "5000.00"
}
FieldTypeDescription
bd_countintActive BD accounts
kol_countintActive KOLs
total_feedecimalSum of all fee_amount across all rebate records
total_nominal_rebatedecimalSum of gross rebates owed
total_kol_rebatedecimalSum of net KOL rebates paid
platform_net_retentiondecimaltotal_nominal_rebate − total_kol_rebate

Admin KOL List

GET /api/v1/broker/admin/kols[?bd_id=<uuid>]
Authorization: Bearer <admin_jwt>

Query Parameters

ParameterTypeRequiredDescription
bd_idstring (UUID)NoFilter by BD. Returns up to 200 KOLs if omitted.

Response

[
{
"broker_id": "550e8400-...",
"wallet_address": "0xabc...",
"nickname": "Alice",
"bd_owner_id": "bd-uuid-...",
"level": 1,
"rebate_rate": "0.70",
"parent_broker": null,
"invitee_count": 25,
"status": "active"
}
]
FieldTypeDescription
broker_idstring (UUID)
wallet_addressstring
nicknamestring | null
bd_owner_idstring (UUID)
levelint | nullTier level. null for sub-KOLs.
rebate_ratestring (decimal)
parent_brokerstring | nullParent KOL's wallet address (only for sub-KOLs)
invitee_countintCount of bound downlines
statusstring"active" or "frozen"

Adjust KOL

Update a KOL's level, rebate_rate, and/or status. Fields are updated individually if present.

Sub-KOLs (those with parent_broker_id set) cannot have their level or rebate_rate adjusted — their rate is fixed by the parent's invite code. Only status can be updated for Sub-KOLs.

PUT /api/v1/broker/admin/kol/:id
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Path Parameters

ParameterTypeDescription
idstring (UUID)Broker ID

Request Body (all fields optional)

{
"level": 2,
"rebate_rate": 0.75,
"status": "frozen"
}
FieldTypeDescription
levelintNew tier level (KOLs only)
rebate_ratefloatNew rebate rate (KOLs only)
statusstring"active" or "frozen"

Response

{ "broker_id": "550e8400-...", "updated": true }

Errors

HTTPDescription
400Cannot adjust level/rebate_rate for sub-KOLs

Set KOL Tier

Set the rebate tier for a KOL (not Sub-KOL) by selecting a pre-configured tier. The rebate_rate is updated to match the tier's configured value.

Sub-KOLs (those with parent_broker_id set) cannot use this endpoint — their rate is fixed by the parent's invite code.

PUT /api/v1/broker/admin/kol/:id/tier
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Path Parameters

ParameterTypeDescription
idstring (UUID)Broker ID

Request Body

{
"tier_level": 2
}
FieldTypeRequiredDescription
tier_levelintYesMust match a level defined in tier_thresholds config

Response

{
"broker_id": "550e8400-...",
"tier_level": 2,
"rebate_rate": "0.75",
"label": "Gold"
}

Errors

HTTPDescription
400Cannot set tier for sub-KOLs
400tier_level does not exist in configuration
500tier_thresholds not configured

Reassign KOL

Move a KOL to a different BD. Audit log entry is created.

PUT /api/v1/broker/admin/kol/:id/reassign
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Request Body

{
"new_owner": "bd-uuid-...",
"reason": "BD left the company"
}
FieldTypeRequiredDescription
new_ownerstringYesBD UUID, or "__company__" to remove BD affiliation
reasonstringNoAudit note

Response

{
"broker_id": "550e8400-...",
"new_bd_id": "bd-uuid-..."
}

Bulk Reassign KOLs

Transfer all KOLs from a given BD to another BD (or company). Optionally disable the source BD.

POST /api/v1/broker/admin/bd/:id/bulk-reassign
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Path Parameters

ParameterTypeDescription
idstring (UUID)Source BD ID

Request Body

{
"new_owner": "target-bd-uuid",
"disable_bd": true,
"reason": "BD resigned"
}
FieldTypeRequiredDescription
new_ownerstringYesTarget BD UUID or "__company__"
disable_bdboolNoIf true, sets source BD status = 'disabled'. Default false.
reasonstringNoAudit note

Response

{
"moved_kol_count": 12,
"new_owner": "target-bd-uuid",
"bd_disabled": true
}

Trigger Settlement

Manually trigger the daily rebate settlement for a specific date (T+0). Idempotent: re-running for the same period recalculates from pre_settlement records.

POST /api/v1/broker/admin/rebate/calculate
Authorization: Bearer <admin_jwt>
Content-Type: application/json

Request Body

{
"period": "2026-05-28",
"mode": "daily"
}
FieldTypeRequiredDescription
periodstringYesDate in YYYY-MM-DD format
modestringNoReserved — ignored currently

Response

{
"period": "2026-05-28",
"total_brokers": 120,
"total_records": 3840,
"total_nominal": "35000.00",
"total_customer_rebate": "7000.00",
"total_share": "3500.00",
"total_kol_net": "24500.00"
}
FieldTypeDescription
periodstringSettlement date
total_brokersintKOLs with at least one record
total_recordsintRebate records created
total_nominaldecimalSum of gross rebates
total_customer_rebatedecimalSum returned to customers
total_sharedecimalSum shared to parent KOLs
total_kol_netdecimalSum net KOL rebates

Errors

HTTPDescription
400Invalid period format (not YYYY-MM-DD)

Payout List

Paginated list of rebate records for payment processing.

GET /api/v1/broker/admin/rebate/payout-list
Authorization: Bearer <admin_jwt>

Query Parameters

ParameterTypeRequiredDescription
periodstringNoFilter by settlement date (YYYY-MM-DD). All periods if omitted.
statusstringNo"pending" (default), "paid", or "all"
pageintNoPage number, minimum 1 (default 1)
per_pageintNoRecords per page, max 500 (default 100)

Response

{
"total": 3840,
"page": 1,
"per_page": 100,
"records": [
{
"id": "record-uuid-...",
"broker_id": "broker-uuid-...",
"downline_wallet": "0xabc...",
"period": "2026-05-28",
"fee_amount": "10.00",
"kol_rebate_rate": "0.70",
"share_ratio": "0.10",
"nominal_rebate": "7.00",
"share_amount": "0.70",
"kol_net_rebate": "5.25",
"payment_status": "pending",
"payment_tx_hash": null
}
]
}