胜算云 胜算云 文档中心 ↗ 精益社区

BYOK 管理 API

查询供应商,并创建、查看和编辑企业 BYOK 配置。

BYOK管理 API

💡

接口参考待联调:当前控制台通过 keys 列表提交多把密钥,并使用 model_mappings、byok_provider_model_ids 等字段;下文旧例的单密钥 schema/config 结构不能直接套用。 以下是待核对的接口资料,不作为可直接接入的正式示例。控制台操作请按对应使用指南完成。

概述

BYOK(Bring Your Own Key)管理API用于管理用户自带的API密钥,支持添加、查看和编辑各种AI服务提供商的密钥配置。这允许企业使用自己的API密钥而不是平台提供的密钥。

基础信息

  • Base URL: YOUR_GATEWAY_MANAGEMENT_BASE_URL
  • 认证方式: AccessKey/SecretKey签名 或 JWT Token
  • 请求格式: JSON
  • 响应格式: JSON

权限说明

操作 主账号 RAM管理员 RAM成员
创建BYOK ✅ ✅ ❌
查看BYOK列表 ✅ ✅ ❌
查看用户BYOK ✅ ✅ ❌
编辑BYOK ✅ ✅ ❌

注意: 所有BYOK操作都需要管理员权限(主账号或RAM管理员)。

API接口列表

1. 获取BYOK提供商列表

查询系统支持的BYOK提供商,以及模型列表。

接口信息

  • Path: /byok/list
  • Method: GET
  • 权限: 主账号、RAM管理员

请求参数

无参数

请求示例

GET /byok/list
X-Access-Key-Id: AK_xxx
X-Timestamp: 2024-01-01T12:00:00+00:00
X-Signature: xxx

响应示例

