Apprise API 2.0 API 使用详解

Apprise API v2.0.2 全部 HTTP 端点 curl 实测详解:状态/元信息、配置管理(增删改查移动)、双模通知、tag 标签路由陷阱、附件上传、Basic Auth 与键级认证实测边界、错误码速查。

Apprise通知自托管API2026/10/25

Apprise API 2.0 API 使用详解

目标:以 curl 逐端点实测的方式讲清 Apprise API v2.0.2 的全部 HTTP 接口——状态与元信息、有状态配置管理(增/删/改/查/移动)、双模通知发送、标签路由、附件上传与认证。所有请求与响应均来自 Ubuntu 22.04 上部署的 v2.0.2 实例逐条实测(安装方式见《Ubuntu 22.04 安装 Apprise API 2.0 指南》),响应原文照抄。

一、环境信息

  • 服务端:Apprise API v2.0.2(Apprise 库 2.1.0、Django 6.0.9),监听 8000 端口
  • 操作系统:Ubuntu 22.04.5 LTS(jammy),x86_64
  • 调用工具:curl(任意能发 HTTP 的客户端均可)
  • 测试辅助:本机 8433 端口的 JSON Webhook 接收器,充当通知目标(脚本见 2.3)
  • 演示配置键:myalerts(已保存 json://127.0.0.1:8433/hook 一条通道)

💡 说明:本文只讲 HTTP API。Apprise 另有同名 CLI(apprise 命令),它属于 Apprise 库(另一仓库),在本机直接发通知、不经过本服务;凡是要「调服务」的场景都走本文的 HTTP 端点。

二、前置条件

2.1 服务可达

curl -s http://127.0.0.1:8000/status
OK

2.2 端点基址与请求约定

本文所有示例基址为 http://127.0.0.1:8000,远程调用换成服务器地址即可。请求体两种形态都支持:HTML 表单(-d 'k=v')或 JSON(-H "Content-Type: application/json" -d '{"k":"v"}')。

2.3 准备通知接收器

为验证通知真实投递,在本机 8433 端口起一个临时 HTTP 接收器(存为 /root/webhook_receiver.py,用 nohup python3 /root/webhook_receiver.py > /var/log/webhook-receiver.log 2>&1 & 后台运行):

from http.server import BaseHTTPRequestHandler, HTTPServer

class H(BaseHTTPRequestHandler):
    def do_POST(self):
        l = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(l)
        print("RECEIVED path=%s body=%s" % (self.path, body.decode()), flush=True)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b"{}")
    def log_message(self, *a):
        pass

HTTPServer(("0.0.0.0", 8433), H).serve_forever()

后文凡涉及投递验证,均以该接收器日志为准。

三、API 总览

Apprise API 是 REST 风格的 HTTP 接口,无独立版本前缀(v2.0.2 的全部端点直接挂在根路径下)。按职能分四域:

域端点方法用途
状态与元信息/status、/status/{key}GET服务健康检查(JSON/文本双格式)
状态与元信息/detailsGETApprise 库版本与全部通道 schema 清单
状态与元信息/metricsGETPrometheus 指标
状态与元信息/qr/{key}GETApprise Mobile 扫码接入元数据
配置管理/add/{key}POST保存/覆盖配置键
配置管理/cfg、/cfg/{key}GET配置键清单(JSON)/ Web 管理页(HTML)
配置管理/get/{key}POST取配置原文
配置管理/json/urls/{key}GET取配置的结构化 JSON
配置管理/move/{key}POST重命名配置键
配置管理/del/{key}POST删除配置键
通知发送/notifyPOST无状态发送(请求体携带 URL)
通知发送/notify/{key}POST有状态发送(引用配置键,支持 tag 路由)
认证/auth/{key}POST设置键级访问凭据

通用通知参数(/notify 系列):title(标题)、body(正文)、type(info/success/warning/failure,默认 info)、format(text/markdown/html)、tag(标签过滤,见 7.3)。无状态 /notify 额外用 urls 字段指定目标。

认证方式:可选全局 Basic Auth(环境变量开启,见第四章);无认证时全部端点开放。限流:v2.0.2 未内置限流,需前置反代自行控制。

四、认证与首次调用

4.1 默认无认证

出厂默认所有端点无认证,直接调用即可(第三章各表均可裸调)。这也是必须尽快开启认证的原因——任何能访问 8000 端口的人都能借你的通道发通知。

4.2 开启全局 Basic Auth(管理员)

在环境文件追加三个变量并重启(演示账号 admin / q1w2e3r4;变量详解见本专栏《Apprise API 2.0 配置参数详解》):

