> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 自定义子域名

Alias 用于查询、设置和重置项目官方域名的前缀。例如把默认前缀改为 `event-demo`，官方域名后缀保持不变。它不会修改项目的 `url_id`，后续项目接口仍使用原来的 `project_id`；也不会绑定独立域名、触发构建或发布。

本节为 0915 新增接口，当前可在预发 8 联调，生产可用性以正式发布为准。以下示例使用预发地址；响应中的 `apps.example.com` 仅为域名后缀示意，真实后缀以接口返回的 `domain_suffix` 为准。

## 接口与权限

| 方法     | 路径（相对 /open/v1）                             | Scope         | 用途      |
| :----- | :------------------------------------------ | :------------ | :------ |
| GET    | `/projects/{project_id}/alias`              | `alias.read`  | 查询当前配置  |
| GET    | `/projects/{project_id}/alias/availability` | `alias.read`  | 检查候选前缀  |
| PUT    | `/projects/{project_id}/alias`              | `alias.write` | 设置或修改前缀 |
| DELETE | `/projects/{project_id}/alias`              | `alias.write` | 恢复默认前缀  |

* `project_id` 使用原项目公开 `url_id`，不是数据库主键，也不是新设置的 Alias。
* 查询和可用性检查要求项目访问地址的查看权限。设置和重置要求项目 Owner 或该租户管理员权限，且项目状态允许操作。
* Scope 与项目权限同时校验。`project.read`、`project.write` 或 `cli.compat` 不替代 `alias.read`、`alias.write`；`alias.write` 也不自动包含 `alias.read`。
* 开放集成账号必须使用团队委托 Token，不能用 OAuth 或 API Key 调用。其他账号的凭证类型按认证与授权规则执行；可配置项目 API Key 的账号可以选择 `alias.read` / `alias.write`，该 Key 仍只能访问绑定项目。
* 首次从默认前缀改成自定义前缀，需要可用的 `custom_domains` 权益。已有自定义前缀的改名、同值提交及恢复默认值不额外要求剩余权益。

## 前缀规则

`alias` 为必填字符串，服务端先去除首尾空白并转小写。自定义前缀归一化后须为 5～24 个字符，只允许英文字母、数字和中划线，首尾不能为中划线；不能传完整 URL、域名或包含下划线的自定义值。

其他项目已占用的前缀、其他项目的默认 `url_id`、系统保留名或审核不通过的名称不可用。名称占用检查不因官方后缀不同而放宽；项目改名后，其默认 `url_id` 仍被保留。提交本项目默认 `url_id` 时恢复默认，不受上述自定义名称格式限制。

PUT 不接受空字符串或 `null` 来表示重置。建议用 DELETE 显式重置；PUT 和 availability 的参数均只接受 `alias`，未知字段返回 400。

## 公共请求变量

```text theme={null}
BASE_URL="https://pre-1d-8.aliyun-inc.com/open/v1"
PROJECT_ID="your-project-url-id"
# ACCESS_TOKEN 使用已获得 alias.read / alias.write 的有效凭证。
# 开放集成账号使用团队委托 Token。
```

## 查询当前 Alias

```text theme={null}
curl --request GET \
  --url "${BASE_URL}/projects/${PROJECT_ID}/alias" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}"
```

成功返回 HTTP 200。GET、PUT、DELETE 使用相同的配置响应结构：

```text theme={null}
{
  "url_id": "your-project-url-id",
  "alias": "event-demo",
  "default_alias": "your-project-url-id",
  "domain_suffix": "apps.example.com",
  "primary_domain": "event-demo.apps.example.com",
  "is_custom_alias": true,
  "access_url": "https://event-demo.apps.example.com"
}
```

| 字段                | 类型      | 说明                       |
| :---------------- | :------ | :----------------------- |
| `url_id`          | string  | 项目原始公开标识，设置 Alias 不改变此值  |
| `alias`           | string  | 当前实际使用的官方子域名前缀           |
| `default_alias`   | string  | 默认前缀，为项目 url\_id 的小写形式   |
| `domain_suffix`   | string  | 已分配的官方域名后缀，本接口不修改后缀      |
| `primary_domain`  | string  | 当前官方完整域名，不包含协议           |
| `is_custom_alias` | boolean | 当前前缀是否不同于默认前缀            |
| `access_url`      | string  | 优先访问地址；已有独立域名时优先返回独立域名地址 |

`access_url` 仅表示配置的访问地址，不保证应用已经发布或当前可访问。有独立域名时，`access_url` 可能不同于 `https://` 加 `primary_domain`。