{
  "code": 0,
  "data": [
    {
      "ID": 10,
      "Name": "百度OpenAI",
      "Desc": "百度OpenAI",
      "Schema": "{\n  \"title\": \"API Token\",\n  \"properties\": {\n    \"api_key\": {\n      \"type\": \"string\",\n      \"title\": \"ApiKey\"\n    }\n  }\n}",
      "ChannelTypeID": 40,
      "Icon": "",
      "BaseUrl": "https://qianfan.baidubce.com/v2",
      "TestRouter": "",
      "ChannelType": {
        "ID": 40,
        "CreatedAt": "0001-01-01T00:00:00Z",
        "UpdatedAt": "0001-01-01T00:00:00Z",
        "name": "Baidu",
        "provider_name": "baidu",
        "description": "baidu",
        "label": "llm",
        "base_url": "https://qianfan.baidubce.com/v2",
        "channel": null,
        "support_models": [
        {
                        "ID": 343,
                        "CreatedAt": "2025-12-10T15:02:24.726661+08:00",
                        "UpdatedAt": "2025-12-17T17:01:00.030477+08:00",
                        "type_id": 4,
                        "name": "deepseek-v3.2",
                        "model_info_id": 245,
                        "description": "",
                        "price": 0,
                        "ratio": 1,
                        "inputprice": 20000,
                        "outputprice": 30000,
                        "cached_price": 2000,
                        "image_price": 0,
                        "completion_ratio": 1,
                        "other_price": "0",
                        "provider_price": 0,
                        "provider_input_price": 20000,
                        "provider_output_price": 30000,
                        "provider_cached_price": 2000,
                        "provider_image_price": 0,
                        "provider_other_price": "0",
                        "provider_rpm": 15000,
                        "provider_tpm": 1200000,
                        "tpm_threshold": 99,
                        "rpm_threshold": 99,
                        "context": 128000,
                        "max_output": 64000,
                        "latency": 20153,
                        "throughput": 11,
                        "precision": "fp16",
                        "auto_route": true,
                        "currency": "CNY",
                        "provider_filter": "",
                        "country_code": "CN",
                        "manual_priority": -20,
                        "supported_apis": "/v1/chat/completions,/v1/messages",
                        "url_path": "",
                        "other_info": "",
                        "model_info": {
                            "ID": 245,
                            "CreatedAt": "2025-12-02T11:12:23.716222+08:00",
                            "UpdatedAt": "2025-12-02T11:15:27.214011+08:00",
                            "company": "DeepSeek",
                            "company_id": 9,
                            "company_info": {
                                "ID": 0,
                                "CreatedAt": "0001-01-01T00:00:00Z",
                                "UpdatedAt": "0001-01-01T00:00:00Z",
                                "icon64": "",
                                "name": "",
                                "description": "",
                                "website": "",
                                "model_infos": null
                            },
                            "model_name": "Deepseek V3.2",
                            "copy_name": "deepseek/deepseek-v3.2",
                            "desc": "DeepSeek-V3.2 是一款大型语言模型,......  ",
                            "offical_site": "https://deepseek.com",
                            "open_source": "https://deepseek.com",
                            "licence": "https://deepseek.com",
                            "model_type_id": 1,
                            "model_type": {
                                "ID": 0,
                                "CreatedAt": "0001-01-01T00:00:00Z",
                                "UpdatedAt": "0001-01-01T00:00:00Z",
                                "display_name": "",
                                "ModelInterfaceCatalog": null,
                                "status": 0
                            },
                            "support_models": null,
                            "supports_prompt_cache": true,
                            "priority": 1,
                            "currency": "CNY",
                            "original_price": 0,
                            "original_input_price": 20000,
                            "original_output_price": 30000,
                            "original_cached_price": 2000,
                            "original_image_price": 0,
                            "original_other_price": "",
                            "model_use_cases": null,
                            "input_modalities": null,
                            "output_modalities": null,
                            "extend_info": {
                                "ID": 0,
                                "CreatedAt": "0001-01-01T00:00:00Z",
                                "UpdatedAt": "0001-01-01T00:00:00Z",
                                "model_info_id": 0,
                                "input_schema": "",
                                "output_schema": "",
                                "price_schema": "",
                                "usage": 0,
                                "preview_url": "",
                                "preview_video": ""
                            }
                        },
                        "channel_types": {
                            "ID": 0,
                            "CreatedAt": "0001-01-01T00:00:00Z",
                            "UpdatedAt": "0001-01-01T00:00:00Z",
                            "name": "",
                            "provider_name": "",
                            "description": "",
                            "label": "",
                            "base_url": "",
                            "channel": null,
                            "support_models": null
                        }
                    }
        ]
      }
    }
  ],
  "msg": "查询成功"
}

2. 获取用户BYOK列表

查询当前用户配置的所有BYOK。

接口信息

  • Path: /byok/user/list
  • Method: GET
  • 权限: 主账号、RAM管理员

请求参数

无参数

请求示例

GET /byok/user/list
X-Access-Key-Id: AK_xxx
X-Timestamp: 2024-01-01T12:00:00+00:00
X-Signature: xxx

响应示例

