External API Integration Documentation
I. API Overview
This document is intended for external developers who need to integrate device data queries.
API Features
- SK Authentication: Header carries
X-Saas-Id+X-SK, does not use platform JWT Token - IP Whitelist: IP whitelist can be configured for users in the backend (multiple specific IPs, comma-separated); if empty, no restriction
- Rate Limiting: Executed according to platform-configured rate limit rules (supports account-specific or global defaults)
- Query Interfaces: Device status, configuration, earnings, etc. are all
GET - Write Interfaces: Device bind/unbind are
POST(requires SK authentication, no transaction password needed)
II. Basic Information
Service URL
Production Environment: https://api.morphogenai.topThere is currently no separate test environment available.
The external business API path prefix is /api, full example:
https://api.morphogenai.top/api/device/statusOnline documentation (Markdown, UTF-8):
GET https://api.morphogenai.top/api/docs/integration
Content-Type: text/markdown;charset=UTF-8Character Encoding
| Scenario | Content-Type |
|---|---|
| Business API JSON response | application/json;charset=UTF-8 |
Online docs /api/docs/integration | text/markdown;charset=UTF-8 |
Common Request Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Saas-Id | String | Yes | Account identifier issued when the platform is activated (provided together with SK, no need to look it up yourself) |
X-SK | String | Yes | Plaintext SK issued when the platform is activated (provided together with X-Saas-Id) |
Unified Response Format
The business API response body is JSON with the following fields:
| Field | Type | Description |
|---|---|---|
code | String | E_000 success; E_001 failure (see Section IV) |
msg | String | "Success" on success; specific reason on failure |
data | Object / null | Business data; generally null on failure |
Success Example:
{
"code": "E_000",
"msg": "Success",
"data": { }
}Failure Example:
{
"code": "E_001",
"msg": "Authentication failed: SK verification failed",
"data": null
}Time Field Format: String, e.g., 2026-05-31T09:30:25 (LocalDateTime JSON serialization, no timezone suffix).
Missing Parameters: When required Query parameters are missing, the framework returns HTTP 400 and does not enter the business ResultVo.
Default Rate Limit Configuration
The platform default rate limits are as follows (administrators can adjust for individual accounts):
| Interface | api_code | time_window | max_requests | Description |
|---|---|---|---|---|
| Device Online Status | DEVICE_STATUS | 1_MINUTE | 1 | 1 time per minute |
| Token Settlement | TOKEN_SETTLE | 1_HOUR | 1 | 1 time per hour |
| Device Config | DEVICE_CONFIG | 1_DAY | 1 | 1 time per day |
| Config Occupancy | DEVICE_CONFIG_OCCUPY | 1_HOUR | 1 | 1 time per hour |
| Device Location | DEVICE_LOCATION | 5_MINUTE | 1 | 1 time per 5 minutes |
| Single Device Earnings | DEVICE_EARNINGS | 1_DAY | 1 | 1 time per day |
| Account Device Earnings Summary | ACCOUNT_DEVICE_EARNINGS | 1_DAY | 1 | 1 time per day |
| Bind Device | DEVICE_BIND | 1_MINUTE | 5 | 5 times per minute |
| Unbind Device | DEVICE_UNBIND | 1_MINUTE | 5 | 5 times per minute |
Earnings Notes:
| Type | Single Device Earnings API | Account Earnings Summary API |
|---|---|---|
| Static Release Earnings | Yes (staticRelease) | Yes (staticRelease) |
| Dynamic Earnings | No (dynamic is always 0) | Yes (dynamic) |
Earnings are in USD.
III. API List
1. Device Online Status
| Item | Description |
|---|---|
| Endpoint | GET /api/device/status |
| api_code | DEVICE_STATUS |
| Default Rate | 1 time per minute |
Request Parameters
Header
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Saas-Id | String | Yes | X-Saas-Id issued when the platform is activated |
X-SK | String | Yes | Caller's SK |
Query
| Parameter | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number (sn_code) |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Same as input |
onlineStatus | Integer | 1 online, 0 offline |
lastHeartbeat | String / null | Latest sync or online/offline time; may be null |
networkType | String | ISP; UNKNOWN if no data |
Only queries devices bound to the current
X-Saas-Id.
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"deviceId": "CL20260327103546870813300",
"onlineStatus": 1,
"lastHeartbeat": "2026-06-08T10:30:25",
"networkType": "Verizon"
}
}2. Token Settlement Data
| Item | Description |
|---|---|
| Endpoint | GET /api/token/settlement |
| api_code | TOKEN_SETTLE |
| Default Rate | 1 time per hour |
Request Parameters
Header
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Saas-Id | String | Yes | X-Saas-Id issued when the platform is activated |
X-SK | String | Yes | Caller's SK |
Query: None
Response data Fields
| Field | Type | Description |
|---|---|---|
saasId | String | Same as X-Saas-Id |
totalTokens | Integer | Total released Tokens |
settledTokens | Integer | Total daily-settled Tokens |
unsettledTokens | Integer | Unsettled Tokens (totalTokens - settledTokens, minimum 0) |
lastSettlementTime | String / null | Latest settlement time; null if no record |
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"saasId": "test_saas_001",
"totalTokens": 10000,
"settledTokens": 8500,
"unsettledTokens": 1500,
"lastSettlementTime": "2026-05-31T08:00:00"
}
}3. Device Configuration Query
| Item | Description |
|---|---|
| Endpoint | GET /api/device/config |
| api_code | DEVICE_CONFIG |
| Default Rate | 1 time per day |
Request Parameters
Header: X-Saas-Id, X-SK (required, same as Section I)
Query
| Parameter | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number (sn_code) |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Same as input |
model | String | CPU model or upstream name; UNKNOWN if no data |
version | String | OS or architecture; UNKNOWN if no data |
memoryGb | Integer | Total memory (GB, rounded) |
storageGb | Integer | Total disk (GB, rounded) |
Only queries devices bound to the current
X-Saas-Id.
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"deviceId": "CL20260327103546870813300",
"model": "Intel(R) Core(TM) i7-12700",
"version": "Linux",
"memoryGb": 32,
"storageGb": 1024
}
}4. Device Configuration Occupancy Query
| Item | Description |
|---|---|
| Endpoint | GET /api/device/config/occupy |
| api_code | DEVICE_CONFIG_OCCUPY |
| Default Rate | 1 time per hour |
Request Parameters
Header: X-Saas-Id, X-SK (required)
Query
| Parameter | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number (sn_code) |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Same as input |
isBound | Boolean | Whether already bound to an account |
boundSaasId | String / null | X-Saas-Id of the binding account; null if not bound |
boundTime | String / null | Binding time; null if not bound |
expireTime | null | Always null (no expiry field currently) |
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"deviceId": "CL20260327103546870813300",
"isBound": true,
"boundSaasId": "2a2cc29053144a6fb84c41039d9717ed",
"boundTime": "2026-05-01T10:00:00",
"expireTime": null
}
}5. Device Online Location
| Item | Description |
|---|---|
| Endpoint | GET /api/device/location |
| api_code | DEVICE_LOCATION |
| Default Rate | 1 time per 5 minutes |
Request Parameters
Header: X-Saas-Id, X-SK (required)
Query
| Parameter | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number (sn_code) |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Same as input |
longitude | null | Latitude/longitude not currently provided, always null |
latitude | null | Latitude/longitude not currently provided, always null |
address | String | Region description (region); UNKNOWN if no data |
updateTime | String | Latest device info sync time |
Only queries devices bound to the current
X-Saas-Id.
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"deviceId": "CL20260327103546870813300",
"longitude": null,
"latitude": null,
"address": "California, USA",
"updateTime": "2026-06-08T10:30:25"
}
}6. Single Device Earnings (by Device ID)
| Item | Description |
|---|---|
| Endpoint | GET /api/device/earnings |
| api_code | DEVICE_EARNINGS |
| Default Rate | 1 time per day |
Queries static release earnings by device serial number; dynamic is always 0 (for dynamic earnings, use the account earnings summary API).
Request Parameters
Header: X-Saas-Id, X-SK (required)
Query
| Parameter | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number (sn_code) |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Same as input |
currency | String | Always USD |
staticRelease | Object | Static release earnings (see table below) |
dynamic | Object | Dynamic earnings (always 0 for single device, same field structure as staticRelease) |
updateTime | String | Statistics update time |
staticRelease / dynamic Sub-fields:
| Field | Type | Description |
|---|---|---|
total | Number | Cumulative total |
today | Number | Today |
yesterday | Number | Yesterday |
staticRelease.total: Total daily-settled static release for this device (USD)staticRelease.today: Released today (USD, includes unsettled portion)staticRelease.yesterday: Yesterday's daily-settled static release (USD)dynamic: All zeros for the single device API
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"deviceId": "CL20260327103546870813300",
"currency": "USD",
"staticRelease": {
"total": 12.34500,
"today": 0.51200,
"yesterday": 0.49800
},
"dynamic": {
"total": 0,
"today": 0,
"yesterday": 0
},
"updateTime": "2026-06-08T10:30:00"
}
}7. Account Device Earnings Summary
| Item | Description |
|---|---|
| Endpoint | GET /api/account/device/earnings |
| api_code | ACCOUNT_DEVICE_EARNINGS |
| Default Rate | 1 time per day |
Queries the total static release and dynamic earnings of all bound devices under the current X-Saas-Id account.
Request Parameters
Header: X-Saas-Id, X-SK (required)
Query: None
Response data Fields
| Field | Type | Description |
|---|---|---|
saasId | String | Same as X-Saas-Id |
deviceCount | Integer | Number of currently bound devices |
currency | String | Always USD |
staticRelease | Object | Total account static release earnings (USD) |
dynamic | Object | Total account dynamic team rewards (USD) |
totalEarnings | Number | staticRelease.total + dynamic.total |
updateTime | String | Statistics update time |
Example:
{
"code": "E_000",
"msg": "Success",
"data": {
"saasId": "test_saas_001",
"deviceCount": 3,
"currency": "USD",
"staticRelease": {
"total": 45.67800,
"today": 1.53600,
"yesterday": 1.49400
},
"dynamic": {
"total": 8.12000,
"today": 0.32000,
"yesterday": 0.28000
},
"totalEarnings": 53.79800,
"updateTime": "2026-06-08T10:30:00"
}
}8. Bind Device
| Item | Description |
|---|---|
| Endpoint | POST /api/device/bind |
| api_code | DEVICE_BIND |
| Default Rate | 5 times per minute |
| Content-Type | application/json;charset=UTF-8 |
Binds a device serial number (sn_code) to the X-Saas-Id account in the Header. The device must already be in the platform's SN whitelist and not occupied by another account.
Request Parameters
Header: X-Saas-Id, X-SK (required)
Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number |
remarkName | String | No | Remark name |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Device serial number |
saasId | String | Binding account |
bindTime | String | Binding time |
onlineStatus | Integer | 1 online, 0 offline |
Example:
curl -X POST "https://api.morphogenai.top/api/device/bind" \
-H "Content-Type: application/json" \
-H "X-Saas-Id: <X-Saas-Id provided by customer service>" \
-H "X-SK: <X-SK provided by customer service>" \
-d '{"deviceId":"CL20260327103546870813300","remarkName":"ServerRoom-A-01"}'9. Unbind Device
| Item | Description |
|---|---|
| Endpoint | POST /api/device/unbind |
| api_code | DEVICE_UNBIND |
| Default Rate | 5 times per minute |
| Content-Type | application/json;charset=UTF-8 |
Unbinds the specified device from the current X-Saas-Id account. The external API uses SK authentication and does not require a transaction password.
Request Parameters
Header: X-Saas-Id, X-SK (required)
Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
deviceId | String | Yes | Device serial number |
Response data Fields
| Field | Type | Description |
|---|---|---|
deviceId | String | Device serial number |
saasId | String | Unbinding account |
unbindTime | String | Unbinding time |
Example:
curl -X POST "https://api.morphogenai.top/api/device/unbind" \
-H "Content-Type: application/json" \
-H "X-Saas-Id: <X-Saas-Id provided by customer service>" \
-H "X-SK: <X-SK provided by customer service>" \
-d '{"deviceId":"CL20260327103546870813300"}'Common Failure Reasons:
| msg | Description |
|---|---|
| Invalid device ID | SN not in platform whitelist |
| Device not found | Device does not exist on OpenAPI side |
| Device already bound by another user | Already occupied by another account |
| You have already bound this device | Duplicate binding |
| Device not bound | No valid binding for current account when unbinding |
IV. Error Code Description
| code | Typical msg | Description |
|---|---|---|
E_000 | Success | Business processing successful |
E_001 | Authentication failed: saasId or SK cannot be empty | Missing Header parameters |
E_001 | Authentication failed: User does not exist | External API not activated |
E_001 | Authentication failed: User has been disabled | Account status ≠ 1 |
E_001 | Authentication failed: SK verification failed | SK mismatch |
E_001 | Request IP is not in the whitelist | IP whitelist verification failed |
E_001 | API call frequency exceeded, please try again later | Rate limit triggered |
On failure,
msgis based on the actual response; authentication failures are uniformly prefixed withAuthentication failed:.
V. Call Examples
# Replace X-Saas-Id, X-SK, deviceId with the values provided by customer service and the actual device serial number
curl -G "https://api.morphogenai.top/api/device/status" \
--data-urlencode "deviceId=CL20260327103546870813300" \
-H "X-Saas-Id: <X-Saas-Id provided by customer service>" \
-H "X-SK: <X-SK provided by customer service>"VI. Activation and Usage Flow
- Apply for activation: Contact masf58722@gmail.com, describe the business purpose and the caller's source IP (if IP whitelist is needed). No need to look up
X-Saas-Idyourself. - Obtain credentials: After review, customer service will provide
X-Saas-IdandX-SKin plaintext once. Save them immediately. - Configure whitelist (optional): Provide multiple specific IPs to customer service (comma-separated, wildcards not supported); leave empty for no restrictions.
- Call APIs: Following the example in Section V, use the provided
X-Saas-IdandX-SKto access/api/**business endpoints. - Subsequent changes: SK reset, IP whitelist, quota adjustments, etc. — please contact masf58722@gmail.com.
VII. Notes
- SK Security: SK is equivalent to a secret key; if leaked, contact masf58722@gmail.com to reset it.
- Rate Limiting: Subject to the platform's actual configuration; account-specific rules take precedence over global defaults.
- IP Whitelist: When the whitelist is non-empty, only the specific IPs listed can call the APIs (exact match, wildcards not supported).
- Encoding: Request URLs, Headers, and JSON responses are all UTF-8.
VIII. Contact Support
For activation requests, SK resets, IP whitelist configuration, quota adjustments, etc., please contact masf58722@gmail.com.
Document Version: v2.0
Last Updated: 2026-06-08