Schwab API 代理

一个固定地址 + 一个密码,直接调 Schwab 官方接口。token 由本服务托管并自动续期。

已授权access_token 剩余 0 分钟刷新令牌剩余 5.4 天重新授权
access_token 已过期,下次请求会自动刷新,无需处理。
最近一次刷新失败:2026-10-05T12:00:39.737Z 定时刷新失败: refresh 失败 400: {"error":"unsupported_token_type","error_description":"400 Bad Request: \"{\"error_description\":\"Refresh token is invalid, expired or revoked\",\"error\":\"invalid_grant\"}\""}
刷新机制正常。上次成功刷新:2026-10-04 07:25 UTC · 累计 354 次

1 · 快速开始

  1. 从项目 README.md 拿到密码。
  2. 用任意一个代码示例调用(把密码放进 X-API-Key 请求头)。
  3. 把 /api/ 后面的路径,原样换成 Schwab 官方文档里的路径。
密码为什么不出现在本页?本页是公开的(免鉴权),谁打开都能看见;不放明文可以更隐蔽。密码记录在项目 README.md 中,在本页下方的自测框里输入一次,浏览器会替你记住。

当前地址:https://schwab-proxy.365200.xyz 回调:/callback

2 · 鉴权方式

三种都支持,推荐第一种:

方式写法备注
请求头X-API-Key: <密码>推荐,无转义问题
BearerAuthorization: Bearer <密码>和官方风格一致
查询参数?api_key=<密码>必须 URL 编码,见下
查询参数要小心。若密码本身含 & + % 等字符,不编码时 & 会被当成参数分隔符、把密码截断(历史踩坑)。当前密码是纯字母数字,暂不受影响;换密码时若含特殊字符,请把密码做 URL 编码后再放进 ?api_key=。

3 · 接口对照

左边是官方路径,右边是经本代理的写法。前缀 /api 后的路径会原样转发(版本号 /v1 自动补全)。

用途调用
账户与持仓GET /api/trader/accounts?fields=positions
单账户详情GET /api/trader/accounts/{accountHash}
订单列表GET /api/trader/accounts/{accountHash}/orders
下单 / 撤单POST|DELETE /api/trader/accounts/{accountHash}/orders
交易者信息GET /api/trader/userPreference
实时报价GET /api/marketdata/quotes?symbols=AAPL,MSFT
历史K线GET /api/marketdata/pricehistory?symbol=AAPL&periodType=day
期权链GET /api/marketdata/chains?symbol=AAPL
行情快照GET /api/marketdata/AAPL?fields=quote,fundamental

完整清单见 Schwab 开发者文档。

4 · 代码示例

curl

BASE='https://schwab-proxy.365200.xyz'
KEY='<密码>'

curl -H "X-API-Key: $KEY" "$BASE/api/trader/accounts?fields=positions"
curl -H "X-API-Key: $KEY" "$BASE/api/marketdata/quotes?symbols=AAPL"

Python

import requests

BASE = "https://schwab-proxy.365200.xyz"
HEAD = {"X-API-Key": "<密码>"}

r = requests.get(BASE + "/api/marketdata/quotes",
                 params={"symbols": "AAPL"}, headers=HEAD)
r.raise_for_status()
print(r.json())

Node.js

const BASE = "https://schwab-proxy.365200.xyz";
const HEAD = { "X-API-Key": "<密码>" };

const r = await fetch(BASE + "/api/marketdata/quotes?symbols=AAPL", { headers: HEAD });
console.log(await r.json());

5 · 辅助端点

端点作用需密码
GET /本手册页否
GET /login跳转 Schwab 授权否
GET /health健康检查否
GET /api/token查看 token 剩余有效期是
POST /api/refresh强制立即刷新是

在线自测

密码填在这里,只存进你自己浏览器的 localStorage,页面源码里不含明文。

等待测试…

6 · 常见返回与处理

现象原因与处理
401 unauthorized密码错或没带。检查 X-API-Key 头;用查询参数时确认已 URL 编码。
500 尚未授权token 没换到。打开 /login 走一遍授权。
Schwab 返回 404路径拼错。核对官方文档的完整路径与参数名。
Schwab 返回 429触发限频。稍后重试,官方限额 120 次/分钟。
浏览器 302 跳 cloudflareaccess.com该域名被 Cloudflare Access 圈住了,删掉对应 Access 应用即可。
redirect_uri mismatch授权页报这个,说明你点 /login 所在域名与 Schwab 后台登记的回调地址不一致。改在登记的那个域名上点授权即可(本服务的 redirect_uri 会自动跟随当前域名)。
curl 报 000 超时只发生在旧地址 *.workers.dev(解析到 199.16.156.75,本机直连不通)。改用正式域名 schwab-proxy.365200.xyz 即可直连;若坚持用旧地址,需加 --proxy http://127.0.0.1:7897。

7 · 授权与续期

正常情况下永远不需要手动重新授权。Schwab 的刷新令牌 7 天滚动有效 —— 每次刷新都会下发新令牌并把有效期重置回 7 天;本服务每 2 天自动刷新一次,7 天窗口内有 3 次重试机会。

只有这三种情况需要重做授权:连续 7 天刷新全失败、你改了 Schwab 密码、或撤销了本应用的第三方授权。本页顶部的徽章与告警会实时反映刷新健康度。

重新授权时,请在「Schwab 后台登记了回调地址的那个域名」上打开 /login;本服务的回调地址会自动跟随当前域名,因此两个域名都能用,只要别交叉着用就行。

8 · 安全与维护

项说明
client_secret存在 Worker 加密 Secret,不在代码与 KV 中
密码比对恒定时间算法,防时序侧信道
本页是否暴露密码否。本页免鉴权、公开可见,但正文与源码都不含密码明文;自测框里填的值只存于你自己的浏览器 localStorage

换密码

cd C:/Users/a4487/WorkBuddy/schwab-proxy
printf '%s' '新密码' | npx wrangler@3 secret put PROXY_PASSWORD

查看实时日志

cd C:/Users/a4487/WorkBuddy/schwab-proxy
export CLOUDFLARE_API_TOKEN=<token> CLOUDFLARE_ACCOUNT_ID=8e43ef2043266e0898cf9e02ca53df2f
npx wrangler@3 tail

源码与完整文档:C:\Users\a4487\WorkBuddy\schwab-proxy · 自检脚本 bash smoke.sh