{
  "code": 0,
  "data": [
    {
      "id": 46,
      "byok_provider_name": "Azure",
      "schema": "{\"deployments\":[{\"api_key\":\"YOUR_PROVIDER_API_KEY\",\"endpoint_url\":\"YOUR_AZURE_OPENAI_ENDPOINT\",\"model_id\":\"gpt-5\",\"model_slug\":\"openai/gpt-5\"}],\"model_api_name\":[\"openai/gpt-5\"]}",
      "model_api_name": [
        "openai/gpt-5"
      ],
      "is_enabled": true,
      "always_use_this_key": false,
      "schema_struct": "{\n  \"title\": \"Azure Configuration(Deployments)\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"deployments\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"model_slug\": {\n            \"type\": \"string\",\n            \"title\": \"Model Slug\"\n          },\n          \"endpoint_url\": {\n            \"type\": \"string\",\n            \"title\": \"Endpoint URL\"\n          },\n          \"api_key\": {\n            \"type\": \"string\",\n            \"title\": \"API Key\"\n          },\n          \"model_id\": {\n            \"type\": \"string\",\n            \"title\": \"Model ID\"\n          }\n        },\n        \"required\": [\n          \"model_slug\",\n          \"endpoint_url\",\n          \"api_key\",\n          \"model_id\"\n        ]\n      },\n      \"minItems\": 1\n    }\n  },\n  \"required\": [\n    \"deployments\"\n  ]\n}",
      "model_mapping": [],
      "support_model": [
        {
          "ID": 106,
          "CreatedAt": "2025-07-22T10:54:15.445333+08:00",
          "UpdatedAt": "2025-11-20T17:18:45.519544+08:00",
          "type_id": 28,
          "name": "gpt-4.1",
          "model_info_id": 74,
          "description": "",
          "price": 0,
          "ratio": 1,
          "inputprice": 12500,
          "outputprice": 100000,
          "cached_price": 1250,
          "image_price": 0,
          "completion_ratio": 0,
          "other_price": "",
          "provider_price": 0,
          "provider_input_price": 12500,
          "provider_output_price": 100000,
          "provider_cached_price": 1250,
          "provider_image_price": 0,
          "provider_other_price": "",
          "provider_rpm": 10000,
          "provider_tpm": 1000000,
          "tpm_threshold": 80,
          "rpm_threshold": 80,
          "context": 0,
          "max_output": 0,
          "latency": 1089,
          "throughput": 14,
          "precision": "",
          "auto_route": true,
          "currency": "USD",
          "provider_filter": "",
          "country_code": "CN",
          "manual_priority": 0,
          "supported_apis": "/v1/chat/completions,/v1/messages",
          "model_info": {
            "ID": 74,
            "CreatedAt": "2025-02-20T15:54:58.348372+08:00",
            "UpdatedAt": "2025-06-04T18:23:43.977268+08:00",
            "company": "OpenAI",
            "company_id": 6,
            "company_info": {
              "ID": 0,
              "CreatedAt": "0001-01-01T00:00:00Z",
              "UpdatedAt": "0001-01-01T00:00:00Z",
              "icon64": "",
              "name": "",
              "description": "",
              "website": "",
              "model_infos": null
            },
            "model_name": "GPT-5-pro",
            "copy_name": "openai/gpt-5-pro",
            "desc": "",
            "offical_site": "",
            "open_source": "",
            "licence": "",
            "model_type_id": 1,
            "model_type": {
              "ID": 0,
              "CreatedAt": "0001-01-01T00:00:00Z",
              "UpdatedAt": "0001-01-01T00:00:00Z",
              "display_name": ""
            },
            "support_models": null,
            "supports_prompt_cache": false,
            "priority": 5,
            "currency": "CNY",
            "original_price": 0,
            "original_input_price": 50000,
            "original_output_price": 90000,
            "original_cached_price": 0,
            "original_image_price": 0,
            "original_other_price": "",
            "model_use_cases": null,
            "input_modalities": null,
            "output_modalities": null,
            "extend_info": {
              "ID": 0,
              "CreatedAt": "0001-01-01T00:00:00Z",
              "UpdatedAt": "0001-01-01T00:00:00Z",
              "model_info_id": 0,
              "input_schema": "",
              "output_schema": "",
              "price_schema": "",
              "usage": 0,
              "preview_url": "",
              "preview_video": ""
            }
          },
          "channel_types": {
            "ID": 0,
            "CreatedAt": "0001-01-01T00:00:00Z",
            "UpdatedAt": "0001-01-01T00:00:00Z",
            "name": "",
            "provider_name": "",
            "description": "",
            "label": "",
            "base_url": "",
            "channel": null,
            "support_models": null
          }
        }
      ]
    }
  ],
  "msg": "查询成功"
}

3. 创建BYOK配置

添加新的BYOK配置。

