API REFERENCE

开发文档

Y-Send 只有一个核心接口,与 ServerChan 协议完全兼容。所有能发起 HTTP 请求的语言和工具都可以调用。

快速开始

1. 打开 控制台 注册账号,系统会自动分配一个 SendKey。

2. 在控制台为 SendKey 配置消息通道(企业微信 / 钉钉 / 飞书群机器人 webhook)。

3. 把下面 URL 中的 <SENDKEY> 换成你自己的,粘贴到浏览器地址栏即可收到第一条消息:

https://push.example.com/<SENDKEY>.send?title=你好&desp=这是第一条消息

发送消息

GET 或 POST  https://push.example.com/<SENDKEY>.send

支持三种传参方式:GET query、POST 表单(application/x-www-form-urlencoded)、POST JSON。

参数必填说明
title消息标题,最长 32 字符,超长截断,缺省为「无标题」
desp消息正文,最长 32KB,企业微信 / 钉钉通道支持 Markdown
idempotency_key幂等键(也可用 Idempotency-Key 请求头,头优先)。1~128 字符、不含控制字符;同一 SendKey + 同一键的重复请求不会重复投递外部通道
⚠ URL 中的中文需要百分号编码(浏览器和绝大多数 HTTP 库会自动处理)。

投递语义

每条消息带 delivery 状态:success(全部通道成功或仅站内保存)/ failed(结果已落盘,有通道失败)/ pending(投递结果未落盘的中间态)/ unknown(结果无法确认)。响应 data.delivery 可读取该状态。

成功响应

{"code":0,"message":"","data":{"pushid":"8f3ad2...","readkey":"","error":"SUCCESS","errno":0,"delivery":"success"}}

通道投递失败响应

只要有一个已配置通道投递失败(网络错误、超时、HTTP 非 2xx、平台错误码、重定向),响应就是非 0 状态,不会伪装成 SUCCESS。调用方应据此重试(建议携带幂等键):

{"code":40004,"message":"通道投递失败:webhook","data":{
  "pushid":"8f3ad2...","error":"CHANNEL_FAILED","errno":40004,"delivery":"failed",
  "results":{"webhook":{"ok":false,"status":500,"error":"http_500"}}}}

投递状态未知响应

外部投递已发生但结果未能落盘(或进程在结果落盘前崩溃)时返回,不会伪装成可安全重试的普通错误:

{"code":40006,"message":"投递结果持久化失败……","data":{
  "pushid":"8f3ad2...","error":"DELIVERY_UNKNOWN","errno":40006,"delivery":"unknown"}}

错误码

code含义
0成功
40001SendKey 不正确或不存在
40002超过每分钟请求上限
40003超过每日请求上限
40004一个或多个通道投递失败,data.results 含各通道结果,调用方应重试
40005触发按 IP+SendKey 的限流(默认 60 条/分钟),请求未写入消息、未计数、未投递
40006DELIVERY_UNKNOWN:投递状态未知(外部通道可能已收到),携带相同幂等键重试不会重复投递
40007幂等键非法(超长或含控制字符),请求未执行任何副作用

调用示例

Shell / crontab

# 每天 9:00 汇报磁盘用量
0 9 * * * curl -s "https://push.example.com/<SENDKEY>.send" \
  --data-urlencode "title=磁盘日报" \
  --data-urlencode "desp=$(df -h / | tail -1)"

Python

import requests

requests.post("https://push.example.com/<SENDKEY>.send", data={
    "title": "备份完成",
    "desp": "共写入 2.3GB,耗时 14 分钟",
})

JavaScript / Node.js

await fetch("https://push.example.com/<SENDKEY>.send", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ title: "构建成功", desp: "v2.4.0 已发布" }),
});

第三方工具

在 UptimeKuma、青龙面板、Check酱、短信转发器等工具的 ServerChan 通知配置中,把推送域名换成本站域名、SendKey 换成你的即可。

通道配置

控制台 的 SendKey 卡片中粘贴对应通道的 webhook 地址,保存即生效。一个 SendKey 可配置多个通道,推送时同时投递。通道配置接口严格校验:仅接受 wecom/dingtalk/feishu/webhook 四个键,值必须是字符串(空字符串表示移除该通道),未知通道名或非字符串值一律拒绝且不落盘。

企业微信群机器人(微信中可收)

钉钉群机器人

飞书群机器人

自定义 Webhook

推送时会向该地址发送 POST application/json

{"title":"标题","desp":"正文","time":"2026-01-01T08:00:00.000Z"}

可用它桥接邮件、短信、Bark 或任何云服务。

安全策略:仅允许 http/https 公网地址——localhost、回环、私有网段、链路本地(含云元数据 169.254.169.254)、文档/保留段(192.0.2.0/24、198.51.100.0/24、203.0.113.0/24 等)、IPv6 等价地址全部拒绝;每次发送前重新解析域名并校验全部解析结果,随后把 TCP/TLS 连接固定到已校验的 IP(不存在第二次解析;TLS SNI 与 Host 头保留原始域名);不跟随重定向;默认超时 8 秒。确有内网桥接需求时,运维可通过 WEBHOOK_ALLOWLIST_HOSTS 精确放行指定主机(不匹配同后缀域名)。

使用限制

项目限制
单 SendKey 每分钟请求50 次
单 SendKey 每日请求以控制台显示为准(按 APP_TIMEZONE 时区的自然日重置)
标题长度32 字符
正文长度32 KB
请求体上限64 KB(超限返回 HTTP 413)
消息记录保留每用户最近 200 条(用户间互不影响),全局硬上限 2000 条

服务配置

常用环境变量(完整列表与各配置的取值范围见 README——所有数值配置都有最小/最大值,非法值会拒绝启动)。服务按单实例运行,外部投递、管理写操作和过期清扫共用存储写锁,避免响应与数据文件状态分叉;该写锁不覆盖请求体读取,慢速客户端不会阻塞其他请求:

变量默认值(范围)说明
APP_TIMEZONEAsia/Shanghai每日限额按此时区的自然日计算;显式设置为空/非法时区名拒绝启动
DAILY_LIMIT / MINUTE_LIMIT200 / 50单 SendKey 每日(1~100000)/ 每分钟(1~10000)上限
SESSION_TTL_MS30 天(1 秒~365 天)登录态有效期,过期自动清理;注销/过期删除均为持久化事务
WEBHOOK_TIMEOUT_MS8000(1000~60000)绝对总超时(含 DNS 解析阶段)
WEBHOOK_RESPONSE_LIMIT65536(1KB~1MB)通道响应体上限,超限立即失败
SEND_IP_LIMIT / SEND_IP_WINDOW_MS60 / 60000按 IP+SendKey 限流,超限返回 code 40005
WEBHOOK_ALLOWLIST_HOSTS明确放行的内网 webhook 主机(精确匹配)
TRUSTED_PROXY_IPS可信反向代理 IP;仅可信来源才解析 X-Forwarded-For(空段/非法项整体回退)
ALLOWED_ORIGINS可信跨域 Origin,为空不返回 CORS 头;白名单跨域预检允许 Content-Type、Authorization、Idempotency-Key,并允许读取 X-Idempotent-Replay
COOKIE_SECURE0仅接受 0/1:HTTPS 部署时设为 1;其他显式取值(含空串)拒绝启动