POST
/v1/members
建会员
Scope
members:write
商户自身
需 x-idempotency-key
两层幂等:external_member_id 天然去重(同一个外部号重复提交拿回
既有那一行,200 而不是 201),另加 x-idempotency-key 一层。
所以「已存在」不是错误,按状态码分支即可。
⚠ **该邮箱若已属于平台上另一个商户的会员,这里返回 400
invalid_request,建不出来。** 身份分层(把邮箱唯一索引从 users
上移到 identities)尚未落地,全局唯一索引还在,所以同一个自然人
暂时不能在两个商户下各建一个账号。
这不是「已注册」的提示:返回的是与「参数不合法」逐字相同的
通用响应,不带任何字样能区分出「这个邮箱在别处存在」——
区分开就等于送出一个跨商户会员探测接口。代价是你拿到 400 时无法
自行判断是格式错还是撞了这条限制,请按「换一个邮箱或联系我方」处理。
(同一个邮箱若本来就在你自己名下,我方会把那一行认作你的会员
并补上你传的 external_member_id,返回 200。)
建出来的账号带一个随机占位密码,不走我方的密码登录;你的会员
经你自己的 App 或我方托管屏进入。
会触发 member.created。
前置条件
- 该邮箱不属于平台上其他商户的会员
请求头
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-idempotency-key |
string | 必填 | UUID v4 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
external_member_id |
string | 必填 | 你自己的会员标识,最长 120 字符。它是这条线上的天然
幂等键,也是后续所有 x-on-behalf-of 的取值之一。 |
email |
string | 必填 | 会员邮箱。服务端转小写后存,只校验「含 @」。 它同时是我方身份层的归并键(见上)。 |
响应
200这个
external_member_id 已存在,回读既有那一行(本次未新建)201新建成功
{
"id": "mem_9f1c0c8e-6f2a-4c1d-9d0b-2a7e5b3f8c41",
"external_member_id": "u-10086",
"uid": "80031427",
"email": "alice@example.com",
"nickname": "",
"status": "normal",
"kyc_level": 0,
"created_at": "2026-08-12T09:30:00.000Z"
}400
invalid_request —— 三种情况同一个响应:body 非 JSON ·
external_member_id 为空或超 120 字符 / email 为空或不含 @ ·
该邮箱已属于另一个商户的会员(见上)403
insufficient_scope 缺 members:write409
idempotency_key_reused · idempotency_in_progress触发的事件
member.created— 看事件体
调用样例
curl -X POST 'https://api.zise.com/v1/members' \
-H 'authorization: Bearer $TOKEN' \
-H 'x-zise-merchant: $MERCHANT_ID' \
-H 'x-idempotency-key: $(uuidgen)' \
-H 'content-type: application/json' \
-d '{
"external_member_id": "u-10086",
"email": "alice@example.com"
}'
const res = await fetch(
"https://api.zise.com/v1/members",
{
method: "POST",
headers: {
"authorization": "Bearer $TOKEN",
"x-zise-merchant": "MERCHANT_ID",
"x-idempotency-key": "crypto.randomUUID()",
"content-type": "application/json"
},
body: JSON.stringify({
"external_member_id": "u-10086",
"email": "alice@example.com"
}),
},
);
// 金额一律按字符串读,不要 JSON.parse 成 number
const data = await res.json();
import requests
res = requests.post(
"https://api.zise.com/v1/members",
headers={
"authorization": "Bearer $TOKEN",
"x-zise-merchant": "$MERCHANT_ID",
"x-idempotency-key": "$(uuidgen)",
"content-type": "application/json"
},
json={
"external_member_id": "u-10086",
"email": "alice@example.com"
},
)
# 金额用 Decimal(str(...)),不要 float
data = res.json()