接口信息

  • Path: /byok/create
  • Method: POST
  • 权限: 主账号、RAM管理员

请求参数

参数名 类型 必填 说明 示例
byok_provider_id int 是 提供商ID 1
channel_type_id int 是 渠道id 21
schema string 是 byok结构信息 见下方示例
model_mappings object 是 模型别名映射 见下方示例
is_enabled bool 是 是否启用 true
always_use_this_key bool 是 是否总是使用这个key 见下方示例
support_model_id array 是 支持的模型 ID 列表 [12]

config对象: 根据不同提供商包含不同字段,参考"获取BYOK提供商列表"返回的config_fields。

请求示例

OpenAI配置示例:

POST /byok/create
Content-Type: application/json
X-Access-Key-Id: AK_xxx
X-Timestamp: 2024-01-01T12:00:00+00:00
X-Signature: xxx

{
  "always_use_this_key": true,
  "byok_provider_id": 0,
  "channel_type_id": 0,
  "is_enabled": true,
  "model_mappings": [
    {
      "custom_name": "string",
      "support_model_name": "string"
    }
  ],
  "schema": "string",
  "support_model_id": [
    0
  ]
}

响应示例

{
  "data": {},
  "msg": "新建Byok成功"
}

4. 编辑BYOK配置

更新已有的BYOK配置。 如果没有schema的变更,那么不需要传入schema

接口信息

  • Path: /byok/edit
  • Method: POST
  • 权限: 主账号、RAM管理员

请求参数

参数名 类型 必填 说明 示例
id integer 是 BYOK配置ID 1
name string 否 新的配置名称 更新后的名称
config object 否 新的配置信息 见下方示例
status integer 否 状态:1启用,2禁用 1

请求示例

POST /byok/edit
Content-Type: application/json
X-Access-Key-Id: AK_xxx
X-Timestamp: 2024-01-01T12:00:00+00:00
X-Signature: xxx

{
  "always_use_this_key": true,
  "byok_id": 0,
  "is_enabled": true,
  "model_mappings": [
    {
      "custom_name": "string",
      "support_model_name": "string"
    }
  ],
  "schema": "string"
}

响应示例

{
  "data": {},
  "msg": "更新成功"
}

5 获取模型列表方法


完整调用示例

Python完整示例

import requests
import hashlib
import hmac
import base64
import json
from datetime import datetime, timezone
from urllib.parse import urlencode


class BYOKAPI:
    def __init__(self, base_url, access_key_id, secret_key):
        self.base_url = base_url
        self.access_key_id = access_key_id
        self.secret_key = secret_key

    def _sign(self, method, uri, body):
        body_bytes = json.dumps(body, separators=(',', ':')).encode('utf-8') if body is not None else b''
        body_hash = base64.b64encode(
            hashlib.sha256(body_bytes).digest()
        ).decode()

        timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S+00:00')

        string_to_sign = f"{method}\n{uri}\n{timestamp}\n{body_hash}"

        signature = base64.b64encode(
            hmac.new(
                self.secret_key.encode(),
                string_to_sign.encode(),
                hashlib.sha256
            ).digest()
        ).decode()

        return timestamp, signature

    def _request(self, method, path, body=None, params=None):
        uri = path
        if params:
            uri = f"{path}?{urlencode(params)}"

        timestamp, signature = self._sign(method, uri, body)

        resp = requests.request(
            method,
            f"{self.base_url}{uri}",
            data=json.dumps(body, separators=(',', ':')).encode('utf-8') if body is not None else None,
            timeout=30,
            headers={
                "Content-Type": "application/json",
                "X-Access-Key-Id": self.access_key_id,
                "X-Timestamp": timestamp,
                "X-Signature": signature
            }
        )
        resp.raise_for_status()
        return resp.json()

    # -------- APIs --------

    def list_providers(self):
        return self._request("GET", "/byok/list")

    def list_user_byoks(self):
        return self._request("GET", "/byok/user/list")

    def create_byok(self, *, byok_provider_id, channel_type_id,
                    schema_dict, support_model_id,
                    model_mappings=None,
                    is_enabled=True,
                    always_use_this_key=False):

        body = {
            "byok_provider_id": byok_provider_id,
            "channel_type_id": channel_type_id,
            "schema": json.dumps(schema_dict, ensure_ascii=False),
            "support_model_id": support_model_id,
            "model_mappings": model_mappings or [],
            "is_enabled": is_enabled,
            "always_use_this_key": always_use_this_key
        }

        return self._request("POST", "/byok/create", body)

    def edit_byok(self, *, byok_id,
                  schema_dict=None,
                  model_mappings=None,
                  is_enabled=None,
                  always_use_this_key=None):

        body = {
            "byok_id": byok_id
        }

        if schema_dict is not None:
            body["schema"] = json.dumps(schema_dict, ensure_ascii=False)

        if model_mappings is not None:
            body["model_mappings"] = model_mappings

        if is_enabled is not None:
            body["is_enabled"] = is_enabled

        if always_use_this_key is not None:
            body["always_use_this_key"] = always_use_this_key

        return self._request("POST", "/byok/edit", body)


