401 Unauthorized 是因未开启API或未配置密钥及IP白名单;需启用API、正确设置key/secret、填写来源IP,并用HMAC-SHA256签名,原始字符串为path?args+secret。

宝塔面板 API 开启后调用失败:401 Unauthorized 怎么办
没开 API 或没配对密钥,401 是最常见拦路虎。宝塔默认关闭 API,且开启后必须手动设置「API 密钥」和「IP 白名单」。
实操建议:
- 登录宝塔后台 → 「安全」→ 找到「API 接口」开关,启用它
- 复制生成的
key和secret,别只存 key 忘了 secret(脚本里两者都要用) -
白名单 IP填你发请求的服务器公网 IP;本地测试时填你本机公网 IP,或临时设为0.0.0.0/0(上线前务必改回) - 签名算法必须用
HMAC-SHA256,且原始字符串格式是path?arg1=val1&arg2=val2 + secret(注意没有空格、无 URL 编码)
用 Python 调用 create_site 接口创建网站失败的典型原因
多数人卡在参数结构不对或权限不足——create_site 不是传个域名就完事,它依赖前置资源(PHP 版本、FTP、数据库等)是否已存在或允许自动创建。
实操建议:
- 先用
get_php_versions查看面板已安装的 PHP 版本,php_version参数必须精确匹配返回值里的name字段(如"74",不是"7.4") -
type字段决定是否自动建 FTP/数据库:0(不建)、1(建 FTP)、2(建 DB)、3(都建)。选3时得确保 MySQL 已启动且有可用数据库配额 - 路径参数
path必须是绝对路径,且父目录需已存在、宝塔运行用户(通常是www)有写权限;别传/www/wwwroot/example.com却忘了/www/wwwroot目录本身不存在 - 若返回
"code": 1, "msg": "站点已存在",说明域名已在面板中注册过,得先调用del_site清理,或加逻辑判断跳过
批量建站脚本中如何避免“创建一半中断导致状态不一致”
网络抖动、API 超时、目标目录冲突都会让脚本中途退出,留下半成品网站(有 Nginx 配置但无文件目录,或建了库却没绑域名),后续重跑容易报错。
实操建议:
- 每个站点创建前,先调用
get_site_list检查域名是否已存在;存在则跳过或记录日志,不强行覆盖 - 关键操作(如建库、建 FTP)后,立即调用对应查询接口验证结果,比如建完库立刻查
get_database_list确认库名出现在列表里 - 所有 API 请求必须带超时(
timeout=30),并捕获requests.exceptions.RequestException,失败时记入日志并continue,别让一个失败拖垮整批 - 把站点配置(域名、路径、PHP 版本)存成 JSON 文件,每次运行前读取并标记「已完成」字段,下次只处理未完成项
为什么用 curl 写批量脚本不如 Python + requests
宝塔 API 签名依赖动态时间戳、HMAC 计算和参数排序,curl 命令行拼接极易出错——尤其是 shell 对特殊字符(&、=、空格)的处理会让签名原文和实际请求参数不一致。
实操建议:
- 别用
curl -X POST -d "..."手动拼 body,改用requests.post(url, json=payload),自动处理 JSON 序列化和 Content-Type - 签名计算必须在发送前最后一刻做(含当前秒级时间戳),shell 里用
date +%s+openssl dgst组合极易因时区、换行符、变量扩展顺序翻车 - Python 可直接复用
hmac和hashlib标准库,几行代码搞定签名,且便于调试打印每一步的原始字符串 - 如果非要用 shell,至少封装成函数,把签名逻辑抽离,避免重复粘贴时漏改某处
secret
真正麻烦的从来不是调通第一个 API,而是当你要建 200 个站时,发现第 187 个因为磁盘满失败,而日志里只写了 “HTTP 500”,得倒回去逐个查 nginx 错误日志、MySQL 错误日志、宝塔任务队列……这时候,每个 try/except 和每条带上下文的 logging.info() 才显出价值。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










