前缀为 /v1/admin。发送 Authorization: Bearer <token>,token 是会话(kks_...,12 小时)或个人访问 token(kkp_...)。不接受 App 密钥。请求体和响应都是 JSON,错误采用通用的错误格式。下文路径中 :t 表示租户 id,:a 表示 App id。
不是租户成员的用户会收到 404 tenant_not_found;是成员但没有相应权限的会收到 403 forbidden。权限列表见密钥与权限。CLI 覆盖了 App 相关接口。
| 方法 |
路径 |
说明 |
| POST |
/auth/login |
{email, password, totp_code} → {token, expires_at, mfa, user}。错误:invalid_credentials、totp_required、totp_invalid、totp_reused、totp_clock_skew |
| POST |
/auth/logout |
结束当前会话 |
| POST |
/invitations/accept |
{token, password, name}。新用户拿到的会话只能用来绑定 TOTP |
| GET |
/me |
当前用户及所属租户 |
| POST |
/me/totp/setup |
返回 secret 和 otpauth_uri |
| POST |
/me/totp/enable |
{code};升级当前会话 |
| DELETE |
/me |
{password, totp_code}。删除账号;如果你是某个还有其他成员的租户的所有者,必须先转让所有权(409 owner_must_transfer) |
| GET, POST |
/me/tokens |
列出或创建个人访问 token。POST {name, expires_in_days?}(1 到 3650),只能在会话中调用;token 只显示一次 |
| DELETE |
/me/tokens/:token_id |
吊销 token |
启用 TOTP 之前,其他所有调用都返回 403 totp_enrollment_required。
| 方法 |
路径 |
权限 |
说明 |
| GET |
/tenants |
任意 |
你所属的租户 |
| GET |
/tenants/:t |
tenant.read |
|
| PATCH |
/tenants/:t |
tenant.update |
{name} |
| DELETE |
/tenants/:t |
tenant.delete |
删除业务数据,保留审计日志 |
| GET |
/tenants/:t/members |
member.read |
|
| PATCH |
/tenants/:t/members/:user_id |
member.manage |
{role}:admin、developer 或 readonly。所有者的角色不能修改 |
| DELETE |
/tenants/:t/members/:user_id |
member.manage |
除所有者外,任何成员都可以移除自己 |
| GET, POST |
/tenants/:t/invitations |
member.manage |
POST {email, role} 返回有效期 7 天的 token,只显示一次 |
| DELETE |
/tenants/:t/invitations/:invitation_id |
member.manage |
撤销邀请 |
| POST |
/tenants/:t/transfer-ownership |
owner.transfer |
{user_id};新所有者必须已启用 TOTP。原所有者变为管理员 |
| GET |
/tenants/:t/audit |
audit.read |
?limit=1..500&before=<id>,最新的在前,返回 next_before |
| 方法 |
路径 |
权限 |
说明 |
| GET |
/tenants/:t/apps |
app.read |
可按 ios_bundle_id、android_package 精确过滤 |
| POST |
/tenants/:t/apps |
app.write |
下列 App 字段,可另带 apple 和 google 凭据。secret_key 和 webhook_secret 只返回一次 |
| GET |
/tenants/:t/apps/:a |
app.read |
包含入站回调路径 |
| PATCH |
/tenants/:t/apps/:a |
app.write |
只修改你发送的字段;null 表示清空 |
| DELETE |
/tenants/:t/apps/:a |
app.delete |
删除 App 及其数据 |
| POST |
/tenants/:t/apps/:a/keys/rotate |
keys.rotate |
{webhook_secret: true} 会同时更换回调签名密钥。旧密钥立即失效 |
| POST |
/tenants/:t/apps/:a/webhooks/test |
webhooks.test |
见测试投递 |
App 字段:
| 字段 |
类型 |
name |
string |
ios_bundle_id, android_package |
string |
apple_app_apple_id |
integer |
apple_environment |
production、sandbox |
apple_refund_preference |
DECLINE、GRANT_FULL、GRANT_PRORATED |
google_pubsub_audience, google_pubsub_email |
string |
google_consumable_products |
string[];末尾的 * 表示前缀 |
webhook_url |
string |
checkout_return_hosts |
string[],最多 50 项 |
cors_origins |
string[],最多 50 项 |
ads_unmapped_policy |
reject、emit |
ads_allow_shared_test_units |
boolean |
凭据只能写入。读取时只返回摘要和指纹(SHA-256 的前 8 位十六进制),从不返回原值。
| 方法 |
路径 |
权限 |
说明 |
| GET |
/tenants/:t/apps/:a/credentials |
app.read |
各渠道的摘要 |
| PUT, DELETE |
/tenants/:t/apps/:a/credentials/apple |
credentials.write |
{issuer_id, key_id, private_key, app_apple_id?, environment?} |
| PUT, DELETE |
/tenants/:t/apps/:a/credentials/google |
credentials.write |
{service_account_json, pubsub_audience?, pubsub_email?} |
| PUT, DELETE |
/tenants/:t/apps/:a/credentials/:channel |
credentials.write |
其他渠道和广告网络:{values: {key: value or null}}。键名:stripe 为 secret_key、webhook_secret;ccbill 为 client_accnum、client_subacc、salt、datalink_username、datalink_password、webhook_ips、environment;applovin 为 event_key;admob 为 app_id;levelplay 为 private_key、app_key、timestamp_window_seconds、ip_allowlist |
| 方法 |
路径 |
权限 |
说明 |
| GET |
/channels |
任意 |
渠道插件及其能力 |
| GET |
/tenants/:t/apps/:a/channels |
app.read |
另附该 App 的凭据检查结果 |
| GET |
/tenants/:t/apps/:a/channels/:channel/products |
app.read |
商品映射 |
| PUT |
/tenants/:t/apps/:a/channels/:channel/products/:product_id |
app.write |
{external_id, type},type 为 subscription 或 one_time |
| DELETE |
/tenants/:t/apps/:a/channels/:channel/products/:product_id |
app.write |
|
| POST |
/tenants/:t/apps/:a/channels/:channel/refunds |
refunds.write |
refund: true 的渠道(CCBill):{transaction_id, amount_micros?}。其他渠道返回 404 refund_not_supported |
| POST |
/tenants/:t/apps/:a/channels/:channel/simulate |
app.write |
simulate: true 的渠道(CCBill):在 test 环境模拟一条渠道通知;需要先打开测试商店 |
每个渠道报告的能力:subscriptions、one_time_purchases、refunds、refund_lookup、active_refund、reconcile、sandbox、chargebacks。
| 方法 |
路径 |
权限 |
说明 |
| GET |
/tenants/:t/apps/:a/test-store |
app.read |
设置和警告 |
| PUT |
/tenants/:t/apps/:a/test-store |
app.write |
{enabled?, subscription_period_seconds?, renewal_success_rate?, grace_period_seconds?, billing_retry_seconds?, products?, prices?} |
| GET |
/tenants/:t/apps/:a/test-store/purchases |
app.read |
?app_user_id=&limit=1..500 |
| POST |
/tenants/:t/apps/:a/test-store/simulate |
app.write |
{scenario, purchase_id?, app_user_id?, product_id?, to_product_id?} |
| POST |
/tenants/:t/apps/:a/test-store/advance |
app.write |
{app_user_id, purchase_id?, outcome?},outcome 为 success 或 failure |
| 方法 |
路径 |
权限 |
说明 |
| GET |
/ad-networks |
任意 |
广告网络插件 |
| GET |
/tenants/:t/apps/:a/ad-networks |
app.read |
该 App 的回调路径和凭据检查结果 |
| GET |
/tenants/:t/apps/:a/ad-units |
app.read |
{ad_units: [{name, networks, units, updated_at}]} |
| PUT |
/tenants/:t/apps/:a/ad-units/:name |
app.write |
{networks: {admob?, applovin?, levelplay?}};见广告位映射 |
| DELETE |
/tenants/:t/apps/:a/ad-units/:name |
app.write |
|
| GET |
/tenants/:t/apps/:a/ads/unmatched |
app.read |
?limit=1..500 |
| GET, PUT |
/tenants/:t/apps/:a/test-ads |
app.read / app.write |
PUT {enabled} |
| POST |
/tenants/:t/apps/:a/ads/simulate |
app.write |
{app_user_id, ad_unit, reward_type?, reward_amount?, custom_data?, outcome?, network_transaction_id?, network?} |
每次写操作都会记入审计日志。