Node.js完整示例

使用 Node.js 18 或以上版本,先执行 npm install axios,将代码保存为 .cjs 文件。替换为获准的测试环境和凭证;底部示例包含写入操作,接口契约仍需按页首说明核准。

const crypto = require('crypto');
const axios = require('axios');

class BYOKAPI {
    constructor(baseUrl, accessKeyId, secretKey) {
        this.baseUrl = baseUrl;
        this.accessKeyId = accessKeyId;
        this.secretKey = secretKey;
    }

    calculateSignature(method, uri, body) {
        const bodyBytes = body ? JSON.stringify(body) : '';
        const bodyHash = crypto.createHash('sha256')
            .update(bodyBytes)
            .digest('base64');

        const timestamp = new Date().toISOString().replace(/\.\d{3}Z$/, '+00:00');
        const stringToSign = `${method}\n${uri}\n${timestamp}\n${bodyHash}`;

        const signature = crypto.createHmac('sha256', this.secretKey)
            .update(stringToSign)
            .digest('base64');

        return { timestamp, signature };
    }

    async request(method, uri, body = null, params = null) {
        let fullUri = uri;
        if (params) {
            const queryString = new URLSearchParams(params).toString();
            fullUri = `${uri}?${queryString}`;
        }

        const { timestamp, signature } = this.calculateSignature(method, fullUri, body);

        const config = {
            method,
            url: `${this.baseUrl}${fullUri}`,
            headers: {
                'Content-Type': 'application/json',
                'X-Access-Key-Id': this.accessKeyId,
                'X-Timestamp': timestamp,
                'X-Signature': signature
            }
        };

        if (body && method === 'POST') {
            config.data = body;
        }

        const response = await axios(config);
        return response.data;
    }

    async listProviders() {
        return this.request('GET', '/byok/list');
    }

    async listUserBYOKs() {
        return this.request('GET', '/byok/user/list');
    }

    async createBYOK(provider, name, config) {
        return this.request('POST', '/byok/create', {
            provider,
            name,
            config
        });
    }

    async editBYOK(byokId, updates) {
        return this.request('POST', '/byok/edit', {
            id: byokId,
            ...updates
        });
    }
}

// 使用示例
(async () => {
    const api = new BYOKAPI(
        'http://your-domain.com',
        'AK_xxx',
        'SK_xxx'
    );

    try {
        // 1. 获取提供商列表
        const providers = await api.listProviders();
        console.log('提供商列表:', providers);

        // 2. 创建BYOK
        const byok = await api.createBYOK('openai', '生产OpenAI', {
            api_key: 'sk-proj-xxxxx',
            organization: 'org-xxxxx'
        });
        console.log('创建BYOK:', byok);

        // 3. 获取用户BYOK列表
        const userBYOKs = await api.listUserBYOKs();
        console.log('用户BYOK:', userBYOKs);

        // 4. 更新BYOK
        const updated = await api.editBYOK(byok.data.id, {
            name: '更新后的配置',
            status: 1
        });
        console.log('更新BYOK:', updated);

    } catch (error) {
        console.error('API调用失败:', error.response?.data || error.message);
    }
})();