sudo tee -a /etc/apprise-api.env <<'EOF'
APPRISE_AUTH_REQUIRED=yes
APPRISE_USER=admin
APPRISE_PASSWORD=q1w2e3r4
EOF
sudo systemctl restart apprise-api

开启后无凭据访问返回 401:

curl -s http://127.0.0.1:8000/status
curl -s -u admin:q1w2e3r4 http://127.0.0.1:8000/status
Access Denied
OK

4.3 键级认证(/auth/{key})

每个配置键可再设独立凭据,请求体必须是 JSON(form 形态不生效):

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"user":"keyuser","password":"q1w2e3r4"}' \
  http://127.0.0.1:8000/auth/myalerts
{"error": null, "auth_state": "user"}

⚠️ 注意(v2.0.2 实测行为):键级 user 凭据不能用于 API 调用——用 keyuser:q1w2e3r4 调 /notify/myalerts、/status/myalerts 均返回 401 Access Denied。键级凭据目前只约束 Web 配置管理器中该键的视图;程序对接一律用 4.2 的管理员 Basic Auth,它是全功能通道。

未开启认证模式时调 /auth/{key} 会明确拒绝:

Authentication mode is disabled

五、状态与元信息域

5.1 GET /status —— 服务健康检查

默认返回纯文本,加 Accept: application/json 得结构化状态:

curl -s -H "Accept: application/json" http://127.0.0.1:8000/status
{"config_lock": false, "attach_lock": false, "stateful_enabled": true, "stateless_enabled": true, "degraded": false, "max_attachments": 6, "attach_size": 209715200, "status": {"persistent_storage": true, "can_write_config": true, "can_write_attach": true, "details": ["OK"]}, "privilege": "admin"}

关键字段:details: ["OK"] 为健康结论;stateful_enabled/stateless_enabled 标示双模可用性;config_lock/attach_lock 为 true 时表示对应功能被冻结;attach_size 是附件上限字节数(默认 209715200 = 200MB);privilege 反映当前凭据级别(无认证时为 admin)。

5.2 GET /status/{key} —— 配置键健康检查

curl -s http://127.0.0.1:8000/status/myalerts
OK

5.3 GET /details —— 版本与通道清单

默认返回 HTML 页面;加 Accept: application/json 返回 Apprise 库版本与全部支持通道的 schema 模板:

