API request
If you need to use the API control token, you need to apply to the reseller or administrator first, and you can use it only after the administrator opens it.
Contact email: support@bsf.ai
Please include the reason for your request and the account to be opened.
All token management endpoints require user authentication (UserAuth middleware) and support two methods:
- Session Cookie (automatically included after browser login)
- Access Token (passed via the
Authorizationheader, suitable for curl / programmatic access)
When using Access Token authentication, include the following headers:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | User Access Token |
All curl examples below use Access Token authentication. Replace:
https://api.bsf.ai/— Your service URL{ACCESS_TOKEN}— Your user Access Token
Base path: /api/token
Data Structure
Token Object
| Field | Type | Description |
|---|---|---|
id | int | Token ID (primary key) |
user_id | int | Owner user ID |
key | string | API Key (48 characters, auto-generated, prefixed with sk-) |
status | int | Status: 1 Enabled / 2 Disabled / 3 Expired / 4 Quota exhausted |
name | string | Token name (max 50 characters) |
created_time | int64 | Creation time (Unix timestamp) |
accessed_time | int64 | Last access time (Unix timestamp) |
expired_time | int64 | Expiration time (Unix timestamp), -1 means never expires |
remain_quota | int | Remaining quota |
unlimited_quota | bool | Whether quota is unlimited |
used_quota | int | Consumed quota |
model_limits_enabled | bool | Whether model restrictions are enabled |
model_limits | string | Allowed models (comma-separated, e.g. gpt-4,claude-3-opus) |
allow_ips | string | IP allowlist (newline \n separated, supports CIDR notation) |
group | string | Channel group |
cross_group_retry | bool | Cross-group retry (only effective for auto group) |
API Endpoints
1. List Tokens
GET /api/token/?p={page}&size={pageSize}Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
p | int | No | Page number, starting from 0 |
size | int | No | Items per page |
Response Example:
{
"success": true,
"message": "",
"data": {
"page": 0,
"page_size": 10,
"total": 2,
"items": [
{
"id": 1,
"name": "my-token",
"status": 1,
"key": "",
"created_time": 1710000000,
"expired_time": -1,
"remain_quota": 500000,
"unlimited_quota": false,
"used_quota": 12000,
"model_limits_enabled": false,
"model_limits": "",
"allow_ips": "",
"group": "",
"cross_group_retry": false
}
]
}
}Note: The
keyfield is cleared in list responses and will not return the actual API Key.
curl Example:
curl -X GET 'https://api.bsf.ai/api/token/?p=0&size=10' \
-H 'Authorization: {ACCESS_TOKEN}'2. Search Tokens
GET /api/token/search?keyword={keyword}&token={tokenKey}&p={page}&size={pageSize}Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
keyword | string | No | Fuzzy search by name |
token | string | No | Search by Key |
p | int | No | Page number |
size | int | No | Items per page |
Search is rate-limited (
SearchRateLimitmiddleware). Fuzzy search requires at least 2 characters and allows up to 2 wildcards.
curl Example:
# Search by name
curl -X GET 'https://api.bsf.ai/api/token/search?keyword=production&p=0&size=10' \
-H 'Authorization: {ACCESS_TOKEN}'
# Search by Key
curl -X GET 'https://api.bsf.ai/api/token/search?token=abc123&p=0&size=10' \
-H 'Authorization: {ACCESS_TOKEN}'3. Get a Single Token
GET /api/token/{id}Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | int | Yes | Token ID |
Response Example:
{
"success": true,
"message": "",
"data": {
"id": 1,
"name": "my-token",
"key": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"status": 1,
"remain_quota": 500000,
"..."
}
}curl Example:
curl -X GET 'https://api.bsf.ai/api/token/1' \
-H 'Authorization: {ACCESS_TOKEN}'4. Create a Token
POST /api/token/
Content-Type: application/jsonRequest Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Token name, max 50 characters |
expired_time | int64 | No | Expiration time (Unix timestamp), -1 for never expires |
remain_quota | int | No | Remaining quota (for non-unlimited tokens, range 0 ~ 1,000,000,000 × QuotaPerUnit) |
unlimited_quota | bool | No | Whether quota is unlimited |
model_limits_enabled | bool | No | Whether to enable model restrictions |
model_limits | string | No | Allowed models (comma-separated) |
allow_ips | string | No | IP allowlist (newline-separated, supports CIDR) |
group | string | No | Channel group |
cross_group_retry | bool | No | Cross-group retry |
Request Example:
{
"name": "production-key",
"expired_time": 1735689600,
"remain_quota": 1000000,
"unlimited_quota": false,
"model_limits_enabled": true,
"model_limits": "gpt-4,gpt-4o,claude-3-opus",
"allow_ips": "192.168.1.0/24\n10.0.0.1",
"group": "default"
}Response:
{
"success": true,
"message": ""
}Each user has a maximum token limit. Creation will fail if the limit is exceeded.
curl Example:
# Create a token with quota and model restrictions
curl -X POST 'https://api.bsf.ai/api/token/' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"name": "production-key",
"expired_time": 1735689600,
"remain_quota": 1000000,
"unlimited_quota": false,
"model_limits_enabled": true,
"model_limits": "gpt-4,gpt-4o,claude-3-opus",
"allow_ips": "192.168.1.0/24\n10.0.0.1",
"group": "default"
}'
# Create an unlimited, never-expiring token
curl -X POST 'https://api.bsf.ai/api/token/' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"name": "unlimited-key",
"expired_time": -1,
"unlimited_quota": true
}'5. Update a Token
5a. Update All Modifiable Fields
PUT /api/token/
Content-Type: application/jsonRequest Body:
| Field | Type | Required | Description |
|---|---|---|---|
id | int | Yes | Token ID to update |
name | string | No | Token name |
expired_time | int64 | No | Expiration time |
remain_quota | int | No | Remaining quota |
unlimited_quota | bool | No | Whether quota is unlimited |
model_limits_enabled | bool | No | Whether to enable model restrictions |
model_limits | string | No | Allowed models |
allow_ips | string | No | IP allowlist |
group | string | No | Channel group |
cross_group_retry | bool | No | Cross-group retry |
curl Example:
# Update token name, quota, and model restrictions
curl -X PUT 'https://api.bsf.ai/api/token/' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"id": 1,
"name": "renamed-key",
"remain_quota": 2000000,
"unlimited_quota": false,
"model_limits_enabled": true,
"model_limits": "gpt-4o,claude-3-5-sonnet",
"expired_time": 1767225600
}'5b. Update Status Only
PUT /api/token/?status_only=1
Content-Type: application/jsonRequest Body:
| Field | Type | Required | Description |
|---|---|---|---|
id | int | Yes | Token ID |
status | int | Yes | 1 Enable / 2 Disable |
Restrictions:
- Expired tokens cannot be enabled unless the expiration time is updated
- Quota-exhausted tokens cannot be enabled unless they have unlimited quota
curl Example:
# Disable a token
curl -X PUT 'https://api.bsf.ai/api/token/?status_only=1' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"id": 1, "status": 2}'
# Enable a token
curl -X PUT 'https://api.bsf.ai/api/token/?status_only=1' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"id": 1, "status": 1}'Response:
{
"success": true,
"message": "",
"data": { "...updated token object..." }
}6. Delete a Token
DELETE /api/token/{id}Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | int | Yes | Token ID |
curl Example:
curl -X DELETE 'https://api.bsf.ai/api/token/1' \
-H 'Authorization: {ACCESS_TOKEN}'Response:
{
"success": true,
"message": ""
}Deletion is a soft delete — data is not immediately purged.
7. Batch Delete Tokens
POST /api/token/batch
Content-Type: application/jsonRequest Body:
{
"ids": [1, 2, 3]
}Response:
{
"success": true,
"message": "",
"data": 3
}data is the number of tokens actually deleted.
curl Example:
curl -X POST 'https://api.bsf.ai/api/token/batch' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"ids": [1, 2, 3]}'Token Usage Query
This endpoint uses Bearer Token authentication (i.e., the API Key queries its own usage) and does not require user login.
GET /api/usage/token/
Authorization: Bearer sk-xxxxxxxxcurl Example:
curl -X GET 'https://api.bsf.ai/api/usage/token/' \
-H 'Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'Response Example:
{
"code": true,
"message": "ok",
"data": {
"object": "token_usage",
"name": "my-token",
"total_usd_granted": 2.024,
"total_usd_used": 0.024,
"total_usd_available": 2.0,
"unlimited_quota": false,
"model_limits": {
"gpt-4": true,
"claude-3-opus": true
},
"model_limits_enabled": true,
"expires_at": 1735689600,
"user_usd_available": 88.5
}
}| Field | Description |
|---|---|
total_usd_granted | Token total granted quota (USD), equals total_usd_available + total_usd_used |
total_usd_used | Token used quota (USD) |
total_usd_available | Token remaining available quota (USD) |
unlimited_quota | Whether quota is unlimited |
model_limits | Model restriction mapping |
expires_at | Expiration time, 0 means never expires |
user_usd_available | User account remaining balance (USD). When unlimited quota is enabled, this field represents the actual usable limit |
Token Daily Usage Statistics
GET /api/token/{id}/usage?start_date={start}&end_date={end}Requires user login authentication (same as token management endpoints).
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | int | Yes | Token ID |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | No | Start date, format YYYY-MM-DD |
end_date | string | No | End date, format YYYY-MM-DD |
Limits:
- Defaults to the last 1 day if no parameters are provided
- Maximum 7 days; automatically truncated to
start_date + 7 daysif exceeded - Results are cached for 10 minutes to reduce database load
Response Example:
{
"success": true,
"data": {
"token_id": 1,
"token_name": "my-token",
"start_date": "2026-03-20",
"end_date": "2026-03-26",
"daily": [
{
"date": "2026-03-20",
"usd": 0.35,
"requests": 12,
"prompt_tokens": 5000,
"completion_tokens": 2000
}
]
}
}daily Field Descriptions:
| Field | Description |
|---|---|
date | Date (YYYY-MM-DD) |
usd | Daily spend (USD) |
requests | Number of requests |
prompt_tokens | Input token count |
completion_tokens | Output token count |
curl Examples:
# Query last 1 day (default)
curl -X GET 'https://api.bsf.ai/api/token/1/usage' \
-H 'Authorization: {ACCESS_TOKEN}'
# Query specific date range (max 7 days)
curl -X GET 'https://api.bsf.ai/api/token/1/usage?start_date=2026-03-20&end_date=2026-03-26' \
-H 'Authorization: {ACCESS_TOKEN}'Quota Unit Conversion
| Unit | Description |
|---|---|
quota | Internal unit |
USD | User-facing unit |
| Conversion | 1 USD = 500,000 quota (i.e., $0.002 / 1K tokens) |
Error Response Format
{
"success": false,
"message": "error message"
}