WisyLink 的 API 让你用代码创建和更新托管网站:上传参考文件,向 POST /chat 发一条文字需求,AI 代理就会构建网站,并托管在独立的 wisylink.com 地址上。带上同一个链接 id 再发消息即可修改。API 与计划共用 5 小时和每周额度。
- 几个 REST 接口就覆盖了完整的生命周期:上传文件、用
POST /chat创建或继续修改网站、轮询状态、列出和删除网站。 POST /chat对话的对象是 Wisy,也就是应用里的那个助手,所以回复可能是一个问题而不是一次构建。开始轮询之前先检查status。- API 密钥在网页端创建,每个密钥都有自己的支出上限,每日、每周或每月最多 $10,并且叠加在计划的额度窗口之上。
- npm 包
@wisylink/cli把同一套接口封装成了命令行工具和 Node 客户端。 - 自定义域名和服务密钥(Stripe、邮件)需要在网页端或手机应用里设置,公开 API 不涉及这些。
能自动化哪些事
API 就是去掉了聊天窗口的聊天。每次 POST /chat 都是发给 Wisy 的一条消息;需求清楚时,AI 构建代理会编写一个服务器端渲染的 Web 应用,部署到 https://<id>.wisylink.com,需求里要求的话,还会带上数据保存、用户账户或文件上传。API 没有模板、主题或页面类型参数。网站的一切,从版块、文案到功能和风格,都写进消息里,就像一个人亲口描述那样。(相关概念见AI 应用生成器是什么。)
基础 URL 是 https://api.wisylink.com。认证方式是请求头 x-api-key: <key> 或 Authorization: Bearer <key>。JSON 接口使用 Content-Type: application/json,时间戳均为毫秒级 Unix 时间。
| 接口 | 方法 | 用途 | 关键字段 |
|---|---|---|---|
/files | POST | 开始上传一个文件 | 传入 name,返回 id |
/files/chunks | POST | 上传文件内容,每次请求最多 4 MB | id,最后一块加 last=true;请求体为原始二进制 |
/files/:id | GET | 读取文件元数据 | content_type、name、size |
/files/:id | DELETE | 删除文件 | 同时从所有链接的 file_ids 中移除 |
/chat | POST | 创建网站(不带 id)或继续修改(带 id) | message,最多 10 个 file_ids;返回 id、url、status、answer |
/links | GET | 列出你的网站,最新的在前 | page、limit(1 到 100);返回 items、total_pages、has_next |
/links/:id | GET | 读取单个网站 | status、url、file_ids |
/links/:id | DELETE | 删除网站及其参考文件 | 返回 {"ok": true} |
公开 API 做不了的事:设置网站收款或发邮件所需的密钥(由所有者在“集成”里填写)、绑定自定义域名、读写网站保存的数据,以及导出源代码。
获取 API 密钥,设置每个密钥的支出上限
- 在 wisylink.com 登录。密钥只能在网页端创建,手机应用里不行。
- 打开账户里的“API 密钥”,点击“生成 API 密钥”。
- 按用途给密钥命名,比如“acme-landing-pages-ci”,这样撤销时就知道哪里会受影响。
- 设置窗口和上限。选择每日、每周或每月,再设一个以美元计的支出上限,每个窗口最多 $10。窗口按 UTC 日、从周一开始的周或自然月计算。
- 立刻复制密钥。它只显示一次。把它存进你的密钥管理工具或 CI 的机密变量,比如命名为
WISYLINK_API_KEY。
这个上限是安全阀,不是你的计划。每个请求同时还会消耗账户的 5 小时和每周滚动窗口,也就是网页端和手机端聊天共用的那两个窗口,按请求触发的 AI 工作量计量,包括读取你的参考文件。上限在每次请求之前检查,支出在请求之后记录,所以一个窗口里的最后一个请求可能会略微超出。撤销密钥会立即删除它,之后仍在使用它的请求都会收到 401。
免费计划能用 API 吗?能。在 Community 计划上,规则和应用里一样:每个 5 小时窗口构建一次,网站保留 30 天,再标记待删除一周。这足以做出一个集成原型;要承接客户项目或批量任务,付费计划能给你更多额度、并行构建,以及在订阅期间一直在线的链接。
上传参考文件(分块上传)
参考文件就是希望代理阅读或放到网站上的任何东西:品牌规范、logo、产品照片、价目表。支持的格式有 JPEG、PNG、WebP、GIF、HEIC、SVG、MP3、MP4、PDF、XLSX、DOCX、CSV、TXT、JSON 和 HTML,每个最大 25 MB。真实类型根据文件内容识别,空文件会被拒绝。
上传分两步。先创建文件,记下返回的 id:
curl -s -X POST https://api.wisylink.com/files -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/json" -d '{"name":"brand-guide.pdf"}'
再发送文件内容。4 MB 及以下的文件可以一次发完,并带上 last=true:
curl -s -X POST "https://api.wisylink.com/files/chunks?id=$FILE_ID&last=true" -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/octet-stream" --data-binary @brand-guide.pdf
更大的文件先切分(split -b 4m brand-guide.pdf part_),按顺序把各块发到同一个 id,只在最后一块加上 last=true;这次调用会完成上传并处理文件。上传必须在 15 分钟内完成,否则会话过期。在 Node 里,下文介绍的客户端会替你自动分块。
用 POST /chat 创建网站,等待上线地址
发送需求说明
不传 id 就会新建网站。消息最长 5,000 个字符,足够写一份像样的需求说明:用途、受众、版块、真实文案、功能、风格和语言。结尾加一句“我没写到的地方,请自行选择合理的默认方案”,第一次调用就开始构建的可能性会更大。把 FILE_ID 换成上传得到的 id。
curl -s -X POST https://api.wisylink.com/chat -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/json" -d '{"message":"为 Ember 做一个单页落地网站,它是新加坡的一家精品咖啡烘焙坊。版块:首屏大图、三款带价格的单一产区咖啡、批发询价表单(提交内容保存到管理后台)、营业时间、地图链接。颜色和字体参照附件中的品牌规范。我没写到的地方,请自行选择合理的默认方案。","file_ids":["FILE_ID"]}'
在 Node 里用 fetch 发同样的请求:
const res = await fetch("https://api.wisylink.com/chat", { method: "POST", headers: { "x-api-key": process.env.WISYLINK_API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ message: brief, file_ids: [fileId] }) }); let link = await res.json();
新建网站会返回 201,包含 id、url、status、answer、created_at 和 updated_at。把 id 保存好:以后修改、读取或删除网站都靠它。把它当作不透明字符串处理,不要校验它的格式。
轮询之前先看状态
POST /chat 响应里的 status 会告诉你构建是否真的开始了:
building或queued- 构建正在运行,或在等待空闲名额(
queued还没写进参考文档的状态列表,但实际会出现)。开始轮询。对新网站来说,首次构建完成前,url会显示一个“构建中”页面。 - 新网站返回
idle - 没有开始构建。Wisy 先回复了你,
answer里通常是一个简短的问题,比如要用哪家支付服务商。带上同一个id再发一次POST /chat回答即可。 - 继续修改后马上返回
completed或aborted - 对已有网站来说,这个状态反映的是最近一次构建的结果。如果它没有变成
building,说明你的消息得到的是一条回复,而不是一次构建;去读answer。
轮询到构建结束
API 没有 Webhook,所以要轮询 GET /links/:id。构建以分钟计,而不是以秒计,每 15 到 30 秒查一次就足够了。除了 completed、aborted 和 idle,其他状态一律当作仍在运行,这样即使以后出现新的进行中状态,你的循环也不会出错:
const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); while (!["completed", "aborted", "idle"].includes(link.status)) { await sleep(20000); link = await (await fetch(`https://api.wisylink.com/links/${link.id}`, { headers: { "x-api-key": process.env.WISYLINK_API_KEY } })).json(); }
status 为 completed 时,url 就是你的在线网站。aborted 表示构建在完成前停止了;已经上线的网站会保留之前的版本,再发一条消息就会重试。如果网站之后绑定了自定义域名,url 会返回那个域名。构建的完整报告,包括网站是否还在等待 Stripe 或邮件密钥的提示,可以在网页端该链接的对话里查看。
继续修改、列出和删除链接
要修改网站,只需发送新的指令,并把 LINK_ID 换成它的 id;服务器会保留对话历史,继续修改的请求返回 200:
curl -s -X POST https://api.wisylink.com/chat -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/json" -d '{"id":"LINK_ID","message":"新增第二家门店:如切路 412 号,每天 7:00 至 15:00 营业。"}'
然后照样轮询。每次修改都是一次新的构建:失败的构建会让上一个正常版本继续在线,成功的构建一完成就立即上线,所以每次修改后都要跑一遍检查。除非新消息是要纠正正在运行的构建,否则等上一个构建结束后再发下一条修改。
要列出网站,就从 GET /links?page=1&limit=100 开始逐页读取,直到 has_next 为 false。要删除网站,DELETE /links/:id 会删除网站和附在它上面的参考文件。它用过的自定义域名会留在你的账户里,可以分配给别的网站。
CLI 与 Node 客户端
@wisylink/cli 包(MIT 许可,需要 Node 18.17 或更高版本)的命令与上面的接口一一对应,是在 Shell 或 CI 任务里调用 WisyLink 的最快方式:
- 先
npm i -g @wisylink/cli,再export WISYLINK_API_KEY=...,或者在每条命令里用--api-key传入。 wisylink files upload ./brand-guide.pdf会自动按 4 MB 分块上传。wisylink chat --message "为 Ember 咖啡做一个落地页。" --file-id FILE_ID创建网站。wisylink links list --page 1 --limit 50列出你的网站。
命令输出 JSON,可以用 jq 取出 id 或 url。--timeout 接受 1,000 到 120,000 毫秒;调用 chat 时把它调大,因为它要等 Wisy 回复。
同一个包还导出了一个 Node 客户端:import { CreateWisyLinkClient } from "@wisylink/cli"; const client = CreateWisyLinkClient({ apiKey: process.env.WISYLINK_API_KEY }); const file = await client.uploadFile("./brand-guide.pdf"); const link = await client.chat({ message: brief, fileIds: [file.id] });
截至 npm 发布的 0.2.1 版本,有两点版本说明。第一,需要传入链接 id 的命令和客户端方法(chat --link-id、links get、links delete,以及 Node 里的 linkId、getLink、deleteLink)会按旧的 id 格式校验,从而拒绝当前的 id,所以继续修改、读取和删除网站请按上文用 HTTP 调用。第二,CLI 文档(英文)已经介绍了一个更新的版本,带有浏览器登录(wisylink login)、能实时显示构建进度的交互式对话,以及 --json 参数;运行 wisylink --version 看看你装的是哪个版本。
限制、错误与最佳实践
错误以 JSON 返回,带有 error 错误码。值得专门处理的有这些:
429 limit_reached- 计划的 5 小时或每周窗口已用完(
reason为5h_limit或weekly_limit)。按reset_at(毫秒时间戳)安排重试,不要循环重试。 429 credit_limit_exceeded- 这个密钥达到了自己的支出上限。任何接口都可能返回它;等到
resets_at,或者在网页端调高上限(最多 $10)。 429 build_concurrency_limit- 正在运行的构建数超出了你的计划允许的数量。等其中一个结束后再发下一个。
429 rate_limited- 短时间内请求太多。退避后重试。
400 bad_request- JSON 无效、消息为空或超过 5,000 个字符,或者文件 id 不存在(列在
missing_file_ids里)。注意只有前 10 个file_ids会被使用,多出来的会被直接丢弃,不报错。 401、404、500 chat_unavailable- 依次表示:密钥缺失或已撤销;链接或文件不属于你;Wisy 暂时不可用,等一会儿重试一次即可。
能省钱、少踩坑的习惯:
- 密钥只放在服务器端。绝不要把密钥写进浏览器或应用代码。每个客户或每条流水线用一个单独的密钥,这样各自有上限,也能单独撤销。
- 不要盲目重试
POST /chat。它不是幂等的:在你这边超时的请求,可能已经创建了网站或开始了构建。重发之前先查GET /links(最新的在前),并把客户端超时设成一分钟以上。 - 批量任务要排队。同时运行的构建数不要超过计划允许的数量,把
build_concurrency_limit当作等待的信号。 - 上线前先检查。AI 的输出可能有错误。在客户或公众看到之前,打开每个网站,测试表单,通读文案;WisyLink 的条款规定,检查和测试是你的责任。
用例:代理公司落地页、活动微站、内部工具
代理公司的落地页。准备一份需求模板,留出客户名称、卖点、版块和语气的空位,从 CRM 里取数据填进去,再把客户的 logo 和品牌规范作为文件附上。每个推广活动都是一个独立的网站,客户的反馈变成后续消息,每个客户一个密钥,支出互不混淆。页面通过审核后,在“域名”里绑定客户的域名(任何计划都行)。页面本身怎么做,可以看用 AI 做候补名单落地页这个完整示例。
每场活动一个微站。表格里一行一场活动(名称、日期、场地、人数上限),脚本为每场活动创建一个报名网站,并把返回的 id 存在对应的行旁边。每份需求说明该写什么,见用 AI 做活动报名页面。活动结束后,删掉网站,或者在付费计划上保留作为存档。
内部自动化。脚本可以创建内部工具的第一版,比如库存跟踪表或审批看板。但不要靠重新构建来更新数据:让 Wisy 加一个接口,供你的系统写入记录,用你在“集成”里设置的密钥保护起来。这样写入的记录大约一分钟内就能被访客看到,而且不消耗构建。这个模式的更多细节见用 AI 搭建内部工具。
获取密钥,用代码构建第一个网站
免费创建账户,生成一个上限较低的 API 密钥,然后用上面的 curl 命令发送您的第一份需求说明。字段级细节请随时查看 API 参考(英文);当集成从原型走向生产时,到价格页面选一个构建额度和并行构建数都够用的计划。
F.A.Q.