使用场景

场景1: 多环境密钥管理

为不同环境配置不同的BYOK:

# 生产环境
production_byok = api.create_byok(
    provider="openai",
    name="生产环境-OpenAI",
    config={
        "api_key": "YOUR_PROVIDER_API_KEY",
        "organization": "org-production"
    }
)

# 测试环境
testing_byok = api.create_byok(
    provider="openai",
    name="测试环境-OpenAI",
    config={
        "api_key": "sk-proj-testing-xxxxx",
        "organization": "org-testing"
    }
)

# 开发环境
dev_byok = api.create_byok(
    provider="openai",
    name="开发环境-OpenAI",
    config={
        "api_key": "sk-proj-dev-xxxxx",
        "organization": "org-dev"
    }
)

场景2: 密钥轮换

定期轮换API密钥以提高安全性:

# 更新密钥
api.edit_byok(
    byok_id=1,
    config={
        "api_key": "YOUR_PROVIDER_API_KEY",
        "organization": "org-xxxxx"
    }
)

场景3: 多提供商配置

配置多个AI服务提供商:

# OpenAI
openai_byok = api.create_byok(
    provider="openai",
    name="OpenAI GPT",
    config={"api_key": "sk-proj-xxxxx"}
)

# Anthropic Claude
anthropic_byok = api.create_byok(
    provider="anthropic",
    name="Anthropic Claude",
    config={"api_key": "sk-ant-xxxxx"}
)

# Azure OpenAI
azure_byok = api.create_byok(
    provider="azure",
    name="Azure OpenAI",
    config={
        "api_key": "azure-key",
        "endpoint": "YOUR_AZURE_OPENAI_ENDPOINT",
        "api_version": "2024-02-15-preview"
    }
)

场景4: 临时禁用BYOK

在密钥泄露或需要维护时临时禁用:

# 禁用BYOK
api.edit_byok(byok_id=1, status=2)

# 恢复启用
api.edit_byok(byok_id=1, status=1)

错误码说明

错误码 说明 解决方法
400 参数错误或配置格式不正确 检查请求参数和config格式
401 未认证 检查AccessKey和签名
403 权限不足(非管理员) 需要主账号或RAM管理员权限
404 BYOK配置不存在 检查BYOK ID
422 API密钥验证失败 检查提供的API密钥是否有效
500 服务器错误 联系技术支持

安全建议

  1. 密钥加密存储: 系统会加密存储所有API密钥
  2. 密钥脱敏显示: 列表查询时API密钥会被脱敏显示(如sk-****)
  3. 定期轮换: 建议定期更换API密钥
  4. 最小权限原则: 为不同环境使用不同的API密钥,限制权限范围
  5. 监控使用情况: 通过last_used_at字段监控密钥使用情况
  6. 及时禁用: 发现密钥泄露时立即禁用

注意事项

  1. 管理员权限: 所有BYOK操作都需要管理员权限(主账号或RAM管理员)
  2. 配置验证: 创建BYOK时系统会验证API密钥的有效性
  3. 提供商支持: 不同提供商支持的模型和配置字段不同,参考/byok/list返回的信息
  4. 密钥格式: 确保API密钥格式正确,包含必要的前缀(如OpenAI的sk-proj-)

相关文档

示例运行范围

完整客户端示例需要 Python 3 与 requests;JavaScript 客户端需要 Node.js 与 axios。后续业务片段复用前文创建的客户端实例,不是独立脚本。执行创建、修改或删除前,仅使用获准的测试环境及测试数据。这里的本地语法检查不代表接口联调通过。