CITV 开放文档
Domainer

平台类客户 API 接口文档

Domainer 商户、域名、DNS 解析明细等开放接口说明

平台类客户 API 接口文档

Domainer API 面向平台类客户的服务端调用场景,提供商户实名档案、商户域名、通用域名和 DNS 解析明细等能力。

项目说明
版本v1.4.0
最后更新2026-05-15
适用对象平台类客户服务端(S2S)调用
鉴权方式Authorization: Bearer <STS token>
API Base URL以部署环境为准,示例:https://portal.citv.cc

接入流程

  1. 先通过 API Token 换取与使用指南 换取短期 STS Token。
  2. 后续所有 /api/v1/* 接口都携带 Authorization: Bearer <token>
  3. 按业务流程调用商户注册、域名创建、域名查询或 DNS 解析明细接口。
  4. 接口返回时优先读取响应体中的 code 判断业务结果。

更新历史

日期版本变更
2026-05-15v1.4.0新增 GET /api/v1/dns-oss-records/daily;新增 dns-records:read scope;明确解析明细查询日期范围最多 31 天
2026-05-13v1.3.0新增 GET /api/v1/domains/quota;明确域名配额统计口径、根域配额归一化规则和缺少平台上下文时的错误语义
2026-03-06v1.2.0补充 auth-check、按商户维度的域名管理路由;修正文档中的 scope 名称、路径、配额与删除语义
2025-11-25v1.1.0商户注册新增必填 userAuthorization;注册接入企业四要素认证与缓存/重试能力;商户禁止修改 licenseNumber

接口总览

分类方法路径Scope说明
鉴权检查GET/api/v1/auth-checkcompany:list检查 Bearer 与 scope 是否生效
商户POST/api/v1/merchants/registermerchant:register创建商户实名档案
商户GET/api/v1/merchants/{merchantId}merchant:read查询商户详情
商户PUT/api/v1/merchants/{merchantId}merchant:update更新商户实名档案
商户DELETE/api/v1/merchants/{merchantId}merchant:delete删除商户档案
商户域名GET/api/v1/merchants/{merchantId}/domainsmerchant:read查询商户域名列表
商户域名POST/api/v1/merchants/{merchantId}/domainsdomain:create为指定商户创建域名
商户域名GET/api/v1/merchants/{merchantId}/domains/{domain}merchant:read查询商户下某个域名
商户域名PUT/api/v1/merchants/{merchantId}/domains/{domain}domain:update更新商户域名 CNAME
商户域名DELETE/api/v1/merchants/{merchantId}/domains/{domain}domain:delete删除商户域名
通用域名POST/api/v1/domains/cnamedomain:create按 platformDomain 创建商户子域名
通用域名GET/api/v1/domains/quotadomain:read查询当前平台域名配额快照
通用域名GET/api/v1/domains/{domain}domain:read查询域名详情
通用域名PUT/api/v1/domains/{domain}/cnamedomain:update更新域名 CNAME
通用域名DELETE/api/v1/domains/{domain}domain:delete删除域名
DNS 解析明细GET/api/v1/dns-oss-records/dailydns-records:read查询日级解析明细文件与临时下载地址

鉴权与返回语义

Bearer 鉴权

所有 v1 路由都只接受 STS Bearer 令牌,不读取 Cookie 或 Session。

STS 建议通过 POST /api/auth/api-token 换取,Token 会绑定实际平台上下文:platformCompanyId / platformCode

当同一用户绑定多个 active 平台时,必须在换 token 时显式传平台选择器,推荐传 platformCompanyId。兼容字段包括:platformIdplatform_company_idplatform_id

限流

所有路由都经过服务端限流。命中限流时:

{
  "code": 429,
  "data": null,
  "message": "请求过于频繁,请稍后重试"
}

统一响应结构

{
  "code": 200,
  "data": {},
  "message": "OK"
}

HTTP 状态与响应体 code

场景HTTP 状态响应体 code
鉴权失败401401
限流429429
GET /api/v1/auth-check 缺少 company:list403403
大多数业务错误200400 / 403 / 404 / 409 / 500

接入方应始终以响应体中的 code 作为业务判断主依据,不能只看 HTTP 状态。

Scope 清单

Scope用途
company:list鉴权检查
merchant:register创建商户
merchant:read查询商户、查询商户域名
merchant:update更新商户
merchant:delete删除商户
domain:create创建域名
domain:read查询通用域名、域名列表及当前平台域名配额快照
domain:update更新域名 CNAME
domain:delete删除域名
dns-records:read查询 DNS 日级解析明细文件与临时下载地址

字段约定

字段说明
merchantId平台方自定义的商户唯一标识,系统按“平台 + merchantId”做唯一性校验
domain完整域名字符串,例如 shop01.platform.citv.cc
platformDomain平台已有域名,例如 platform.citv.cc
rootDomain启用的基础根域,例如 citv.cc;部分接口也允许传平台域名形式,例如 platform.citv.cc
subdomain商户子域名前缀,只允许单段 label,例如 shop01,不要传 shop01.platform
userAuthorization用户授权标记,推荐传字符串 "1""0",当前实现也兼容数值 1 / 0

鉴权检查

GET /api/v1/auth-check

用于快速确认 Bearer 令牌是否可用、scope 是否生效。

项目说明
所需 scopecompany:list
缺少 BearerHTTP 401
缺少 scopeHTTP 403,返回当前 scope 与所需 scope

成功响应:

{
  "code": 200,
  "message": "鉴权通过",
  "data": {
    "userId": "xxx",
    "accessKeyId": "ak_xxx",
    "scope": ["company:list"],
    "expiresAt": "2026-03-06T12:00:00.000Z",
    "serverTime": "2026-03-06T11:30:00.000Z"
  }
}

商户实名档案

POST /api/v1/merchants/register

创建平台商户实名档案。

项目说明
所需 scopemerchant:register
认证注册前会先做企业四要素认证
幂等建议客户端应自行控制 merchantId 幂等

请求体:

字段类型必填说明
merchantIdstring平台侧商户唯一 ID
namestring商户名称
licenseNumberstring营业执照编号
licenseImageUrlstring营业执照图片地址
legalRepNamestring法人姓名
legalRepIdNumberstring法人证件号
bankNamestring开户行
bankAccountNumberstring银行账号
publicInfoUrlstring公示信息页地址
userAuthorizationstring"1" 已授权,"0" 未授权
contactNamestring联系人
contactPhonestring联系电话
contactEmailstring联系邮箱
addressstring地址
descriptionstring描述
logoUrlstringLogo 地址
websiteUrlstring官网地址

成功响应:

{
  "code": 200,
  "data": { "created": true },
  "message": "OK"
}

业务规则:

  • 当前账号必须能解析到至少一个可用平台公司,否则返回 code=400message=当前账户未关联可用公司
  • userAuthorization="0" 时,直接拒绝:code=403message=没有获得用户授权
  • 企业状态非在营时返回 code=400message=企业经营状态异常:<状态码>(<状态说明>)
  • 认证服务异常返回 code=500message=实名认证服务异常
  • 命中预算限制返回 code=403message=预算已用尽
  • 平台内重复校验:merchantIdnamelicenseNumber 重复均返回 code=409

认证状态码:

状态码含义
1在营(开业)
2迁出
3注销
4吊销
5撤销
6停业
0其他

缓存与重试:

  • 命中“确定性失败缓存”时会直接返回失败,不再重试外部认证。
  • 命中“暂态失败缓存”时会重新触发认证。
  • 外部认证的暂态错误当前最多重试 3 次。

GET /api/v1/merchants/{merchantId}

查询商户实名档案与关联域名摘要。

项目说明
路径参数merchantId
所需 scopemerchant:read
未找到商户code=404message=资源不存在

成功响应示例:

{
  "code": 200,
  "data": {
    "merchantId": "EXT-998877",
    "name": "示例科技有限公司",
    "licenseNumber": "9132XXXXXXXXXXXXX",
    "licenseImageUrl": "https://cdn.example.com/licenses/9132XX.png",
    "legalRepName": "张三",
    "legalRepIdNumber": "1101XXXXXXXXXXXXXX",
    "bankName": "中国银行某支行",
    "bankAccountNumber": "622202XXXXXXXXXXXX",
    "publicInfoUrl": "https://example.com/merchant/EXT-998877",
    "contactName": "李四",
    "contactPhone": "13800138000",
    "contactEmail": "contact@example.com",
    "address": "北京市海淀区中关村大街1号",
    "description": "主营 SaaS 服务",
    "logoUrl": "https://cdn.example.com/logo.png",
    "websiteUrl": "https://merchant.example.com",
    "domains": [
      {
        "domainId": "67c93f...",
        "domainName": "shop01.platform.citv.cc",
        "cnameValue": "target.example.net"
      }
    ]
  },
  "message": "OK"
}

当前实现会按商户公司 companyId 聚合域名摘要;该聚合未显式过滤软删除域名记录。

PUT /api/v1/merchants/{merchantId}

更新商户实名档案,支持部分字段更新。

项目说明
路径参数merchantId
所需 scopemerchant:update
可更新字段merchantId 外,基本与注册字段一致;userAuthorization 可选
禁止更新licenseNumber

成功响应:

{
  "code": 200,
  "data": { "updated": true },
  "message": "OK"
}

业务规则:

  • 请求体带 licenseNumber 时,返回 code=400message=营业执照号码不允许修改
  • 商户不存在返回 code=404message=未找到商户信息
  • 平台内名称重复返回 code=409message=商户名称已存在
  • 更新成功后会尝试重新触发企业认证,但认证失败不会阻断本次更新成功响应。

DELETE /api/v1/merchants/{merchantId}

删除商户档案。

项目说明
路径参数merchantId
所需 scopemerchant:delete
商户不存在code=404message=未找到商户信息

成功响应:

{
  "code": 200,
  "data": { "deleted": true },
  "message": "OK"
}

当前实现只删除商户档案,不会级联删除该商户名下域名;如需清理域名,请单独调用域名删除接口。

商户维度域名接口

这组接口显式绑定 merchantId,适合对某个商户名下域名做管理。

GET /api/v1/merchants/{merchantId}/domains

查询商户域名列表。

项目说明
路径参数merchantId
所需 scopemerchant:read

成功响应:

{
  "code": 200,
  "data": [
    {
      "_id": "67c9...",
      "subdomain": "shop01.platform",
      "rootDomain": "citv.cc",
      "cnameValue": "target.example.net",
      "status": "ACTIVE",
      "companyId": "67c8...",
      "platformId": "67c7...",
      "dnsRecordId": "rr-xxx",
      "createdAt": "2026-03-06T10:00:00.000Z",
      "updatedAt": "2026-03-06T10:00:00.000Z",
      "company": {
        "id": "67c8...",
        "name": "示例商户",
        "email": "merchant@example.com",
        "status": "ACTIVE",
        "user": { "email": "owner@example.com" }
      }
    }
  ],
  "message": "OK"
}

说明:

  • 商户不存在返回 code=404message=未找到商户信息
  • 当前实现会先检查商户实名状态;若商户未认证或经营状态异常,会直接返回 403
  • 可能的 message:商户未认证,禁止创建域名商户经营状态异常:<状态码>(<说明>)

POST /api/v1/merchants/{merchantId}/domains

为指定商户创建域名。

项目说明
路径参数merchantId
所需 scopedomain:create

请求体:

字段类型必填说明
rootDomainstring基础根域,如 citv.cc;也可传平台域形式,如 platform.citv.cc
cnameValuestringCNAME 目标值
subdomainstring商户子域名前缀,只允许单段 label;不传则服务端随机生成 5 位
ttlnumberDNS TTL,正整数

平台域名形式处理规则:

  • 当前实现统一生成三级域名:<商户前缀>.<平台域前缀>.<基础根域>
  • rootDomainplatform.citv.cc 这类平台域名时,服务端先校验该平台域确属当前平台。
  • 平台域名会规范化为:最终 rootDomain = citv.cc,最终 subdomain = <商户前缀>.platform
  • rootDomain 只传基础根域时,如果当前平台在该根域下有多个平台域,会返回错误,要求改传明确的平台域名。

成功响应:

{
  "code": 200,
  "data": {
    "domainId": "67c93f...",
    "dnsRecordId": "rr-xxx",
    "domain": {
      "subdomain": "shop01.platform",
      "rootDomain": "citv.cc",
      "cnameValue": "target.example.net",
      "status": "ACTIVE"
    }
  },
  "message": "OK"
}

常见错误:

code场景
400参数错误、rootDomain 不在启用列表、平台子域名配额已满、商户域名数量已达上限、RootDomain 三级域名配额已满、商户子域名前缀格式错误
403platformDomain 不属于当前平台,或 rootDomain 不在平台允许范围
404未找到商户信息
500域名服务、DNS 或数据库异常

GET /api/v1/merchants/{merchantId}/domains/{domain}

查询某个商户下的单个域名。

项目说明
路径参数merchantIddomain
所需 scopemerchant:read
格式错误domain 不能按当前启用根域正确拆分时返回 code=400
未找到商户不存在、域名不存在或域名不属于该商户时返回 code=404

PUT /api/v1/merchants/{merchantId}/domains/{domain}

更新商户域名 CNAME。

项目说明
路径参数merchantIddomain
所需 scopedomain:update

请求体:

字段类型必填说明
cnameValuestring新的 CNAME
remarkstring备注

成功响应:

{
  "code": 200,
  "data": {
    "domainId": "67c93f...",
    "domain": {
      "subdomain": "shop01.platform",
      "rootDomain": "citv.cc",
      "cnameValue": "new.example.net"
    }
  },
  "message": "OK"
}

常见错误:

code场景
400参数错误、缺少 cnameValue、域名不在启用根域或格式不正确
404未找到商户信息,或资源不存在

DELETE /api/v1/merchants/{merchantId}/domains/{domain}

删除商户域名。

项目说明
路径参数merchantIddomain
所需 scopedomain:delete

成功响应:

{
  "code": 200,
  "data": { "deleted": true },
  "message": "OK"
}

常见错误:

code场景
400domain 解析失败
404商户不存在、域名不存在或域名不属于该商户
500删除失败或底层服务异常

通用域名接口

这组接口不显式带 merchantId 路径,适合按完整域名或平台域名操作。

POST /api/v1/domains/cname

基于 platformDomain 为指定商户创建商户子域名,并配置 CNAME。

项目说明
所需 scopedomain:create
生成结构<商户子域名>.<平台子域名>.<基础根域>

请求体:

字段类型必填说明
merchantIdstring平台侧商户 ID
platformDomainstring平台域名,如 platform.citv.cc
subdomainstring自定义商户子域名,只允许单段 label,不要包含 platformDomain
cnameValuestringCNAME 目标值
ttlnumberDNS TTL,正整数

生成规则:

输入结果
platformDomain = mengz.citv.ccsubdomain = shop01shop01.mengz.citv.cc
platformDomain = mengz.citv.cc,未传 subdomain自动生成随机 5 位商户前缀,例如 1rn5e.mengz.citv.cc

成功响应:

{
  "code": 200,
  "data": {
    "domainId": "67c93f...",
    "dnsRecordId": "rr-xxx",
    "domain": {
      "subdomain": "1rn5e.mengz",
      "rootDomain": "citv.cc",
      "cnameValue": "target.example.net",
      "status": "ACTIVE"
    }
  },
  "message": "OK"
}

常见错误:

code场景
400参数错误、当前账户未关联可用公司、platformDomain 格式不正确、平台域名不是二级域名、配额已满、商户子域名前缀格式错误
403platformDomain 不属于当前平台,或 rootDomain 不在平台允许范围
404未找到商户信息

当前实现不会在此接口内检查商户实名状态是否已通过。

GET /api/v1/domains/quota

查询当前 STS 所属平台的域名配额快照。

项目说明
所需 scopedomain:read
查询范围只返回当前令牌绑定平台的数据,不接受任何平台查询参数
统计状态仅统计 PENDINGACTIVESUSPENDED
不计入状态软删除域名和 REJECTED 状态域名

成功响应:

{
  "code": 200,
  "data": {
    "platformCompanyId": "67c7...",
    "platformCode": "demo",
    "allowWildcardDomains": false,
    "allowedRootDomains": ["citv.cc"],
    "platformDomains": {
      "used": 3,
      "limit": 5,
      "remaining": 2,
      "unlimited": false,
      "exceeded": false
    },
    "merchantDomains": {
      "used": 12,
      "limit": 30,
      "remaining": 18,
      "unlimited": false,
      "exceeded": false
    },
    "singleMerchantDomainLimit": {
      "limit": 5,
      "unlimited": false
    },
    "rootDomains": [
      {
        "rootDomain": "citv.cc",
        "platformDomains": {
          "used": 1,
          "limit": 2,
          "remaining": 1,
          "unlimited": false,
          "exceeded": false
        },
        "merchantDomains": {
          "used": 6,
          "limit": 20,
          "remaining": 14,
          "unlimited": false,
          "exceeded": false
        }
      }
    ]
  },
  "message": "OK"
}

字段说明:

字段说明
platformCompanyId平台公司文档 ID,即 STS 当前绑定的平台主体
platformDomains平台基础域名配额,即平台自身持有的二级域名数量
merchantDomains平台下所有商户域名总配额
singleMerchantDomainLimit单个商户可持有的域名上限,仅表达配置值,不返回某个商户的已用量
rootDomains已配置根域细分配额时返回;未配置时为空数组
limit = null未配置上限或无限制,此时 remaining = nullunlimited = true
exceeded = true当前已用量超过配置上限;等于上限时 remaining = 0,但不视为超出

常见错误:

code场景
400当前账户未关联可用平台
403缺少 domain:read
404平台主体不存在
500服务器内部错误

GET /api/v1/domains/{domain}

查询完整域名详情。

项目说明
路径参数domain
所需 scopedomain:read

说明:

  • domain 必须属于启用根域,否则返回 code=400
  • 若域名不存在,或存在但不属于当前账号可见公司集合,则返回 code=404
  • 当前实现按域名记录的 companyId 做归属判断,不会在此接口中额外用 platformId 放行。
  • 若要查询商户子域名,优先推荐使用 /api/v1/merchants/{merchantId}/domains/{domain}

PUT /api/v1/domains/{domain}/cname

更新完整域名的 CNAME。

项目说明
路径参数domain
所需 scopedomain:update

请求体:

字段类型必填说明
domainNamestring必须与路径中的 {domain} 完全一致(忽略大小写)
cnameValuestring新的 CNAME

成功响应:

{
  "code": 200,
  "data": {
    "domainId": "67c93f...",
    "domain": {
      "subdomain": "1rn5e.mengz",
      "rootDomain": "citv.cc",
      "cnameValue": "new.example.net"
    }
  },
  "message": "OK"
}

归属校验满足以下任一条件即可:

  • 域名记录的 companyId 属于当前账号可见公司。
  • 域名记录的 platformId 属于当前账号可见公司。

常见错误:

code场景
400参数错误、路径与请求体域名不一致、域名不在启用根域或格式不正确
404未找到域名资源

DELETE /api/v1/domains/{domain}

按完整域名删除记录。

项目说明
路径参数domain
所需 scopedomain:delete

成功响应:

{
  "code": 200,
  "data": { "deleted": true },
  "message": "OK"
}

删除语义:

  • 当前实现为软删除:会把域名记录标记为 deleted=true
  • 删除前会尝试移除 DNS 记录。
  • 如果删除的是平台二级域名,还会级联软删除其下一层直属商户子域名。
  • 例如删除 platform.citv.cc,可能会连带删除 shop01.platform.citv.cc

常见错误:

code场景
400domain 不在启用根域或格式不正确
404资源不存在,或底层未找到域名记录
500删除失败或其他服务内部错误

DNS 解析明细

GET /api/v1/dns-oss-records/daily

查询当前 STS 令牌绑定平台的日级 DNS 解析明细文件元数据与临时下载地址。该接口只返回当前平台上下文的数据,不接受客户端指定其他平台。

项目说明
所需 scopedns-records:read
鉴权STS Bearer
状态码HTTP 状态与响应体 code 一致:400 / 403 / 404 / 500

查询参数:

字段类型必填说明
datestring单日查询,格式 YYYY-MM-DD
fromDatestring区间起始日,格式 YYYY-MM-DD,包含当天
toDatestring区间结束日,格式 YYYY-MM-DD,不包含当天

必须传 date,或同时传 fromDatetoDate。区间查询最多 31 天,超过 31 天时请客户端拆分为多次请求。

单日查询成功响应:

{
  "code": 200,
  "message": "OK",
  "data": {
    "platformId": "platform_001",
    "date": "2026-05-01",
    "status": "complete",
    "format": "ndjson",
    "compression": "zstd",
    "recordCount": 12345,
    "partCount": 1,
    "totalSizeBytes": 1048576,
    "expiresAt": "2026-05-02T00:00:00Z",
    "parts": [
      {
        "partNo": 1,
        "fileName": "records-000001.ndjson.zst",
        "sizeBytes": 1048576,
        "sha256": "hex_sha256",
        "recordCount": 12345,
        "downloadUrl": "https://domaineross.citv.cn/dns-billing-records/published/2026-05-01/platform_001/records-000001.ndjson.zst?Expires=..."
      }
    ]
  }
}

区间查询成功响应:

{
  "code": 200,
  "message": "OK",
  "data": {
    "items": [
      {
        "date": "2026-05-01",
        "parts": []
      }
    ]
  }
}

区间内未生成明细文件的日期会被跳过;如果单日查询目标文件未生成,返回 404

常见错误:

code场景
400datefromDate / toDate 必填;解析明细查询范围超过 31 天
403缺少 dns-records:read
404解析明细文件未生成
500查询 DNS 解析明细失败,或底层 dnsx / OSS 签名服务异常

接入建议

  • 对写接口请使用业务幂等控制,尤其是商户注册与域名创建。
  • 429 建议使用指数退避重试。
  • 对返回 HTTP 200 但 code != 200 的场景,不要直接当作成功。
  • 商户注册接口已内置部分认证重试,客户端不应在极短时间内无脑并发重放。
  • 当前实现对大多数写操作都会记录审计日志。

建议接入方自行记录:

信息用途
调用时间排查请求链路
merchantId / domain定位业务对象
Bearer 令牌对应的接入账户定位调用方
响应体中的 codemessage判断业务结果与失败原因

On this page