Loading layout…
Platform Open API | Let AI RunPlatform Open API
This document is for third-party server integration. All management APIs use a platform-level key with the default base path /api/platform/open.
1. Overview
- Version:
V1 (with selected V2 fields)
- Target integrator: third-party backend services
- Auth header:
Authorization: Bearer <platform-key>
- Success criteria: always rely on
success in response body
2. Data Model
- One third-party platform maps to one platform key
- One platform contains many platform users (
platform_user_id)
- One platform user can own multiple projects (
platform_project_id)
- Each project has an isolated
token_key for model inference
- Platform key is for management APIs only, not for inference APIs
3. Common Response Schema
{
"success": true,
"message": "",
"data": {}
}
{
"success": false,
"message": "error message"
}
- Both success and failure commonly return
HTTP 200
- Use
success as the final status indicator
- Read
message for failure cause
4. States And Field Semantics
4.1 Status Values
| Field | Value | Meaning |
|---|
| User/mapping status | 1 | Enabled |
| User/mapping status | 2 | Disabled |
| Token status | 1 | Enabled |
| Token status | 2 | Disabled |
| Token status | 3 | Expired |
| Token status | 4 | Exhausted |
4.2 Log Types
type | Meaning |
|---|
0 | All |
1 | Top-up |
2 | Usage |
3 | Admin operations |
4 | System logs |
5 | Error logs |
6 | Refund |
4.3 Quota Semantics
- User-level quota (
User.Quota) is the only real balance source
quota_used on project side is cumulative project usage
user_quota_remaining on project side is the real user balance
quota_limited_by currently always returns user
1 USD = 500000 quota
quota = USD amount x 500000
USD amount = quota / 500000
Balance-changing fields by endpoint:
- Top-up:
quota
- Refund/reversal:
refund_quota
- Balance reset:
target_quota
- Balance adjust:
delta_quota
amount, refund_amount, currency, and metadata are audit fields only and do not trigger automatic conversion.
5. Idempotency
| Scenario | Idempotency key |
|---|
| User upsert | external_user_id (optional but recommended) |
| Project upsert | external_project_id (optional but recommended) |
| User top-up | external_order_id (required) |
| Top-up refund/reversal | external_refund_id (required) |
| Balance reset | external_reset_id (required) |
| Balance adjustment | external_adjust_id (required) |
Persist and pass these external IDs consistently to prevent duplicate provisioning and repeated balance operations.
6. Recommended Integration Flow
- Create and store the platform key in admin console
- Call user upsert API
- Use returned
platform_user_id for top-up/refund/adjustment flows
- Call project upsert API and get project token
- Use
token_key for /v1/chat/completions and other inference APIs
- Use query APIs for user/project/top-up/usage reconciliation
7. Endpoint List
| Method | Path | Description |
|---|
POST | /api/platform/open/users/upsert | Create or get platform user |
POST | /api/platform/open/users/:platform_user_id/disable | Disable platform user |
POST | /api/platform/open/users/:platform_user_id/enable | Enable platform user |
GET | /api/platform/open/users/:platform_user_id/summary | Query user quota summary |
GET | /api/platform/open/users/:platform_user_id/logs | Query user usage logs |
POST | /api/platform/open/users/:platform_user_id/topups | Top up user quota |
POST | /api/platform/open/users/:platform_user_id/topups/refund | Refund/reverse top-up |
POST | /api/platform/open/users/:platform_user_id/balance/reset | Reset user balance |
POST | /api/platform/open/users/:platform_user_id/balance/adjust | Increase/decrease user balance |
GET | /api/platform/open/users/:platform_user_id/topups | Query top-up records |
POST | /api/platform/open/users/:platform_user_id/projects/upsert | Create/get project and return token |
POST | /api/platform/open/projects/:platform_project_id/disable | Disable project |
POST | /api/platform/open/projects/:platform_project_id/enable | Enable project |
GET | /api/platform/open/projects/:platform_project_id/summary | Query project token summary |
GET | /api/platform/open/projects/:platform_project_id/logs | Query project token usage logs |
8. Core Request Examples
8.1 Create Or Get Platform User
POST /api/platform/open/users/upsert
Authorization: Bearer <platform-key>
Content-Type: application/json
{
"external_user_id": "u_10001",
"name": "Alice",
"email": "alice@example.com",
"phone": "+86-13800000000",
"metadata": {
"channel": "partner-a"
}
}
8.2 Top Up Platform User
POST /api/platform/open/users/:platform_user_id/topups
Authorization: Bearer <platform-key>
Content-Type: application/json
{
"external_order_id": "ord_20260518_0001",
"quota": 5000000,
"amount": "72.00",
"currency": "CNY",
"remark": "package top-up"
}
8.3 Refund Or Reverse Top-up
POST /api/platform/open/users/:platform_user_id/topups/refund
Authorization: Bearer <platform-key>
Content-Type: application/json
{
"external_refund_id": "refund_20260518_0001",
"external_order_id": "ord_20260518_0001",
"refund_quota": 1000000,
"refund_amount": "14.40",
"currency": "CNY",
"remark": "partial refund"
}
8.4 Create Or Get Project And Return Token
POST /api/platform/open/users/:platform_user_id/projects/upsert
Authorization: Bearer <platform-key>
Content-Type: application/json
{
"external_project_id": "p_10001",
"name": "Support Bot",
"expired_time": 1798761599,
"remain_quota": 0
}
9. Use Project Token For Inference
After project upsert succeeds, call inference APIs with returned token_key instead of platform key:
curl --request POST \
--url https://api.letai.run/v1/chat/completions \
--header 'Authorization: Bearer <token_key>' \
--header 'Content-Type: application/json' \
--data '{
"model": "gpt-5.4",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
10. FAQ
Why do query APIs use platform_user_id / platform_project_id?
external_* IDs are integration-side mapping keys. Internal query APIs are keyed by platform IDs, so query endpoints use platform IDs consistently.
What happens if external_user_id or external_project_id is omitted?
Each upsert can be treated as a fresh create, which may generate duplicate users or projects.
Why is metadata sometimes returned as a string?
In some paths it is serialized before storage. Consumers should handle both JSON string and object forms.
Can project token still call models after user is disabled?
No. Disabling a user also blocks model access for all project tokens under that user.
11. Integration Recommendations
- Store platform key and project tokens separately with least privilege
- Record
x-request-id, external_* idempotency keys, and business order IDs in your own logs
- Add caller-side retry and deduplication for top-up/refund/adjustment APIs
- Alert on
success=false and insufficient balance events