PXAnyAPI 文档
PXANY / API DOCUMENTATION

PXAny 公共 API

面向 Codex、AI Agent、服务端脚本和 PXAny Chrome 扩展的数据接口。 当前提供站点 Analytics、Serp 搜索代理、URL 重定向解析、URL 内容提取、 关键词搜索量、Ahrefs DR、Product Hunt、On Page SEO 检测以及外链发布工作流。

基础地址https://api.pxany.com/v1
数据格式HTTPS / JSON
鉴权方式Bearer API Key
PUBLIC ENDPOINTS

接口总览

以下是当前可直接调用的公共业务接口。管理后台内部路由/api/admin/* 不属于公共 API。

GET/v1/analytics/ga4GA4 流量、渠道和落地页数据需要密钥
GET/v1/analytics/ga4/eventsGA4 各事件的用户数和次数(实时查询,可按维度拆分)需要密钥
GET/v1/analytics/gscGSC 搜索词和页面数据需要密钥
GET/v1/serp通过私有 SerpAPI 账号池代理 Google 搜索需要密钥
GET/v1/trends复用 SerpAPI 账号池查询 Google Trends 趋势、地区热度及相关词需要密钥
GET/v1/ahrefs-domain-rating查询域名或 URL 的 Ahrefs Domain Rating需要密钥
GET/v1/aitdkAITDK domain traffic, Whois, and SEO event data需要密钥
GET/v1/product-hunt/daily-products拉取 Product Hunt 指定日期的全部产品和产品 URL需要密钥
GET/v1/url-redirect解析 HTTP(S) URL 的最终地址和完整跳转链需要密钥
POST/v1/url-content抓取指定 URL 并转换为 Markdown 内容需要密钥
POST/v1/sites创建标准站点需要密钥
GET/v1/sites/lookup按域名查询标准站点需要密钥
PATCH/v1/sites/{siteId}更新标准站点状态需要密钥
GET/v1/landing-pages读取站点内页 URL 结构与近 28 天 GSC 数据需要密钥
PATCH/v1/landing-pages/{pageId}更新内页上线 URL 与生命周期状态需要密钥
GET/v1/domains/check实时查询域名注册状态(RDAP / WHOIS)需要密钥
POST/v1/keyword-volumesGoogle Ads 关键词历史指标需要密钥
GET/POST/v1/chrome2cf/*PXAny 浏览器/扩展采集通道需要密钥
GET/POST/v1/publishing/deliveries/{id}Substack、Medium 与 Beehiiv 冻结文稿、私有配图与一次性发布许可需要密钥
GET/v1/extension/statusPXAny Chrome 扩展连接状态需要密钥
GET/POST/v1/on-page-seo-check/*检测扩展当前标签页,并按 page_id 读取关键词和历史报告需要密钥
GET/PATCH/v1/backlinks/settings外链库筛选组配置需要密钥
POST/v1/backlinks/directory-submissions/plan外链表单分析后生成 AI 填写计划需要密钥
POST/v1/backlinks/submission-guides/generate根据整页内容生成通用外链提交步骤和全部草稿需要密钥
POST/v1/backlinks/directory-submissions/rewrite外链表单单字段按自定义要求重新生成草稿需要密钥
POST/v1/backlinks/campaign-items/{itemId}/*博客评论任务准备、一次性提交许可、结果回写与人工继续需要密钥
GET/POST/PATCH/DELETE/v1/backlinks/*外链目标网站、任务创建、评论生成和结果回写需要密钥
访问边界

外部调用统一走 https://api.pxany.com/v1/*。 扩展不直接访问 Supabase,也不直接调用 Gemini。

AUTHENTICATION

身份鉴权

所有公共业务接口使用同一把私有密钥。请求头必须包含 Bearer Token。

HTTP 请求头
Authorization: Bearer <PXANY_API_KEY>

密钥只保存到服务端、Cloudflare Secret 或所有者本机环境。 示例、日志、文档和仓库中只允许出现占位符。

GET/v1/analytics/ga4 / /v1/analytics/gsc
需要密钥

站点 Analytics

从最近一次同步的数据中读取 GA4 或 GSC 报告。

查询参数

sitestring / 必填

已在 PXAny 中启用的标准站点域名。

daysinteger / 可选

1 到 90 的整数,默认 28。

cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/analytics/ga4?site=<SITE_DOMAIN>&days=28"

curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/analytics/gsc?site=<SITE_DOMAIN>&days=28"
GA4 返回

包含 totals、dailySeries、channelBreakdown 和 topLandingPages。

GSC 返回

包含 totals、dailySeries、topQueries 和 topPages。

GET/v1/analytics/ga4/events
需要密钥

GA4 事件

用 PXAny 的 Google 服务账号实时查询 GA4 Data API,返回每个事件的 去重用户数(totalUsers)和触发次数 (eventCount),用于搭建转化漏斗。事件数据不进入每小时同步, 每次请求都会访问 GA4。时间范围截至 UTC 昨天,共 days 天。

查询参数

sitestring / 必填

已在 PXAny 中启用且配置了 GA4 的标准站点域名。

daysinteger / 可选

1 到 90 的整数,默认 28。

eventsstring / 可选

逗号分隔的事件名,最多 30 个;不传则返回全部事件。

breakdownstring / 可选

额外拆分维度,只能选一个:date、sessionDefaultChannelGroup、deviceCategory、country、landingPage,或customEvent:<参数名>。自定义维度必须先在 GA4 媒体资源中注册,否则返回 400。

cURL
curl --fail-with-body --get "https://api.pxany.com/v1/analytics/ga4/events" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  --data-urlencode "site=<SITE_DOMAIN>" \
  --data-urlencode "days=28" \
  --data-urlencode "events=page_view,offer_viewed,begin_checkout,purchase" \
  --data-urlencode "breakdown=customEvent:offer_surface"
200 返回

events 按用户数从高到低排列,用户数在每个事件内由 GA4 去重;breakdown.rows 是事件 × 维度值的明细,行数超过 10,000 时truncated 为 true。不要把拆分行的用户数相加当作事件总用户数。

JSON
{
  "source": "ga4",
  "site": {
    "id": 1,
    "slug": "example.com",
    "name": "Example",
    "domain": "example.com",
    "timezone": "UTC"
  },
  "range": {
    "days": 28,
    "start": "2026-10-09",
    "end": "2026-11-05"
  },
  "events": [
    {
      "eventName": "page_view",
      "totalUsers": 30251,
      "eventCount": 50918
    },
    {
      "eventName": "offer_viewed",
      "totalUsers": 2100,
      "eventCount": 4300
    },
    {
      "eventName": "begin_checkout",
      "totalUsers": 60,
      "eventCount": 75
    },
    {
      "eventName": "purchase",
      "totalUsers": 18,
      "eventCount": 20
    }
  ],
  "breakdown": {
    "dimension": "customEvent:offer_surface",
    "truncated": false,
    "rows": [
      {
        "eventName": "offer_viewed",
        "value": "pricing",
        "totalUsers": 900,
        "eventCount": 1500
      }
    ]
  },
  "generatedAt": "2026-11-06T08:00:00.000Z"
}
错误响应

400:参数不合法或自定义维度未注册;401:密钥无效;404:站点不存在或未配置 GA4; 502:GA4 Data API 请求失败。

JSON
{
  "type": "https://api.pxany.com/errors/invalid-request",
  "title": "Invalid request",
  "status": 400,
  "detail": "GA4 rejected breakdown customEvent:offer_surface. Custom dimensions must be registered in the GA4 property first.",
  "requestId": "example-request-id"
}
GET/v1/ahrefs-domain-rating
需要密钥

Ahrefs Domain Rating

查询域名或 URL 当前的 Ahrefs DR。

查询参数

targetstring / 必填

目标域名或 HTTP(S) URL,例如 example.com。

cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/ahrefs-domain-rating?target=example.com"
GET/v1/aitdk
Requires API key

AITDK

Proxy the former Cloudflare aitdk Worker through PXAny. The default response parses AITDK SSE events and also includes the raw upstream stream text.

Query parameters

domainstring / required

Domain or HTTP(S) URL, for example htmltourl.com.

formatjson | sse / optional

Defaults to json. Use sse to stream the upstream event stream.

nonce / signature / timestampoptional

Omit these to let PXAny sign the upstream AITDK request with its stored API Account. Provide all three to forward a pre-signed request.

cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/aitdk?domain=htmltourl.com"
Full parsed response
{
  "data": {
    "whois": {
      "domain": "htmltourl.com",
      "data": {
        "objectClassName": "domain",
        "handle": "3098391454_DOMAIN_COM-VRSN",
        "ldhName": "HTMLTOURL.COM",
        "links": [
          {
            "value": "https://rdap.verisign.com/com/v1/domain/HTMLTOURL.COM",
            "rel": "self",
            "href": "https://rdap.verisign.com/com/v1/domain/HTMLTOURL.COM",
            "type": "application/rdap+json"
          },
          {
            "value": "https://rdap.namecheap.com/domain/HTMLTOURL.COM",
            "rel": "related",
            "href": "https://rdap.namecheap.com/domain/HTMLTOURL.COM",
            "type": "application/rdap+json"
          }
        ],
        "status": ["client transfer prohibited"],
        "entities": [
          {
            "objectClassName": "entity",
            "handle": "1068",
            "roles": ["registrar"],
            "links": [
              {
                "href": "http://www.namecheap.com",
                "type": "text/html",
                "value": "https://rdap.namecheap.com/",
                "rel": "about"
              }
            ],
            "publicIds": [
              {
                "type": "IANA Registrar ID",
                "identifier": "1068"
              }
            ],
            "vcardArray": [
              "vcard",
              [
                ["version", {}, "text", "4.0"],
                ["fn", {}, "text", "NameCheap, Inc."]
              ]
            ],
            "entities": [
              {
                "objectClassName": "entity",
                "roles": ["abuse"],
                "vcardArray": [
                  "vcard",
                  [
                    ["version", {}, "text", "4.0"],
                    ["fn", {}, "text", ""],
                    ["tel", { "type": "voice" }, "uri", "tel:+1.6613102107"],
                    ["email", {}, "text", "abuse@namecheap.com"]
                  ]
                ]
              }
            ]
          }
        ],
        "events": [
          {
            "eventAction": "registration",
            "eventDate": "2026-05-11T19:37:13Z"
          },
          {
            "eventAction": "expiration",
            "eventDate": "2027-05-11T19:37:13Z"
          },
          {
            "eventAction": "last changed",
            "eventDate": "2026-05-11T20:07:52Z"
          },
          {
            "eventAction": "last update of RDAP database",
            "eventDate": "2026-07-21T01:30:35Z"
          }
        ],
        "secureDNS": {
          "delegationSigned": false
        },
        "nameservers": [
          {
            "objectClassName": "nameserver",
            "ldhName": "ROAN.NS.CLOUDFLARE.COM"
          },
          {
            "objectClassName": "nameserver",
            "ldhName": "VAL.NS.CLOUDFLARE.COM"
          }
        ],
        "rdapConformance": [
          "rdap_level_0",
          "icann_rdap_technical_implementation_guide_1",
          "icann_rdap_response_profile_1"
        ],
        "cached": 1785667400864
      }
    },
    "traffic": {
      "domain": "htmltourl.com",
      "data": {
        "hostname": "htmltourl.com",
        "title": "",
        "description": "",
        "cached": 1785667400862,
        "overview": {
          "bounceRate": "0.2031821140725134",
          "month": "6",
          "year": "2026",
          "pagePerVisit": "6.7623626864547965",
          "visits": "7268",
          "timeOnSite": "305.59707482219966",
          "hostname": "htmltourl.com",
          "globalRank": 2034642,
          "countryRank": 31298
        },
        "monthlyVisits": {
          "2026-02-01": 0,
          "2026-03-01": 0,
          "2026-04-01": 0,
          "2026-05-01": 0,
          "2026-06-01": 7268
        },
        "trafficSources": {
          "socialOrganic": 0,
          "socialPaid": 0,
          "mail": 0,
          "referrals": 0,
          "searchOrganic": 0,
          "searchPaid": 0,
          "direct": 0,
          "genAi": 0,
          "affiliate": 0,
          "displayAds": 0
        },
        "trafficSourceTrends": {
          "direct": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          },
          "search": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          },
          "social": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          },
          "referrals": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          },
          "paidReferrals": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          },
          "mail": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          },
          "other": {
            "2026-04-01": 0,
            "2026-05-01": 0,
            "2026-06-01": 0
          }
        },
        "topKeywords": [
          {
            "name": "convert html to url online free",
            "estimatedValue": 90,
            "volume": 340,
            "cpc": null
          },
          {
            "name": "htmltourl",
            "estimatedValue": 70,
            "volume": 160,
            "cpc": null
          },
          {
            "name": "permanent html code to website link converter free",
            "estimatedValue": 50,
            "volume": 240,
            "cpc": null
          },
          {
            "name": "html в url",
            "estimatedValue": 50,
            "volume": 60,
            "cpc": null
          },
          {
            "name": "html code to url converter",
            "estimatedValue": 40,
            "volume": 110,
            "cpc": null
          }
        ],
        "topRegions": [
          {
            "country": 356,
            "name": "India",
            "value": 0.6081085218092226
          },
          {
            "country": 840,
            "name": "United States",
            "value": 0.3630825938044913
          },
          {
            "country": 586,
            "name": "Pakistan",
            "value": 0.028808884386285635
          }
        ],
        "aiTraffic": {
          "trends": []
        }
      }
    },
    "complete": {
      "status": "DONE",
      "duration": 64
    }
  },
  "domain": "htmltourl.com",
  "fetchedAt": "2026-08-02T10:43:21.022Z",
  "ok": true,
  "raw": "event: whois\ndata: {...}\n\nevent: traffic\ndata: {...}\n\nevent: complete\ndata: {...}\n\n",
  "source": "aitdk",
  "status": 200
}
Server-side signing

Callers only need PXANY_API_KEY and domain. PXAny generates the AITDK nonce, timestamp, and signature on the server.

GET/v1/product-hunt/daily-products
需要密钥

Product Hunt

每天通过 Product Hunt 官方 v2 GraphQL API 拉取指定日期的全部产品, 重点返回每个产品的官网 URL。

查询参数

dateYYYY-MM-DD / 可选

要同步的日期;不传时使用当前 UTC 日期。接口会转换成当天00:00:00.000Z 到 23:59:59.999Z 的查询范围。

featuredboolean / 可选

不传时返回 Product Hunt API 在该日期范围内可见的全部 posts; 传 true 时只取 featured 产品。

cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/product-hunt/daily-products?date=2026-08-01"
返回字段

每个产品包含 productUrl、productHuntUrl、name、slug、tagline、votesCount 和 commentsCount。

服务端密钥

Product Hunt developer token 保存在 API Accounts 的product_hunt账号中,调用方仍然只发送PXANY_API_KEY。

上游来源

该接口调用Product Hunt API v2的 GraphQL 入口;字段按官方 posts 查询封装,按 postedAfter / postedBefore过滤指定日期。

GET/v1/url-redirect
需要密钥

URL 重定向解析

跟随 HTTP 跳转和页面 Meta Refresh,返回最终网页地址、 规范化域名以及完整跳转链。

查询参数

urlstring / 必填

需要解析的 HTTP 或 HTTPS URL,最长 2048 个字符。 参数应进行 URL 编码。

cURL
curl --fail-with-body --get \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  --data-urlencode "url=https://httpbin.org/redirect/1" \
  "https://api.pxany.com/v1/url-redirect"
响应示例
{
  "canonical": null,
  "checkedAt": "2026-08-06T00:00:00.000Z",
  "contentType": "application/json",
  "domain": "httpbin.org",
  "finalUrl": "https://httpbin.org/get",
  "inputUrl": "https://httpbin.org/redirect/1",
  "loopDetected": false,
  "redirectCount": 1,
  "redirects": [
    {
      "durationMs": 1004,
      "from": "https://httpbin.org/redirect/1",
      "statusCode": 302,
      "to": "https://httpbin.org/get",
      "type": "http"
    }
  ],
  "server": "cloudflare",
  "statusCode": 200,
  "totalDurationMs": 1920,
  "warnings": [],
  "xRobotsTag": null
}

错误响应

400 / 401请求错误

URL 不合法、目标为本地地址,或者 API Key 无效。

429 / 502 / 503 / 504上游错误

直连目标或备用重定向服务限流、返回异常、不可用或请求超时。

鉴权和实现

调用方只发送 PXANY_API_KEY。PXAny 先在服务端直接跟踪 公开 HTTP(S) 跳转;直连请求失败或结果不可用时,再依次串行调用 RedirectCheck 和 Unshortened。优秀新站的 Product Hunt URL 解析也复用同一逻辑。

GET/v1/serp
需要密钥

Serp 搜索代理

通过 PXAny 私有 SerpAPI 账号池代理 Google 搜索。

查询参数

qstring / 必填

搜索词,不能为空。

gl / hl / start / num / safe可选

Google 地区、语言、分页、数量和安全搜索参数。

cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/serp?q=best+espresso+beans&gl=us&hl=en&num=10&start=0&safe=off"
参数限制

请求中不能传 api_key、engine、output;这些字段由 PXAny 接管。

POST/v1/sites
需要密钥

创建标准站点

鉴权:Authorization: Bearer <PXANY_API_KEY>。复用后台标准站点创建逻辑,返回 201 JSON 和 Cache-Control: no-store。

JSON 请求体

name:必填非空字符串。domain:必填非空字符串,接受裸域名或 HTTPS URL,由现有站点模块规范化。

websiteUrl:domain 缺省时使用的字符串别名;同时传入时优先 domain。不单独存储,目标网址由规范化域名派生为 https://{domain}。

可选字段:cloudflareDeploymentUrl 为 HTTPS 部署 URL 字符串或 null;githubRepository 为 HTTPS GitHub 仓库 URL 字符串或 null;isPinned 为 boolean,默认 false;status 为 active 或 inactive,默认 active。

可选 Analytics:ga4PropertyId 为数字字符串或 null,允许 properties/ 前缀,拒绝 G- Measurement ID;reportEnabled 为 boolean,默认 true;syncEnabled 为 boolean,默认 false,启用时必须提供 GA4 Property ID;timezone 为字符串,默认 Asia/Shanghai。GSC 自动使用 sc-domain:域名,不接受 gscSiteUrl。

可选发布配置:productDescription(产品描述)、author(作者)、siteEmail(联系邮箱)、commentInstructions(外链评论要求)均为字符串或 null,去除首尾空白,空值保存为 null;anchorTexts 为字符串数组或换行/逗号分隔字符串,去除空白及重复项,默认空数组。省略的发布文本默认 null。不接受 logoUrl、websiteScreenshotUrl、shareImageUrl 或 profileMedia* 等自动媒体字段。

cURL
curl -X POST 'https://api.pxany.com/v1/sites' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Flying Broom AI","domain":"flyingbroomai.com","productDescription":"AI writing assistant","ga4PropertyId":"123456789","author":"Alex","siteEmail":"hello@example.com","anchorTexts":["AI writing","writing assistant"]}'
201 JSON
{
  "ok": true,
  "site": {
    "id": 1,
    "name": "Flying Broom AI",
    "domain": "flyingbroomai.com",
    "slug": "flyingbroomai.com",
    "status": "active",
    "isPinned": false,
    "cloudflareDeploymentUrl": null,
    "githubRepository": null,
    "domainRating": null,
    "domainRatingErrorMessage": null,
    "domainRatingFetchedAt": null,
    "domainRatingLicense": null,
    "productDescription": "AI writing assistant",
    "author": "Alex",
    "siteEmail": "hello@example.com",
    "commentInstructions": null,
    "anchorTexts": [
      "AI writing",
      "writing assistant"
    ],
    "ga4PropertyId": "123456789",
    "gscSiteUrl": "sc-domain:flyingbroomai.com",
    "lastSyncedAt": null,
    "logoUrl": "https://www.google.com/s2/favicons?domain=flyingbroomai.com&sz=128",
    "reportEnabled": true,
    "syncEnabled": false,
    "timezone": "Asia/Shanghai"
  }
}

错误:400 Invalid request(JSON 无效、字段缺失、类型或值无效);401 缺少或无效 Bearer 密钥;409 域名已存在;500 内部错误。均使用 application/problem+json,包含 status、title、detail、requestId、type。重复创建不会新建站点。

409 JSON
{
  "status": 409,
  "title": "Conflict",
  "detail": "A site with this domain already exists.",
  "requestId": "example-request-id",
  "type": "https://api.pxany.com/errors/conflict"
}
GET/v1/sites/lookup
需要密钥

按域名查询标准站点

鉴权:Authorization: Bearer <PXANY_API_KEY>。必填查询参数 domain 接受域名或 HTTP(S) URL,去除协议、www、端口、路径及查询并转小写。结果包含 active 和 inactive 站点,返回 200 JSON,Cache-Control: no-store。

cURL
curl --get 'https://api.pxany.com/v1/sites/lookup' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  --data-urlencode 'domain=https://www.example.com/path'
200 JSON
{
  "site": {
    "id": 1,
    "name": "Example",
    "domain": "example.com",
    "status": "inactive"
  }
}

错误:400 域名缺失或无效;401 密钥无效;404 站点不存在;409 多条站点匹配;500 内部错误。错误使用 application/problem+json。

404 JSON
{
  "status": 404,
  "title": "Not found",
  "detail": "Site not found.",
  "requestId": "example-request-id",
  "type": "https://api.pxany.com/errors/not-found"
}
PATCH/v1/sites/{siteId}
需要密钥

更新标准站点状态

鉴权:Authorization: Bearer <PXANY_API_KEY>。路径参数 siteId 必须为正整数;JSON 请求体仅允许必填 status,值为 active 或 inactive。返回 200 JSON,Cache-Control: no-store。

cURL
curl -X PATCH 'https://api.pxany.com/v1/sites/1' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{"status":"inactive"}'
200 JSON
{
  "site": {
    "id": 1,
    "name": "Example",
    "domain": "example.com",
    "status": "inactive"
  }
}

错误:400 ID 或请求体无效;401 密钥无效;404 站点不存在;500 内部错误。错误使用 application/problem+json。

404 JSON
{
  "status": 404,
  "title": "Not found",
  "detail": "Site not found.",
  "requestId": "example-request-id",
  "type": "https://api.pxany.com/errors/not-found"
}
GET/v1/landing-pages
需要密钥

读取站点内页 URL 结构

鉴权:Authorization: Bearer <PXANY_API_KEY>。必填查询参数 siteId 为正整数。只读,返回 200 JSON,Cache-Control: no-store。

返回该站已登记页面组成的 URL 树(深度优先,父页面为最近的已登记上级路径,/ 为首页根节点)。每个节点包含 pageId、url、path、depth、parentPageId、status(draft / published / indexed / ranking)、页面用途 pageType(ranking 排名页 / index 索引页 / other 其他页)、词群 groupId / groupName、coreKeyword、parentMismatch(词群上级与 URL 上级不一致)以及 gsc:近 28 天曝光、点击、按曝光加权的平均排名和前 5 个查询词,没有数据时为 null。排名页一定绑定词群;索引页默认不绑定(groupId 为 null),只有例外绑定时才有词群,此时要按排名页写内容;其他页不绑定词群。同一站点内一个关键词只属于一个页面。未绑定页面的词群列在 unboundGroups。Agent 选词、定 URL 和加内链时以此为准。

cURL
curl --get 'https://api.pxany.com/v1/landing-pages' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  --data-urlencode 'siteId=1'
200 JSON
{
  "site": {
    "id": 1,
    "domain": "example.com"
  },
  "nodes": [
    {
      "pageId": 10,
      "url": "/",
      "path": "/",
      "depth": 0,
      "parentPageId": null,
      "status": "ranking",
      "pageType": "ranking",
      "groupId": 1,
      "groupName": "home",
      "coreKeyword": "ai sticker maker",
      "parentMismatch": false,
      "gsc": {
        "impressions": 3200,
        "clicks": 85,
        "position": 12.4,
        "topQueries": [
          {
            "query": "ai sticker maker",
            "impressions": 1900,
            "clicks": 60,
            "position": 8.1
          }
        ]
      }
    },
    {
      "pageId": 11,
      "url": "/stickers",
      "path": "/stickers",
      "depth": 1,
      "parentPageId": 10,
      "status": "indexed",
      "pageType": "index",
      "groupId": null,
      "groupName": null,
      "coreKeyword": null,
      "parentMismatch": false,
      "gsc": null
    },
    {
      "pageId": 12,
      "url": "/stickers/cat",
      "path": "/stickers/cat",
      "depth": 2,
      "parentPageId": 11,
      "status": "draft",
      "pageType": "ranking",
      "groupId": 2,
      "groupName": "cat stickers",
      "coreKeyword": "cat stickers",
      "parentMismatch": false,
      "gsc": null
    }
  ],
  "unboundGroups": []
}

错误:400 siteId 缺失或无效;401 密钥无效;404 站点不存在;500 内部错误。错误使用 application/problem+json。

404 JSON
{
  "status": 404,
  "title": "Not found",
  "detail": "Site not found.",
  "requestId": "example-request-id",
  "type": "https://api.pxany.com/errors/not-found"
}
PATCH/v1/landing-pages/{pageId}
需要密钥

更新内页上线 URL 与状态

鉴权:Authorization: Bearer <PXANY_API_KEY>。路径参数 pageId 必须为正整数。JSON 请求体只允许 status 和 url,至少提供一个。用于 Codex / Agent 在页面上线后把页面标为 published 并写入线上地址。返回 200 JSON,Cache-Control: no-store。

status:draft、published、indexed 或 ranking。indexed 与 ranking 通常由每天一次的 GSC 判断自动推进(有曝光为 indexed,核心词平均排名进入前 30 为 ranking,只升不降,不改 draft)。url:站内相对路径或该站域名下的 http(s) 地址(忽略 www),统一保存为不带结尾斜杠的路径;属于其他站点返回 400,与本站其他页面重复返回 409。

cURL
curl -X PATCH 'https://api.pxany.com/v1/landing-pages/12' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{"status":"published","url":"https://example.com/stickers/cat"}'
200 JSON
{
  "page": {
    "pageId": 12,
    "siteId": 1,
    "status": "published",
    "url": "/stickers/cat"
  }
}

错误:400 ID、请求体、状态或 URL 无效;401 密钥无效;404 页面不存在;409 本站已有页面使用该 URL;500 内部错误。错误使用 application/problem+json。

409 JSON
{
  "status": 409,
  "title": "Conflict",
  "detail": "Another page already uses /stickers/cat on this site.",
  "requestId": "example-request-id",
  "type": "https://api.pxany.com/errors/conflict"
}
GET/v1/domains/check
需要密钥

实时域名可用性查询

鉴权:Authorization: Bearer <PXANY_API_KEY>。返回不包装的 JSON 数组,Cache-Control: no-store;所有后缀并发查询。优先 RDAP,失败或不支持时通过 TCP 43 查询注册局 WHOIS。每次请求超时 8 秒并重试一次;仅 IANA RDAP 引导数据缓存 7 天。

查询参数

q 必填。完整域名只检查自身,支持 example.co.uk,tld 为第一个标签之后的部分;否则转小写并移除非 [a-z0-9-] 字符,例如 broom riding ai → broomridingai。标签必须为 1–63 字符,不能以连字符开头或结尾。

tlds 可选,逗号分隔,去掉首尾点,覆盖默认后缀并去重,支持 co.uk;完整域名忽略此参数。

默认后缀:com net org ai io app co me xyz dev tech tools tool online site website pro art video studio design photo photos pics gallery cc so to gg ly sh fm tv im vip fun lol live top cloud info biz us。

cURL
curl --get 'https://api.pxany.com/v1/domains/check' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  --data-urlencode 'q=broom riding ai' \
  --data-urlencode 'tlds=com,io,co.uk'
200 JSON
[
  {
    "domain": "example.com",
    "tld": "com",
    "status": "taken",
    "registered_at": "1995-08-14T04:00:00.000Z",
    "registrar": "Example Registrar",
    "source": "rdap"
  }
]

status 为 available / taken / unknown;registered_at 为 ISO UTC 日期或 null;registrar 为注册商或 null;source 为 rdap / whois / null。无法明确判定时返回 unknown,不猜测。查询可用不保证可以购买。

错误:400 参数无效,401 缺少或无效密钥,500 内部错误,均使用 application/problem+json。上游失败按域名返回 unknown(HTTP 200)。

400 JSON
{
  "detail": "q must produce a valid domain label of 1–63 characters, without leading or trailing hyphens.",
  "requestId": "example-request-id",
  "status": 400,
  "title": "Invalid request",
  "type": "https://api.pxany.com/errors/invalid-request"
}
POST/v1/url-content
需要密钥

URL 内容提取

抓取指定页面,并返回适合 Agent 消费的 Markdown 内容。遇到 Cloudflare 等验证页会返回 422,不会把验证页伪内容当作成功正文。

JSON 请求体

urlstring / 必填

需要抓取的 HTTP 或 HTTPS URL,最长 2048 个字符。

cURL
curl --fail-with-body \
  -X POST "https://api.pxany.com/v1/url-content" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "url": "https://example.com"
  }'

该公共接口不会调用所有者 Chrome。仅 `/publishing` 的内部读取流程会在 Browser Run 被验证页拦截后,通过 Chrome2CF 进行人工可见的浏览器兜底。

POST/v1/keyword-volumes
需要密钥

关键词搜索量

生成 Google Ads 关键词历史指标和逐月搜索量。

JSON 请求体

keywordsstring[] / 必填

至少一个非空关键词,重复项会被移除。

geoTargetId / languageIdstring / 必填

Google Ads 地理位置和语言常量 ID;可使用 ALL。

keywordPlanNetwork / batchSize可选

网络类型和批量大小。

cURL
curl --fail-with-body \
  -X POST "https://api.pxany.com/v1/keyword-volumes" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "keywords": ["<KEYWORD_1>", "<KEYWORD_2>"],
    "geoTargetId": "<GEO_TARGET_ID>",
    "languageId": "<LANGUAGE_ID>",
    "keywordPlanNetwork": "GOOGLE_SEARCH",
    "batchSize": 100
  }'
GET / POST/v1/chrome2cf/*
需要密钥

chrome2cf 采集通道

PXAny 内置的浏览器/扩展采集通道。它负责连接 owner 侧 collector、排队任务和回收结果;当前支持 Semrush keyword_metrics、Google intitle 结果数,以及由 publishing 模块在用户手动确认或已开启的自动发布设置下派发的publishing.substack.publish.v1 / publishing.substack.verify.v1,以及 owner 自用的chatgpt 页面任务。旧的/semrush-keyword 网关路径已退役。

接口

GET /v1/chrome2cf/statuscollector 状态

返回当前 collector 连接状态和 Durable Object 队列计数。

GET /v1/chrome2cf/jobs/{jobId}任务查询

按任务 ID 查询 queued、running、succeeded 或 failed 状态。

POST /v1/chrome2cf/keyword-metricsSemrush 指标

提交 keyword_metrics 采集任务。PXAny 的 one-minute cron 会自动用它处理数据库里的 pending keyword jobs;这个接口主要用于手动验证 collector 链路。

POST /v1/chrome2cf/intitleGoogle intitle

提交 google_intitle 任务。collector 会新开一个后台标签页, 使用 intitle:"关键词" 执行 Google 精确短语搜索, 读取 Google 显示的近似结果数,然后关闭该任务标签页。新版扩展遇到 Google 人机验证或同意页时,会在后台保留原标签页,不切换当前页面,等待所有者手动完成;每秒检查页面一次,通过后继续查询。最多等待 20 分钟,超时保留标签页并返回失败,绝不把验证失败写成结果数 0。

POST /v1/chrome2cf/chatgptChatGPT 页面任务

接受 1–20,000 个字符的原始 prompt,每次在后台新建chatgpt.com 标签页和会话。结果可能包含文字、最多 4 张私有图片,或两者混合;拒绝文字也算正常文字输出。 任务必须轮询,queued/running 不含 success,只有存在可读取文字或成功保存图片时终态才为 success:true。

PUT/GET /v1/chrome2cf/jobs/{jobId}/images/{index}私有图片

扩展只上传 PNG、JPEG 或 WebP(每张不超过 16 MiB,索引 1–4)。下载始终需要 Bearer 密钥,不生成公开 URL。PUT 只验证任务仍在 running;终态结果和 GET 才验证图片输出引用。 部分图片失败会留在 warnings 中,只要仍有其他输出任务就算成功。

ChatGPT 参数、轮询与错误

prompt必填

去除首尾空白后必须为 1–20,000 个字符;发送时不追加“生成图片”等包装文字。

Idempotency-Key可选

1–128 个可打印 ASCII 字符。相同 Key 和提示词返回原任务;换提示词返回 409。服务端只保存 Key 的 SHA-256。

success终态字段

queued/running 不返回;succeeded 且至少有文字或图片为 true,失败或没有可用输出为 false。

chatgpt_login_required / chatgpt_captcha / chatgpt_request_blocked / chatgpt_rate_limited / chatgpt_page_changed / chatgpt_timeout稳定错误码

页面未登录、可见验证码、接口暂时拒绝、请求频率受限、页面结构变化、十分钟超时,以及图片捕获/上传失败都会以稳定 code 返回;接口拒绝或限流会暂停新 ChatGPT 任务十分钟,错误中不会包含提示词或页面全文。

ChatGPT 页面执行前提与边界

建议安装 pxany-extension/0.3.24,并由已连接的 owner collector 声明 chatgpt.page.v1。用户需要先在 Chrome 中自然登录 ChatGPT;登录或 CAPTCHA 时停止任务并保留诊断页,不尝试绕过。 插件在后台任务标签页中复用已登录页面的请求客户端。页面模块或响应结构变化可能返回 chatgpt_page_changed,不是官方 API SLA。

ChatGPT 会话请求在已登录页面内执行,页面凭据不传入 PXAny。文字和图片消耗用户自己的 ChatGPT 账户额度;PXAny 不承诺订阅额度可稳定变成第三方 API 配额。 API 调用者不会收到 Cookie、Token 或页面内部请求。

ChatGPT cURL
# 页面驱动的 ChatGPT 通用任务;提示词原样发送,不是 OpenAI 官方 API。
curl --fail-with-body -X POST "https://api.pxany.com/v1/chrome2cf/chatgpt" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: local-demo-001" \
  --data '{"prompt":"生成一段关于未来城市的简短介绍"}'

# 轮询 Location 或 pollUrl,直到 succeeded / failed。
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/chrome2cf/jobs/<CHATGPT_JOB_ID>"

# 图片结果通过同一个 Bearer 密钥下载,不能把 URL 当成公开地址。
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/chrome2cf/jobs/<CHATGPT_JOB_ID>/images/1" --output chatgpt-1.png
ChatGPT 终态响应
{
  "id": "chatgpt:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "object": "chrome2cf.chatgpt.task",
  "status": "succeeded",
  "success": true,
  "data": {
    "outputs": [
      {
        "type": "text",
        "text": "未来城市在清洁能源与立体交通中保持安静而高效。"
      },
      {
        "type": "image",
        "contentType": "image/png",
        "url": "https://api.pxany.com/v1/chrome2cf/jobs/chatgpt%3A0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef/images/1"
      }
    ],
    "warnings": [],
    "conversationUrl": "https://chatgpt.com/c/example-conversation"
  },
  "error": null,
  "createdAt": 1788240000000,
  "startedAt": 1788240000100,
  "finishedAt": 1788240012000,
  "pollUrl": "/v1/chrome2cf/jobs/chatgpt%3A0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}

插件通过 PUT /v1/chrome2cf/jobs/{id}/images/{index} 上传图片,使用相同的 Bearer 鉴权。任务必须正在执行,index 为 1–4,Content-Type 为 image/png、image/jpeg 或 image/webp,请求体为图片二进制,最大 16 MiB。相同任务、序号、类型及完全相同的字节可重复上传以恢复丢失的确认响应;不同图片返回 409,已有文件不会被覆盖。成功响应包含 contentType、index、size;类型错误返回 415,超限返回 413,存储异常返回 503。

图片上传手动请求
curl -X PUT "https://api.pxany.com/v1/chrome2cf/jobs/chatgpt%3AEXAMPLE/images/1" -H "Authorization: Bearer YOUR_PXANY_API_KEY" -H "Content-Type: image/png" --data-binary @image.png
# 成功示例:{"contentType":"image/png","index":1,"size":1024}

intitle 参数与错误

keyword必填

1–200 个字符;接口会把它作为精确短语放入 intitle 查询。

400 / 401 / 404HTTP 错误

分别表示参数无效、Bearer 密钥无效和任务不存在。collector 离线、Google 超时、验证等待超时或页面无法解析会体现在任务的 failed 状态与 error 字段中。验证等待期间任务保持 running,data.progress 为 google_verification_required;通过后自动继续。

状态 cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/chrome2cf/status"
状态响应
{
  "ok": true,
  "service": "pxany.chrome2cf",
  "status": {
    "activeCollector": {
      "connectedAt": 1785936000000,
      "nodeId": "collector-main",
      "status": "idle",
      "version": "1.0.0"
    },
    "queue": {
      "queued": 0,
      "running": 0,
      "succeeded": 12,
      "failed": 1
    }
  }
}
关键词任务 cURL
curl --fail-with-body \
  -X POST "https://api.pxany.com/v1/chrome2cf/keyword-metrics" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "keywords": ["ai website builder", "html to url"],
    "waitMs": 10000
  }'
关键词任务响应
{
  "id": "7e7d5d51-8a1f-4574-9c46-767c6f21f3fb",
  "action": "keyword_metrics",
  "status": "succeeded",
  "payload": {
    "keywords": ["ai website builder", "html to url"]
  },
  "data": {
    "data": [
      {
        "keyword": "ai website builder",
        "success": true,
        "volume": 2900,
        "kd": 47,
        "cpc": 3.21
      }
    ]
  },
  "error": null,
  "createdAt": 1785936000000,
  "updatedAt": 1785936001200,
  "startedAt": 1785936000100,
  "finishedAt": 1785936001200,
  "nodeId": "collector-main"
}
intitle cURL
curl --fail-with-body \
  -X POST "https://api.pxany.com/v1/chrome2cf/intitle" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "keyword": "ai website builder"
  }'
intitle 响应
{
  "id": "17374851-9658-4fa7-a152-5b2de63dbfeb",
  "action": "google_intitle",
  "status": "succeeded",
  "payload": {
    "keyword": "ai website builder"
  },
  "data": {
    "source": "google",
    "keyword": "ai website builder",
    "query": "intitle:\"ai website builder\"",
    "intitleCount": 12500,
    "resultStats": "About 12,500 results (0.31 seconds)",
    "searchUrl": "https://www.google.com/search?q=intitle%3A%22ai+website+builder%22&hl=en&filter=0&pws=0",
    "collectedAt": "2026-08-10T08:30:01.200Z"
  },
  "error": null,
  "createdAt": 1786350600000,
  "updatedAt": 1786350601200,
  "startedAt": 1786350600100,
  "finishedAt": 1786350601200,
  "nodeId": "pxany-extension"
}
GET / POST/v1/publishing/deliveries/{id}
需要密钥

Substack、Medium 与 Beehiiv 内容发布

通过 Chrome2CF 浏览器任务将后台已经冻结的素材发布到 Substack、Medium 个人主页或 Beehiiv 网页。可手动派发,也可由全局自动发布设置按当天排期派发;订阅邮件固定关闭且不发送 App 通知。插件接口只读取已经由后台派发的任务,没有公开的生成或发布触发接口。自动派发同样要求渠道能力、一次性提交许可及提交后的只读核验。后台操作统一在 内容发布。

鉴权、方法与参数

三个接口均发送 Authorization: Bearer <PXANY_API_KEY>,返回 Cache-Control: no-store。路径 id 是 PXAny Delivery UUID,不是渠道平台的远端 ID。

POST /v1/publishing/deliveries/{id}/startJSON

插件实际开始执行时提交精确 jobId。Delivery 此前保持 queued 且没有租约;成功后才变为 publishing、attempt 加一并开始十分钟租约。同一活动 jobId 可幂等重试,旧任务或不匹配任务返回 409。

GET /v1/publishing/deliveries/{id}冻结文稿

兼容读取活动中的冻结文稿。共同字段为标题、段落、来源 URL、publication 和三张有序私有图片。Medium 另有可选 subtitle、0–5 个 tags 与 paywall=false;Substack 省略这些字段。sendEmail 固定 false,audience 固定 everyone;不返回凭据、Cookie、原始资料快照或可变渠道配置。

GET /v1/publishing/deliveries/{id}/assets/{kind}图片字节

kind 固定为 cover、infographic 或 website_screenshot。成功响应是 image/png 或 image/jpeg,最大 8 MiB。插件后台携带 Bearer 下载后粘贴到相应渠道;不能把密钥放入 URL,也不能在公开文章中引用这个私有图片接口。

POST /v1/publishing/deliveries/{id}/checkpointJSON

必填 jobId 和 stage。stage=draft 时必填 draftId、draftUrl;stage=committing 使用已保存草稿;stage=confirmed 时必填 remoteId、remoteUrl。draft URL 必须是该 Delivery 对应渠道的草稿,public URL 必须是同一 publication 或 Medium 个人主页下的已公开文章;不接收任意脚本。

一次性许可与恢复

每个 checkpoint 必须匹配当前已派发任务。committing 检查任务所有权和十分钟租约,只有首次成功响应的 clickAllowed=true 才能点击一次。它不读取自动开关、发布日期或排期。重复请求返回 409;最终提交后只能核验,不重新领许可或点击;响应丢失、断线或超时也遵循这一边界。confirmed 必须基于实际公开页面、正文和图片核验,相同确认结果重复回报可成功。

发布配置按渠道定义字段,字段值从素材包选择。Substack 首次分发冻结标题、段落、来源网址,以及固定顺序的封面图、信息图、网站截图。Medium 个人主页首次分发还冻结 subtitle、0–5 tags 与 free paywall=false。三个渠道都要求三张图按 cover、infographic、website_screenshot 顺序完整;缺少任意一张都会阻止发布。

文稿 / 图片 cURL
# 用现有任务的真实 delivery ID 替换 <DELIVERY_ID>;这里只读取,不触发发布。
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/publishing/deliveries/<DELIVERY_ID>"

curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/publishing/deliveries/<DELIVERY_ID>/assets/infographic" --output infographic.png
文稿响应(直接 DTO)
{
  "id": "a390d5a5-f0fd-4bd8-97da-a69a9b6b292a",
  "jobId": "publishing:substack:a390d5a5-f0fd-4bd8-97da-a69a9b6b292a:1",
  "publicationUrl": "https://example.substack.com",
  "title": "A practical tool introduction",
  "paragraphs": [
    "A source-grounded introduction to the product."
  ],
  "sourceUrl": "https://example.com/product",
  "images": [
    {
      "kind": "cover",
      "path": "/v1/publishing/deliveries/a390d5a5-f0fd-4bd8-97da-a69a9b6b292a/assets/cover",
      "altText": "Product cover",
      "caption": ""
    },
    {
      "kind": "infographic",
      "path": "/v1/publishing/deliveries/a390d5a5-f0fd-4bd8-97da-a69a9b6b292a/assets/infographic",
      "altText": "Product workflow",
      "caption": "Key workflow"
    },
    {
      "kind": "website_screenshot",
      "path": "/v1/publishing/deliveries/a390d5a5-f0fd-4bd8-97da-a69a9b6b292a/assets/website_screenshot",
      "altText": "Product website",
      "caption": "Official website"
    }
  ],
  "contentPackage": {
    "title": "A practical tool introduction",
    "shortText": "完整独立短文,用于需要短内容的分发渠道;长文仍由 blocks 表示。",
    "excerpt": "A source-grounded introduction to the product.",
    "seoTitle": "A practical tool introduction",
    "seoDescription": "How this practical tool works and who it helps.",
    "socialShort": "A practical tool introduction in one minute.",
    "socialMedium": "A practical tool introduction with the key takeaways.",
    "tags": [
      "tools",
      "workflow"
    ],
    "blocks": [
      {
        "type": "heading",
        "level": 2,
        "text": "A practical tool introduction"
      }
    ],
    "images": [
      {
        "type": "cover",
        "slot": "cover",
        "prompt": "Editorial product illustration",
        "altText": "Product illustration",
        "caption": "Cover illustration"
      }
    ],
    "sourceUrl": "https://example.com/product",
    "sourceFetchedAt": "2026-08-30T00:00:00.000Z",
    "audio": [],
    "video": []
  },
  "draftId": null,
  "draftUrl": null,
  "commitStartedAt": null,
  "sendEmail": false,
  "audience": "everyone"
}

自动领取在数据库内原子检查同一目标、同一渠道所有素材版本的 Delivery 历史。前置配置或素材校验失败会持久化 failed Delivery(AUTOMATIC_VALIDATION_FAILED),下一分钟继续其他候选,修复后须手动发布。Cron 的 dispatched 包含 queued 与 publishing;queued/running 不代表文章已公开。Chrome2CF 全局最多同时运行 6 个任务,每种任务类型最多运行 1 个,其余按可执行 FIFO 排队;队首类型繁忙时不会阻塞其他空闲类型。状态接口只返回总数和 byLane 数量,不返回任务 payload。

checkpoint 手动模拟(有状态写入)
# 以下是手动模拟格式,只能对已分配的测试任务按真实进度调用。
# start:插件实际开始执行时才领取十分钟租约;同一 jobId 的响应丢失可安全重试。
curl --fail-with-body -X POST   "https://api.pxany.com/v1/publishing/deliveries/<DELIVERY_ID>/start"   -H "Authorization: Bearer $PXANY_API_KEY" -H "Content-Type: application/json"   --data '{"jobId":"publishing:substack:<DELIVERY_ID>:<ATTEMPT>"}'

# draft:草稿已创建且 ID/URL 已核对后保存。
curl --fail-with-body -X POST \
  "https://api.pxany.com/v1/publishing/deliveries/<DELIVERY_ID>/checkpoint" \
  -H "Authorization: Bearer $PXANY_API_KEY" -H "Content-Type: application/json" \
  --data '{"jobId":"publishing:substack:<DELIVERY_ID>:<ATTEMPT>","stage":"draft","draftId":"12345","draftUrl":"https://example.substack.com/publish/post/12345"}'

# committing:会消耗一次性提交许可。不要重复请求,不要配置 curl --retry。
curl --fail-with-body -X POST \
  "https://api.pxany.com/v1/publishing/deliveries/<DELIVERY_ID>/checkpoint" \
  -H "Authorization: Bearer $PXANY_API_KEY" -H "Content-Type: application/json" \
  --data '{"jobId":"publishing:substack:<DELIVERY_ID>:<ATTEMPT>","stage":"committing"}'

# confirmed:只有已实际核验公开文章、正文和配图后才能回报。
curl --fail-with-body -X POST \
  "https://api.pxany.com/v1/publishing/deliveries/<DELIVERY_ID>/checkpoint" \
  -H "Authorization: Bearer $PXANY_API_KEY" -H "Content-Type: application/json" \
  --data '{"jobId":"publishing:substack:<DELIVERY_ID>:<ATTEMPT>","stage":"confirmed","remoteId":"12345","remoteUrl":"https://example.substack.com/p/practical-tool"}'
checkpoint 200 响应
draft:      {"clickAllowed":false,"status":"publishing"}
committing: {"clickAllowed":true,"status":"publishing"}
confirmed:  {"clickAllowed":false,"status":"published"}

错误响应

400:非法 UUID、JSON、参数或 URL;401:缺失或错误 Bearer;404:文章或图片不存在;409:旧 job、租约过期、并发操作、状态冲突或许可已领取;503:数据库、图片存储或发布执行器暂不可用。响应使用 application/problem+json,包含 status、title、detail、requestId;发布业务错误还带安全 code,不返回凭据或第三方原始错误。

409 示例
{
  "type": "https://api.pxany.com/errors/conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "当前任务或文章状态不允许此操作,请刷新后重试;已提交的文章只能重新核验。",
  "code": "STATE_CONFLICT",
  "requestId": "example-request-id"
}

c2CF 发布动作

Beehiiv 文稿另含 subtitle、seoDescription、publishToEmail=false、platform="web" 和 displayThumbnailOnWeb=false;渠道由任务 action 确定,文稿不额外携带 channel 字段。发布器保存并读回三图正文,确认无邮件收件人数且关闭社区发布,再领取最终提交许可。Beehiiv draftId 是 UUID,草稿地址为 https://app.beehiiv.com/posts/<UUID>/edit,成功地址必须为配置的 publicationUrl 下的 /p/<slug>。

插件握手声明 capabilities=["publishing.substack.publish.v1","publishing.substack.verify.v1","publishing.medium.publish.v1","publishing.medium.verify.v1","publishing.beehiiv.publish.v1","publishing.beehiiv.verify.v1"];缺失时需要更新插件。publish 动作执行准备与一次性提交;verify 动作只核验,不写编辑器、不提交。三个渠道动作共用现有 WebSocket,最长十分钟;最终提交后断线不会自动重排发布。

Worker 发给插件的任务(示例期限已过,不能直接执行)
{
  "action": "publishing.substack.publish.v1",
  "id": "publishing:substack:a390d5a5-f0fd-4bd8-97da-a69a9b6b292a:1",
  "payload": {
    "deliveryId": "a390d5a5-f0fd-4bd8-97da-a69a9b6b292a",
    "postId": "9b4769e5-b784-4a63-9b78-dab4b775d574",
    "channel": "substack",
    "deadline": "2026-09-23T01:10:00.000Z"
  }
}
Medium Worker 任务(示例期限已过,不能直接执行)
{
  "action": "publishing.medium.publish.v1",
  "id": "publishing:medium:a390d5a5-f0fd-4bd8-97da-a69a9b6b292a:1",
  "payload": {
    "deliveryId": "a390d5a5-f0fd-4bd8-97da-a69a9b6b292a",
    "postId": "9b4769e5-b784-4a63-9b78-dab4b775d574",
    "channel": "medium",
    "deadline": "2026-09-23T01:10:00.000Z"
  }
}

任务 ID 格式为 publishing:<channel>:<deliveryUUID>:<attempt>,payload 必含 deliveryId、postId、channel,以及 Hub 在实际派发时生成的 deadline。verify 使用相同 payload,分别改为 publishing.substack.verify.v1 、publishing.medium.verify.v1 或 publishing.beehiiv.verify.v1。收到任务后先调用 start,再读取配图和调用 checkpoint;start 只是执行握手,不是公开发布触发入口。

c2CF 手动查询
# 发布动作只能由 publishing 模块调度;没有公开的提交发布任务接口。
# 读取执行器能力和已有任务状态:
curl --fail-with-body -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/chrome2cf/status"
curl --fail-with-body -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/chrome2cf/jobs/publishing:substack:<DELIVERY_ID>:<ATTEMPT>"

后台接口

PATCH /api/admin/publishing/settings 保存素材语言、AI 提示词、全局自动发布开关及 Asia/Shanghai 每日开始时间;PATCH /api/admin/publishing/channels/{channel} 独立保存指定渠道地址、language 与素材字段映射,POST channels/{channel}/preview 只读预览该映射的内容。POST /api/admin/publishing/targets 只接受网站 url;targets/{id}/prepare 每次对账同一个持久化 ChatGPT 生成任务,失败不会自动重投,retry-generation 才能在版本 CAS 通过后解锁新 attempt;posts/{id}/regenerate 会在安全 Delivery 前重新生成素材。posts/{id}/deliveries/{channel}/publish 手动派发冻结 Delivery,deliveries/{id}/sync 只同步已有插件任务,deliveries/{id}/verify 只核验已有 commit_started_at 的不确定提交。每分钟 Cron 最多自动处理一个当天到期、素材已就绪且没有 Delivery 历史的渠道;失败或结果未知不会自动重试。后台使用管理员 Cookie;修改请求必须同源,不接受公开 API 密钥代替登录。

GET/v1/extension/status
需要密钥

PXAny Chrome 扩展状态

用于测试扩展与 PXAny API 的公共连接,并返回当前可用模块。 当前返回 backlinks、chrome2cf 和on-page-seo-check。

参数

无GET

仅需要 Bearer 鉴权。

cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/extension/status"
响应示例
{
  "name": "PXAny",
  "status": "ok",
  "modules": ["backlinks", "chrome2cf", "on-page-seo-check"]
}
POST / GET/v1/on-page-seo-check/v4/*
需要密钥

插件页面检查 v4:上线前验收

使用自己的 PXAny 检测引擎,参考哥飞公开规则;未公开的逐项权重和公式采用 PXAny 补充规则,不调用哥飞 API。请求统一发送 Authorization: Bearer <PXANY_API_KEY>。

POST /v1/on-page-seo-check/v4/runs:传 pageId 或一个 keyword,二者互斥。手动关键词无需登记站点或页面,响应 pageId、siteId 为 null。两种模式都必须提交 snapshot:pageUrl、html、contentType、responseStatus、responseTimeMs。html 为当前渲染后 DOM,UTF-8 上限2MB。可选 snapshot.rendered 提交工具可见性/首屏位置和图片尺寸证据。

可选 evidence 包含 document、robots、sitemaps(最多5个)及 sitemapComplete、xRobotsTag。每个资源含 url、status、contentType、text、redirected、durationMs、contentEncoding、error。只接受同源URL;document地址须匹配当前页(忽略锚点),robots路径须为 /robots.txt。原始HTML上限2MB,辅助资源各256KB;服务端不请求这些地址,原始正文不写入历史。

调试模式可选传 targetUrl(完整正式 URL,含路径);不传即真实模式。snapshot.pageUrl 与 evidence 仍保留实际预览地址,服务端不会请求 targetUrl。Canonical、相对链接解析、内外链、关键词 URL 和 Sitemap 包含关系按正式 URL 判断;robots 与 Sitemap 内容采集自预览站,声明的正式域名 Sitemap 路径映射到预览站读取。报告 crawl.targetUrl 标识调试模式,requestedUrl/finalUrl 仍是采集地址,手动历史按正式 URL + 核心词查询。HTTPS 标记待补查,调试报告不会判为可上线;HTTP 状态、响应时间和跳转仅代表预览页。

Sitemap自动识别同协议、同端口、同路径和同查询参数的www/裸域名版本。完整URL一致且robots已声明时得2/2分;仅www版本不同时显示「已找到对应页面(www版本不同)」并提示统一地址,按警告得1/2分,evidence显示检测URL和实际匹配URL。不会改写targetUrl,不把其他路径、子域名或协议当作同一页,也不声称已验证正式站跳转。调试采集可把上述两种域名声明的Sitemap路径映射到预览站,实际请求和提交证据仍严格同源。

核心词 URL 项检查审核地址的域名与路径,域名中的完整关键词连写也可命中。例如 astrocartography chart 与 https://astrocartographychart.net/ 对应时该项为2/2分;查询参数、片段、顶级域名不计入。证据显示完整审核 URL;调试时使用 targetUrl,不改写原始页面内容,也不自动放宽品牌词要求。

GET /v1/on-page-seo-check/v4/history:传 pageId,或 url + keyword。手动历史按当前URL与规范化核心词隔离;GET /v1/on-page-seo-check/v4/runs/{runId} 查看完整报告。成功分别返回201或200;400参数错误、401密钥无效、404页面/报告不存在、422缺少核心词或页面5xx、503数据库暂不可用。

评分为 round(earned / possible × 100),再取最低封顶;unknown(待补查)与 not_applicable(确实不适用)不计有效满分。scores 显示 earned、possible、coverage、unknownChecks 和 acceptance(ready / fix_required / incomplete)。只要仍有待补查项就不能当作完整验收通过。分类显示 score、weight、applicableWeight,每个检查项含 earned、证据和整改建议。

词数封顶75/55/35,聚焦度封顶65/45/25;noindex、robots屏蔽、HTTP错误封顶20,CSR空壳封顶40为PXAny补充规则。单词密度3%–5%,多词密度仅展示,不重复计分。所有者自定义验收项「核心词 · 同词数密度排名」占6分:N个单词检查N-GRAM,完整核心词第1或并列第1得6分,其余0分并判需修改;相同次数并列,排名来自完整统计,榜单展示前15条。当前支持1–5词,超出标待补查。品牌候选未核验SERP,不自动放宽。相关/长尾仅提示,不计总分;KGR/KD、词族密度合计、main存在、文本代码比、重复标题等不再计分。旧路径保留v3契约,历史版本不同不比较涨跌。

手动关键词模拟请求
curl --fail-with-body 'https://api.pxany.com/v1/on-page-seo-check/v4/runs' \
  -H 'Authorization: Bearer <PXANY_API_KEY>' \
  -H 'Content-Type: application/json' \
  --data '{"keyword":"passport photo maker","snapshot":{"pageUrl":"http://localhost:3000/","html":"<html><body><h1>Passport photo maker</h1></body></html>","contentType":"text/html","responseStatus":200,"responseTimeMs":100}}'
手动关键词历史
curl --get 'https://api.pxany.com/v1/on-page-seo-check/v4/history' -H 'Authorization: Bearer <PXANY_API_KEY>' --data-urlencode 'url=http://localhost:3000/' --data-urlencode 'keyword=passport photo maker'
响应字段节选
{"run":{"runId":42,"pageId":null,"focusKeyword":"passport photo maker","scoringVersion":"on-page-seo-check-v4","report":{"scores":{"raw":85,"final":75,"earned":85,"possible":100,"coverage":90,"unknownChecks":2,"acceptance":"fix_required","appliedCaps":[{"cap":75,"reason":"正文不足600词/字。"}]}}}}
GET / POST/v1/on-page-seo-check/*
需要密钥

On Page SEO Check

供 PXAny Chrome 扩展的独立 SEO 面板使用。扩展直接采集当前标签页渲染后的 DOM 快照,pageId 用于读取 1 个核心词、按搜索量排序的最多 5 个同义词; 其余关键词按搜索量排序,最多选 20 个作为长尾词检查。词群本身不受此检查数量限制。 当前页可以是 localhost、预览环境或任意 HTTP(S) URL,不要求与 page_id 登记域名一致,浏览器也不会接触 Supabase Service Role Key。

接口

POST /v1/on-page-seo-check/runs执行检测

JSON 请求体包含 pageId 和扩展当前标签页的snapshot。服务端直接分析该 DOM,不重新抓 URL,也不做域名限制; 成功返回 201 和完整报告,只有检测成功才写入历史。

GET /v1/on-page-seo-check/runs/{runId}单次报告

读取指定历史运行的完整评分、关键词分层、逐项结论和抓取统计。

GET /v1/on-page-seo-check/history?pageId=123历史趋势

返回最近 20 次摘要以及最新完整报告;从未检测时history 为空且 run 为 null。

评分与抓取

新报告使用 on-page-seo-check-v3 契约:核心词严格检查 Title、Description、H1、URL、开头和正文,并独立决定聚焦度封顶;同义词重点检查 H2/H3 与对应段落正文;长尾词只检查正文完整词组覆盖,不要求进入 TDK。 每个关键词同时返回 Google KGR、Semrush KGR、Semrush eKGR 和 Semrush KD 作为选词参考; 这四个数据库指标不参与页面聚焦度或总分计算,缺失时返回 null。densityRankings 返回正文 1–5 gram 的前 20 个连续词组及其出现次数、密度和名次;targetDensity 将核心词与同义词的精确词组密度合并为一个词族,长尾词不参与合并。 词族状态包含 missing、low、base、focused、high 和 stuffing_risk,其中 3%–5% 标记为 focused; 这些状态只用于诊断提示,不参与页面聚焦度或总分计算。 报告还包括 0–100 总分、正文词数/noindex 封顶、关键词分层对比、 7 类分类分和逐项整改建议。DOM 快照 UTF-8 体积上限 2 MB,原始快照不写入历史。 仅凭 DOM 无法可靠取得的跳转链、robots.txt、Sitemap 和 SSR/CSR 等技术项显示为 N/A, 不进入分类分母。

执行检测 cURL
curl --fail-with-body \
  -X POST "https://api.pxany.com/v1/on-page-seo-check/runs" \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "pageId": 123,
    "snapshot": {
      "pageUrl": "http://localhost:3000/preview",
      "contentType": "text/html",
      "html": "<html><body>Current rendered page</body></html>",
      "responseStatus": 200,
      "responseTimeMs": 120
    }
  }'
历史记录 cURL
curl --fail-with-body \
  -H "Authorization: Bearer $PXANY_API_KEY" \
  "https://api.pxany.com/v1/on-page-seo-check/history?pageId=123"
检测响应(字段节选)
{
  "run": {
    "runId": 42,
    "pageId": 123,
    "url": "https://example.com/tools/compress",
    "targetKeywords": ["image compressor", "compress image online"],
    "focusKeyword": "image compressor",
    "rawScore": 84,
    "finalScore": 75,
    "focusScore": 78,
    "grade": "pass",
    "wordCount": 512,
    "scoringVersion": "on-page-seo-check-v3",
    "createdAt": "2026-08-09T09:30:00.000Z",
    "report": {
      "version": "on-page-seo-check-v3",
      "scores": {
        "raw": 84,
        "final": 75,
        "focus": 78,
        "grade": "pass",
        "appliedCaps": [
          {"cap": 75, "reason": "Visible body content is below 600 words."}
        ]
      },
      "categories": [],
      "keywordFocus": [],
      "densityRankings": {
        "1": [{"phrase": "image", "count": 20, "density": 3.91, "rank": 1}],
        "2": [{"phrase": "image compressor", "count": 6, "density": 2.34, "rank": 1}],
        "3": [],
        "4": [],
        "5": []
      },
      "targetDensity": {
        "phrases": [
          {"phrase": "image compressor", "role": "core", "count": 6, "density": 2.34},
          {"phrase": "compress image online", "role": "related", "count": 2, "density": 1.17}
        ],
        "totalCount": 8,
        "totalDensity": 3.51,
        "status": "focused"
      },
      "checks": [],
      "crawl": {},
      "page": {},
      "stats": {},
      "generatedAt": "2026-08-09T09:30:00.000Z"
    }
  }
}
ERROR RESPONSES

错误响应

公共 API 默认使用 application/problem+json。 排查问题时保留响应头 x-request-id 和正文中的requestId。

错误结构
{
  "type": "https://api.pxany.com/errors/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "A valid PXAny API key is required.",
  "requestId": "00000000-0000-0000-0000-000000000000"
}
400请求体或参数不合法
401API Key 缺失或无效
404目标记录不存在
503上游服务或必要资源不可用