curl -s -H "Accept: application/json" http://127.0.0.1:8000/details
{"version": "2.1.0", "schemas": [{"service_name": "46elks", "service_url": "https://46elks.com", "setup_url": "https://appriseit.com/services/46elks/", "details": {"templates": ["{schema}://{user}:{password}@{from_phone}", "{schema}://{user}:{password}@{from_phone}/{targets}"], ...

(输出节选:实测完整 JSON 含 100+ 通道的模板定义,共数万个字符。)该端点可程序化回答「这个服务支持哪些通道、URL 怎么拼」。

5.4 GET /metrics —— Prometheus 指标

curl -s http://127.0.0.1:8000/metrics | grep -E '^apprise_django' | head -4
apprise_django_http_requests_before_middlewares_total 1.0
apprise_django_http_requests_before_middlewares_created 1.7928988484512937e+09
apprise_django_http_responses_before_middlewares_total 0.0
apprise_django_http_responses_before_middlewares_created 1.7928988484513123e+09

由 django-prometheus 提供,含请求计数、延迟直方图(apprise_django_http_requests_latency_including_middlewares_seconds_bucket)等,可直接被 Prometheus 抓取。

5.5 GET /qr/{key} —— Apprise Mobile 扫码元数据

curl -s http://127.0.0.1:8000/qr/myalerts
{"url": "apprise://127.0.0.1/myalerts", "uses_admin_credentials": false, "password_required": false}

返回手机端接入所需的连接元数据(Web 管理器页面据此渲染二维码);官方 Android 应用 Apprise Mobile 扫码后即可以该键发通知。

六、配置管理域

6.1 POST /add/{key} —— 保存配置

表单形态用 urls 字段(多条 URL 用逗号或换行分隔):

curl -s -X POST -d 'urls=json://127.0.0.1:8433/hook' http://127.0.0.1:8000/add/d5form
Successfully saved configuration

JSON 形态等价(响应也是 JSON):

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"urls": "json://127.0.0.1:8433/hook"}' \
  http://127.0.0.1:8000/add/myalerts
{"error": null}

同键重复 POST 为覆盖语义。配置以纯文本落盘(simple 模式下 /var/lib/apprise/config/{key}.cfg),服务重启后仍在。

6.2 GET /cfg —— 配置键清单

curl -s -H "Accept: application/json" http://127.0.0.1:8000/cfg
["myalerts"]

GET /cfg/{key} 返回的是 Web 配置管理页(text/html),程序化处理请用 6.4 的 /json/urls/{key}。

6.3 POST /get/{key} —— 取配置原文

注意该端点只接受 POST(GET 返回 405)。空 body 返回配置原文(text/plain):

curl -s -X POST http://127.0.0.1:8000/get/myalerts
json://127.0.0.1:8433/hook?method=POST&overflow=upstream&retry=0&wait=0.5&optional=no

方法与否决行为实测:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8000/get/myalerts
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1:8000/get/nonexist
405
204

(GET 405 Method Not Allowed;键不存在返回 204 无内容。)

6.4 GET /json/urls/{key} —— 结构化配置

curl -s http://127.0.0.1:8000/json/urls/myalerts
{"tags": [], "urls": [{"id": "d5ce4bba", "service_name": "JSON", "enabled": true, "url": "json://127.0.0.1:8433/hook?method=POST&overflow=upstream&retry=0&wait=0.5&optional=no", "retry": 0, "optional": false, "tags": [], "tag_details": [], "template": {}}]}

每条 URL 带 service_name(解析出的通道类型)、enabled、retry、tags 等结构化字段,是程序读取配置的正确入口。键不存在同样返回 204。

6.5 POST /move/{key} —— 重命名配置键

需同时给 from 与 to 两个表单字段:

curl -s -X POST -d 'from=d5form&to=d5moved' http://127.0.0.1:8000/move/d5form
Successfully moved configuration

/cfg 清单立即反映新键名。

6.6 POST /del/{key} —— 删除配置键

curl -s -X POST http://127.0.0.1:8000/del/d5moved
Successfully removed configuration

删除同时清理落盘的 {key}.cfg 文件,不可恢复,生产环境调用前建议先 POST /get/{key} 留档。

七、通知发送域

7.1 无状态发送:POST /notify

请求体直接携带目标 URL,无需任何预存配置,即发即走:

curl -s -X POST -d 'urls=json://127.0.0.1:8433/webhook&title=Test Title&body=hello apprise&type=success' \
  http://127.0.0.1:8000/notify
2026-10-25 03:24:24,324 - INFO - Notifying 1 service(s).
2026-10-25 03:24:24,328 - INFO - Sent JSON POST notification.

接收器确认投递内容(type 映射为通知级别):

RECEIVED path=/webhook body={"version": "1.0", "title": "Test Title", "message": "hello apprise", "attachments": [], "type": "success"}

多通道群发:urls 字段写多条 URL(逗号分隔)即可一次投递多个通道。

7.2 有状态发送:POST /notify/{key}

引用预存配置键,调用方与通道解耦——通道变更只改服务端配置,不动业务代码:

curl -s -X POST -d 'body=via saved key' http://127.0.0.1:8000/notify/myalerts
2026-10-25 03:52:36,757 - INFO - Notifying 1 service(s).
2026-10-25 03:52:36,762 - INFO - Sent JSON POST notification.

键不存在返回 404:

curl -s -o /dev/null -w '%{http_code}\n' -X POST -d 'body=x' http://127.0.0.1:8000/notify/nonexist
404

7.3 标签路由(tag)

一个配置键下可保存多条 URL 并分别打标签,发送时按标签选子集。打标签必须用 config 字段传文本格式 标签=URL(urls 字段中的 tag 会被剥离、不生效):

curl -s -X POST --data-urlencode 'config=ops=json://127.0.0.1:8433/hook' http://127.0.0.1:8000/add/d5tag
Successfully saved configuration

结构化读取确认标签已挂上:

curl -s http://127.0.0.1:8000/json/urls/d5tag
{"tags": ["ops"], "urls": [{"id": "d5ce4bba", "service_name": "JSON", "enabled": true, "url": "json://127.0.0.1:8433/hook?method=POST&overflow=upstream&retry=0&wait=0.5&optional=no", "retry": 0, "optional": false, "tags": ["ops"], "tag_details": [{"name": "ops", "priority": 0, "token": "ops", "exact": "0:ops"}], "template": {}}]}

发送行为(v2.0.2 实测,最容易踩的坑):

curl -s -X POST -d 'body=no-tag test' http://127.0.0.1:8000/notify/d5tag
curl -s -X POST -d 'body=tag-ops test' 'http://127.0.0.1:8000/notify/d5tag?tag=ops'
curl -s -X POST -d 'body=nomatch test' 'http://127.0.0.1:8000/notify/d5tag?tag=nomatch'
One or more notification could not be sent
2026-10-25 03:49:04,199 - INFO - Notifying 1 service(s).
2026-10-25 03:49:04,203 - INFO - Sent JSON POST notification.
One or more notification could not be sent

结论:配置键内全部 URL 都带标签后,不带 tag 的发送会失败(没有匹配任何通道);tag=ops 命中投递,tag=nomatch 同样失败。要发全体用 tag=all。设计键内通道时务必想清楚标签策略:要么全键无标签,要么发送方显式带 tag。

7.4 消息类型与正文格式

type 取 info/success/warning/failure(影响通道侧展示样式,如颜色);format 取 text/markdown/html,可用查询参数或表单字段传入:

curl -s -X POST 'http://127.0.0.1:8000/notify/myalerts?format=markdown' \
  --data-urlencode 'body=**bold** and [link](https://www.quzuo.net)'
2026-10-25 03:52:52,984 - INFO - Notifying 1 service(s).
2026-10-25 03:52:52,986 - INFO - Sent JSON POST notification.

接收器可见正文原文透传(markdown 渲染由目标通道各自完成):

RECEIVED path=/hook body={"version": "1.0", "title": "", "message": "**bold** and [link](https://www.quzuo.net)", "attachments": [], "type": "info"}

7.5 附件上传

multipart 表单用 attach 字段带文件(可多个),附件随通知投递到支持附件的通道;json:// 通道以 base64 内联呈现:

echo 'attachment demo content' > /tmp/demo.txt
curl -s -X POST -F attach=@/tmp/demo.txt -F title='Attach Demo' -F body='with attachment' \
  http://127.0.0.1:8000/notify/myalerts
2026-10-25 03:49:15,970 - INFO - Notifying 1 service(s).
2026-10-25 03:49:15,972 - INFO - Sent JSON POST notification.

接收器收到的附件结构:

RECEIVED path=/hook body={"version": "1.0", "title": "Attach Demo", "message": "with attachment", "attachments": [{"filename": "demo.txt", "base64": "YXR0YWNobWVudCBkZW1vIGNvbnRlbnQK", "mimetype": "text/plain"}], "type": "info"}

限制:单请求最多 6 个附件、合计 200MB(默认值,见《Apprise API 2.0 配置参数详解》5.3)。

7.6 错误码速查

状态码场景响应体
200成功OK / Successfully ... / JSON
204配置键不存在(get/json/urls 系)空
401认证缺失或凭据错误Access Denied
404通知键不存在(notify 系)空
405方法不允许(如 GET /get/{key})HTML 错误页
200 但投递失败通道不可达/标签未匹配One or more notification could not be sent

⚠️ 注意最后一行:投递失败仍返回 HTTP 200,错误只在响应体文本里。程序对接时必须检查响应体,不能只看状态码。

八、分页、过滤与排序约定

v2.0.2 无分页/排序参数:/cfg 一次返回全量配置键清单,/json/urls/{key} 一次返回键内全部 URL。配置键数量级在百以内时无压力;唯一的「过滤」机制就是通知发送时的 tag 标签路由(见 7.3)。

九、常见问题

Q1:配置全部打了标签后,普通发送失败? A:v2.0.2 行为如此——键内 URL 全带 tag 时,不带 tag 参数的发送匹配不到任何通道,返回 One or more notification could not be sent。发送方显式带 tag=xxx,或用 tag=all 发全体。

Q2:urls= 里写 tag=ops,json://... 为什么不生效? A:urls 字段不支持标签语法,tag 会被静默剥离。打标签必须用 config 字段传文本格式 ops=json://...(见 7.3)。

Q3:GET /get/{key} 返回 405? A:该端点只接受 POST。取配置原文用 POST /get/{key},取结构化 JSON 用 GET /json/urls/{key}。

Q4:键级凭据调 API 返回 401? A:v2.0.2 实测键级 user 凭据只对 Web 配置管理器生效,API 调用(/notify、/status/{key} 等)一律用全局管理员 Basic Auth(见 4.3 的 ⚠️)。

Q5:响应是纯文本,想要 JSON? A:两处入手——加 Accept: application/json 请求头(/status、/details、/cfg 等支持双格式);或改用专用 JSON 端点(/json/urls/{key}、/qr/{key});写操作加 JSON Content-Type 请求头后响应也是 JSON({"error": null})。

Q6:HTTP 200 但通知没收到? A:响应体是 One or more notification could not be sent 即投递失败:先查响应体文本,再查服务日志(journalctl -u apprise-api -n 50 --no-pager),常见原因是目标地址不通、URL 拼写错误(对照 /details 的 schema 模板)或 7.3 的标签问题。

十、参考链接