## 检查可用性

Query 参数 `alias` 必填。示例中的空白和大写会归一化为 `event-demo`：

```text theme={null}
curl --get \
  --url "${BASE_URL}/projects/${PROJECT_ID}/alias/availability" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --data-urlencode "alias= Event-Demo "
```

```text theme={null}
{
  "alias": "event-demo",
  "available": true,
  "primary_domain": "event-demo.apps.example.com"
}
```

`available` 为 boolean。名称不可用时通常仍返回 HTTP 200、`available:false`；格式错误返回 400，审核服务异常返回 503。本项目当前前缀视为可用。

可用性查询只检查名称，不预留名称，不保证调用方拥有写权限、剩余权益或后续写入一定成功。即使返回 true，实际 PUT 仍可能因并发占用返回 409，或因权益不足返回 403。

## 设置或修改 Alias

```text theme={null}
curl --request PUT \
  --url "${BASE_URL}/projects/${PROJECT_ID}/alias" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{"alias":"event-demo"}'
```

请求体仅包含必填字符串 `alias`。成功返回 HTTP 200 和更新后的完整配置。修改已设置的自定义前缀使用同一个 PUT 接口。

重复提交相同目标值具有幂等语义，不重复占用权益。发生网络超时可以先 GET 确认当前配置，再按需重试同值 PUT。响应成功表示配置已提交，关联配置同步可能稍后生效；同值 PUT 可用于重试关联同步。客户端应以返回配置为准，不把接口成功当作站点已经发布或域名已可访问。

改名不提供旧自定义地址保留或重定向保证，应更新对外分享地址。

## 恢复默认前缀

```text theme={null}
curl --request DELETE \
  --url "${BASE_URL}/projects/${PROJECT_ID}/alias" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}"
```

DELETE 不带请求字段，不删除项目或官方域名记录。成功返回 HTTP 200，此时 `alias` 等于 `default_alias`、`is_custom_alias` 为 false。重复 DELETE 仍返回默认配置，不要求剩余自定义域名权益。PUT 提交本项目默认 `url_id` 也可恢复默认。

## 限流

以下限额分别按接口桶统计；PUT 和 DELETE 共用写入桶。任一维度达到限制均可能返回 429。

| 操作        | 应用 / API Key 维度 / 分钟 | 应用与用户维度 / 分钟 | 项目维度 / 分钟 |
| :-------- | :------------------- | :----------- | :-------- |
| 查询配置      | 600                  | 60           | —         |
| 可用性检查     | 300                  | 30           | —         |
| 设置与重置（共用） | 300                  | 20           | 10        |

发生 429 时按 `Retry-After` 等待后重试。错误请求也可能计入已通过的限流检查，批量参数自测或轮询应控制频率。

## 常见错误

错误响应使用 `application/problem+json`，包含 `status`、`code`、`detail` 和 `trace_id`。保留 `trace_id` 便于排查；响应头也提供 `X-Meoo-Trace-Id`。

| HTTP 状态 / code                                                                     | 说明与处理                                   |
| :--------------------------------------------------------------------------------- | :-------------------------------------- |
| `400 invalid_request`                                                              | project\_id、alias、Content-Type 或请求字段不合法 |
| `401 invalid_token`                                                                | 凭证缺失、无效或过期                              |
| `403 insufficient_scope`                                                           | 缺少对应 alias.read / alias.write           |
| `403 forbidden`                                                                    | 凭证绑定项目不符，或开放集成账号使用了不支持的凭证类型             |
| `403 entitlement_required`                                                         | 首次设置自定义前缀时无可用 custom\_domains 权益        |
| `403 project_frozen / project_banned / project_under_review / project_unavailable` | 项目当前状态不允许修改                             |
| `404 not_found`                                                                    | 项目不存在、已删除，或当前身份不具有该操作所需项目权限             |
| `409 alias_unavailable`                                                            | 名称已占用、为保留名称、审核未通过或发生并发占用；选择其他名称后重试      |
| `409 domain_not_initialized`                                                       | 项目官方域名尚未初始化；稍后重试，持续出现时联系支持              |
| `429 temporarily_unavailable`                                                      | 调用频率超过限制，按 Retry-After 重试               |
| `503 service_unavailable`                                                          | 审核、权益查询或域名配置暂不可用；稍后重试                   |
| `500 server_error`                                                                 | 服务端异常，保留 trace\_id 联系支持                 |
