# piv.day API Reference

Full reference for the piv.day REST API: every endpoint, request body, response shape, error code and webhook. Exported from https://piv.day/api/docs for use with AI assistants.

---

## Getting started

Business 套餐的 REST API。Bearer 令牌、JSON、幂等端点、可预测的错误码。以下文档为每个端点提供请求和响应示例。

### Base URL

```
https://app.piv.day/api/v1
```

所有端点均位于此前缀下。单一环境——没有独立的 staging 主机。

### 身份验证

```
Authorization: Bearer YOUR_API_KEY
```

密钥在 dashboard 的 `设置 → API Keys` 中创建。每个密钥具有细粒度的权限（读取号码、发送 SMS、购买代理等）。泄露的 token 一键轮换——无需重新注册团队。

### 账户

**200 OK**
```
curl https://app.piv.day/api/v1/account \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**单一工具端点——当前账户余额和 email。可用于确认密钥有效且身份验证配置正确。**
```
{
  "success": true,
  "data": {
    "user_id": "usr-uuid-...",
    "balance": 150.50,
    "email": "u***@example.com",
    "team_id": null,
    "is_team_member": false
  }
}
```

GET /api/v1/account

### 响应格式

```
{
  "success": true,
  "data": { ... }
}
```

所有响应均为 JSON。出错时 `success` = `false`，响应体包含 `error.code` 和 `error.message`。

### Rate limits

**每个 API key 每分钟 100 次请求。该限制在所有端点间共享。流量峰值需要更高配额？联系 Telegram 支持，我们将快速提升上限。

超出限制时返回 `429 RATE_LIMITED` 和 `Retry-After` 响应头——表示下次请求前需等待的秒数。**
```
HTTP/1.1 429 Too Many Requests
Retry-After: 12

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded, retry in 12s"
  }
}
```

429 Too Many Requests

## 号码

购买、续期和恢复号码。接收和发送 SMS。启动 Google QR 验证。通过 webhook 订阅事件。

### 国家与价格列表

`GET /api/v1/numbers/countries`

返回可购买的国家，包含当前价格和 SMS 功能。所有价格均已含订阅折扣。

**Response fields**

| Field | Type | Description |
| --- | --- | --- |
| `country_code` | string | 两字母 ISO 国家代码（例如 `SE`）。 |
| `price_per_month` | number | 您套餐的最终价格——购买时实际扣费金额。Premium / Business 折扣已包含在内。 |
| `base_price` | number | 无折扣价格（Free 套餐）。用于比较，以便查看订阅节省了多少。 |
| `can_send_sms` | boolean | 此号码是否支持发送出站 SMS。 |
| `can_receive_sms` | boolean | 是否支持接收入站 SMS。 |
| `sms_send_price` | number\|null | 出站 SMS 价格，同样已含套餐折扣。当此国家不支持发送时为 `null`。 |

**curl**
```bash
curl https://app.piv.day/api/v1/numbers/countries \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": [
    {
      "country_code": "SE",
      "price_per_month": 4.00,
      "base_price": 5.00,
      "can_send_sms": true,
      "can_receive_sms": true,
      "sms_send_price": 0.25
    },
    {
      "country_code": "GB",
      "price_per_month": 3.00,
      "base_price": 3.00,
      "can_send_sms": true,
      "can_receive_sms": true,
      "sms_send_price": 0.20
    }
  ]
}
```

### 账户号码列表

`GET /api/v1/numbers`

返回账户号码分页列表，支持按国家、状态过滤及按号码或自定义名称搜索。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `limit` | integer | 每页记录数（默认 50，最大 200）。 |
| `offset` | integer | 分页偏移量。 |
| `country` | string | ISO 国家代码过滤器。 |
| `status` | string | 以下之一：`active`、`expired`、`pending_restore`。 |
| `search` | string | 按电话号码或自定义名称的子字符串搜索。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/numbers?country=SE&status=active&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "numbers": [
      {
        "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
        "phone_number": "+46764794425",
        "country_code": "SE",
        "status": "active",
        "created_at": "2026-05-01T10:00:00Z",
        "expires_at": "2026-05-31T10:00:00Z",
        "auto_renew": false,
        "custom_name": "Office line",
        "purchased_at": "2026-05-01T10:00:00Z",
        "next_renewal_date": "2026-05-31T10:00:00Z",
        "tags": ["support"],
        "can_send_sms": true,
        "can_receive_sms": true
      }
    ],
    "pagination": { "total": 1, "limit": 10, "offset": 0 }
  }
}
```

### 按 ID 获取单个号码

`GET /api/v1/numbers/{piv_num_id}`

完整号码记录：状态、日期、自动续期、标签、允许的 SMS 方向。

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NUMBER_NOT_FOUND` | 404 | 号码不存在或不属于该账户。 |

**curl**
```bash
curl https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "phone_number": "+46764794425",
    "country_code": "SE",
    "status": "active",
    "created_at": "2026-05-01T10:00:00Z",
    "expires_at": "2026-05-31T10:00:00Z",
    "auto_renew": false,
    "custom_name": "Office line",
    "purchased_at": "2026-05-01T10:00:00Z",
    "next_renewal_date": "2026-05-31T10:00:00Z",
    "tags": ["support"],
    "can_send_sms": true,
    "can_receive_sms": true
  }
}
```

### 购买号码

`POST /api/v1/numbers/purchase`

在所选国家购买一个号码，持续指定时长。费用从账户余额扣除。返回 `piv_num_id`，用于后续所有号码操作。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `country_code` * | string | ISO 国家代码。 |
| `duration_months` * | integer | 租用期限（月），最少 1 个月。 |
| `auto_renew` * | boolean | 购买后立即开启自动续期。 |
| `custom_name` | string | 号码的可选人性化名称。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `COUNTRY_NOT_AVAILABLE` | 400 | 该国家不可用或无定价。 |
| `NO_NUMBERS_AVAILABLE` | 400 | 目前所请求国家没有可用号码。 |
| `INSUFFICIENT_BALANCE` | 402 | 账户余额不足以完成购买。 |
| `VALIDATION_ERROR` | 400 | 请求体中存在无效字段。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/numbers/purchase \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "country_code": "SE",
    "duration_months": 1,
    "auto_renew": false,
    "custom_name": "My Sweden Number"
  }'
```

**200 OK**
```json
{
  "success": true,
  "cost": 5.00,
  "numbers": [
    {
      "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
      "country_code": "SE",
      "phone_number": "+46764794425",
      "created_at": "2026-05-01T10:00:00Z",
      "expires_at": "2026-05-31T10:00:00Z",
      "auto_renew": false,
      "custom_name": "My Sweden Number"
    }
  ]
}
```

### 续期号码

`POST /api/v1/numbers/{piv_num_id}/renew`

将活跃号码延长指定时间。费用在调用时扣除。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `duration_months` * | integer | 要增加的月数。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NUMBER_NOT_FOUND` | 404 | 号码不存在或不属于该账户。 |
| `COUNTRY_NOT_AVAILABLE` | 400 | 未找到该号码所在国家的定价。 |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足以续期。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/renew \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "duration_months": 1 }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "phone_number": "+46764794425",
    "old_expires_at": "2026-05-31T10:00:00Z",
    "new_expires_at": "2026-06-30T10:00:00Z",
    "cost": 5.00
  }
}
```

### 更新号码

`PATCH /api/v1/numbers/{piv_num_id}`

目前只能更新自定义名称。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `custom_name` * | string | 号码的新名称。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NUMBER_NOT_FOUND` | 404 | 号码不存在或不属于该账户。 |
| `VALIDATION_ERROR` | 400 | 请求体中存在无效值。 |

**curl**
```bash
curl -X PATCH https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "custom_name": "Support line" }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "phone_number": "+46764794425",
    "country_code": "SE",
    "status": "active",
    "custom_name": "Support line",
    "auto_renew": false,
    "expires_at": "2026-05-31T10:00:00Z",
    "tags": []
  }
}
```

### 自动续期管理

`PATCH /api/v1/numbers/{piv_num_id}/auto-renewal`

开启或关闭号码自动续期。开启后，续期费用在到期前 24 小时自动扣除。若余额不足，号码将过期；可在 7 天内通过 `POST /numbers/restore` 恢复。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `auto_renew` * | boolean | 自动续期标志的新值。 |

**curl**
```bash
curl -X PATCH https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/auto-renewal \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "auto_renew": true }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "phone_number": "+46764794425",
    "auto_renew": true
  }
}
```

### 恢复已过期号码

`POST /api/v1/numbers/restore`

在 7 天窗口期内恢复已过期号码。传入 `piv_num_id` 数组——号码将携带 SMS 历史和设置一并恢复。恢复费用高于购买新号码（含恢复倍数）——确认前在 Dashboard 显示精确金额。每个号码的最终状态通过 `number.restore_completed` webhook 送达；失败号码的退款自动计入余额。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `piv_num_ids` * | string[] | 要恢复的号码 ID 数组。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NO_RESTORABLE_NUMBERS` | 404 | 提供的所有号码均无法恢复（7 天窗口已过或不属于您）。 |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足以支付恢复费用。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/numbers/restore \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "piv_num_ids": [
      "vzPA1-kHKSg-EAL7e-Jqd3o",
      "abc12-defgh-ijklm-nopqr"
    ]
  }'
```

**200 OK**
```json
{
  "success": true,
  "queued": 2,
  "skipped": 0,
  "total_charged": 9.00,
  "numbers": [
    {
      "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
      "phone_number": "+46764794425",
      "status": "pending"
    }
  ]
}
```

### 号码 SMS 历史记录

`GET /api/v1/numbers/{piv_num_id}/sms`

以逆时间顺序返回该号码的入站和出站消息。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `limit` | integer | 返回的消息数量（默认 50，最大 200）。 |
| `offset` | integer | 分页偏移量。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "messages": [
      {
        "id": "42",
        "from_number": "+46764794425",
        "to_number": "+14155551234",
        "message_body": "Hello from piv.day",
        "direction": "outbound",
        "status": "delivered",
        "received_at": "2026-05-22T11:30:00Z"
      },
      {
        "id": "41",
        "from_number": "+14155551234",
        "to_number": "+46764794425",
        "message_body": "Hey, got your message!",
        "direction": "inbound",
        "status": "received",
        "received_at": "2026-05-22T11:35:00Z"
      }
    ],
    "pagination": { "total": 2, "limit": 20, "offset": 0 }
  }
}
```

### 发送 SMS

`POST /api/v1/numbers/{piv_num_id}/sms/send`

适用于允许出站发送的国家（如 CA、GB、SE）。消息费用在发送时扣除。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `to_number` * | string | 国际格式 (E.164) 的收件人号码。 |
| `message_body` * | string | 消息文本。支持 GSM-7 和 UCS-2。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NUMBER_NOT_FOUND` | 404 | 号码不存在或不属于该账户。 |
| `NUMBER_EXPIRED` | 403 | 号码已过期。 |
| `NUMBER_NOT_ACTIVE` | 400 | 号码当前状态不允许发送。 |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足以发送。 |
| `INVALID_MESSAGE_FORMAT` | 400 | 消息体超过允许长度或包含禁止字符。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to_number": "+14155551234",
    "message_body": "Hello from piv.day"
  }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "message_id": "42",
    "from_number": "+46764794425",
    "to_number": "+14155551234",
    "message_body": "Hello from piv.day",
    "status": "queued",
    "created_at": "2026-05-22T11:30:00Z"
  }
}
```

### 启动 Google QR 验证

`POST /api/v1/numbers/{piv_num_id}/verify`

使用提供的 URL 启动 Google QR 验证。结果——成功或失败——通过 verify.completed 或 verify.failed webhook 到达。任务入队时扣费。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `gv_url` * | string | 完整的 Google 验证 URL（从 Google 页面获取）。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NUMBER_NOT_FOUND` | 404 | 号码不存在或不属于您。 |
| `NUMBER_NOT_ACTIVE` | 400 | 号码未处于活跃状态。 |
| `SMS_DISABLED` | 400 | 此号码的 SMS 发送已禁用。 |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足以完成验证。 |
| `PROXY_DEAD` | 502 | 代理不可用——余额已退还。 |
| `QUEUE_FULL` | 503 | 队列已满，请稍后重试——余额已退还。 |
| `SERVER_UNAVAILABLE` | 503 | 自动化服务器不可用——余额已退还。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/verify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "gv_url": "https://gv.google.com/..." }'
```

**202 Accepted**
```json
{
  "success": true,
  "message": "Verification initiated"
}
```

## 代理

覆盖数十个国家的住宅 IPv6。批量购买、续期、Restore 保持相同登录名和密码，按所需格式导出。

### 服务器列表

`GET /api/v1/proxy/servers`

可用代理服务器及其价格。

**curl**
```bash
curl https://app.piv.day/api/v1/proxy/servers \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "servers": [
      {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "name": "EU-DE-01",
        "country": "DE",
        "socks5_port": 1080,
        "http_port": 3128,
        "price_per_proxy": 0.50
      },
      {
        "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
        "name": "EU-NL-01",
        "country": "NL",
        "socks5_port": 1080,
        "http_port": 3128,
        "price_per_proxy": 0.45
      }
    ]
  }
}
```

### 订单列表

`GET /api/v1/proxy/orders`

您的代理订单列表，支持按状态或关键词筛选。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `limit` | integer | 每页记录数。默认 100，最大 500。 |
| `offset` | integer | 分页偏移量。 |
| `status` | string | 状态筛选：`active`、`expired`。 |
| `search` | string | 在订单中搜索。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/proxy/orders?status=active&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "orders": [
      {
        "id": "ord-uuid-...",
        "country": "DE",
        "quantity": 10,
        "price_per_proxy": 0.50,
        "price_total": 5.00,
        "status": "active",
        "purchased_at": "2026-01-01T00:00:00Z",
        "expires_at": "2026-02-01T00:00:00Z"
      }
    ],
    "pagination": { "total": 1, "limit": 20, "offset": 0 }
  }
}
```

### 获取单个订单

`GET /api/v1/proxy/orders/{id}`

获取特定订单的详细信息，包括代理凭据列表。

**curl**
```bash
curl https://app.piv.day/api/v1/proxy/orders/ord-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "order": {
      "id": "ord-uuid-...",
      "country": "DE",
      "quantity": 10,
      "price_per_proxy": 0.50,
      "price_total": 5.00,
      "status": "active",
      "purchased_at": "2026-01-01T00:00:00Z",
      "expires_at": "2026-02-01T00:00:00Z",
      "created_at": "2026-01-01T00:00:00Z",
      "items": [
        {
          "login": "user1",
          "password": "pass1",
          "host": "185.1.2.3",
          "socks5_port": 1080,
          "http_port": 3128,
          "ipv6": "2a00:1:2:3::1"
        }
      ]
    }
  }
}
```

### 购买代理

`POST /api/v1/proxy/purchase`

在所选服务器上购买代理。一次请求创建一个包含 N 个代理的订单（最多 500 个）。不支持批量订单 — 如需更多请重复调用该方法。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `server_id` * | string | 来自 `GET /proxy/servers` 的服务器 ID。 |
| `quantity` * | integer | 购买的代理数量（1–500）。 |
| `months` * | integer | 租用期（月），取值范围 1–12。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足。 |
| `NOT_FOUND` | 404 | 代理服务器未找到或处于非活动状态。 |
| `VALIDATION_ERROR` | 400 | 请求体无效。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/proxy/purchase \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "server_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "quantity": 5,
    "months": 1
  }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "order": {
      "id": "ord-uuid-...",
      "country": "DE",
      "quantity": 5,
      "price_total": 2.50,
      "status": "active",
      "expires_at": "2026-02-01T00:00:00Z",
      "created_at": "2026-01-01T00:00:00Z",
      "items": [
        {
          "login": "user1",
          "password": "pass1",
          "host": "185.1.2.3",
          "socks5_port": 1080,
          "http_port": 3128,
          "ipv6": "2a00:1:2:3::1"
        },
        {
          "login": "user2",
          "password": "pass2",
          "host": "185.1.2.3",
          "socks5_port": 1080,
          "http_port": 3128,
          "ipv6": "2a00:1:2:3::2"
        }
      ]
    }
  }
}
```

### 续期订单

`POST /api/v1/proxy/orders/{id}/renew`

将活跃的代理订单延长指定月数。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `months` * | integer | 要添加的月数。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../renew \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "months": 1 }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "order_id": "ord-uuid-...",
    "cost": 5.00,
    "new_expires_at": "2026-03-01T00:00:00Z"
  }
}
```

### Restore 已过期订单

`POST /api/v1/proxy/orders/{id}/restore`

无需重新购买即可恢复已过期的代理订单。登录名、密码、IPv6 地址、国家与绑定关系 — 均与之前相同。有效期延长 1 个月。无需重新配置指纹浏览器。

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../restore \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "order_id": "ord-uuid-...",
    "quantity": 10,
    "total_cost": 5.00,
    "expires_at": "2026-03-01T00:00:00Z"
  }
}
```

### 导出代理列表

`GET /api/v1/proxy/orders/{id}/export`

将订单的代理凭据导出为文本列表（login:password@host:port）。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `format` | string | 导出格式：`socks5`、`http` 或 `both`（默认 `socks5`）。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../export?format=socks5" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "content": "user1:pass1@1.2.3.4:1080\nuser2:pass2@1.2.3.4:1080",
    "filename": "piv-day-proxy-ord-uuid--socks5.txt",
    "format": "socks5",
    "count": 2
  }
}
```

## 域名

无需KYC即可搜索和注册，自动配置Cloudflare和SSL，通过API管理DNS记录和NS服务器。

### 可用性检查

`GET /api/v1/domains/search`

检查域名是否可用及注册费用。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `q` * | string | 要查询的域名，例如 `mysite.com`。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/domains/search?q=mysite.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "domain": "mysite.com",
    "available": true,
    "create_price": 12.50,
    "renew_price": 12.50,
    "currency": "USD"
  }
}
```

### 域名列表

`GET /api/v1/domains`

您的已注册域名列表，支持过滤。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `limit` | integer | 每页记录数。默认100，最大500。 |
| `offset` | integer | 分页偏移量。 |
| `status` | string | 域名状态：`active`、`pending`、`expired`。 |
| `cloudflare` | string | 按Cloudflare状态过滤：`true` 或 `false`。 |
| `auto_renew` | string | 按自动续费过滤：`true` 或 `false`。 |
| `search` | string | 按域名搜索。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/domains?status=active&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "domains": [
      {
        "id": "dom-uuid-...",
        "domain_name": "mysite.com",
        "status": "active",
        "registered_at": "2026-01-01T00:00:00Z",
        "expires_at": "2027-01-01T00:00:00Z",
        "auto_renew": true,
        "cloudflare_enabled": true,
        "cloudflare_status": "active",
        "ssl_type": "lets_encrypt",
        "ssl_status": "active",
        "ssl_mode": "full",
        "ssl_expires_at": "2026-04-01T00:00:00Z",
        "created_at": "2026-01-01T00:00:00Z",
        "updated_at": "2026-01-01T00:00:00Z"
      }
    ],
    "pagination": { "total": 1, "limit": 20, "offset": 0 }
  }
}
```

### 注册域名

`POST /api/v1/domains`

注册新域名。请求是异步的——返回 `queue_id` 用于跟踪。Cloudflare 开启：不能传递 `nameservers`；可选传递 `dns_records` 和 `ssl_mode`。Cloudflare 关闭：不能传递 `dns_records` 或 `ssl_mode`；`nameservers` 为必填项（至少2个）。我们从不暴露Cloudflare的nameserver。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `domain` * | string | 要注册的域名，例如 `mysite.com`。 |
| `period` * | integer | 注册年限（1–10）。 |
| `cloudflare` * | boolean | 自动将域名接入Cloudflare。 |
| `auto_renew` * | boolean | 启用自动续费。 |
| `ssl_mode` | string | `flexible` \| `full` \| `strict`。仅在 `cloudflare: true` 时有效。 |
| `nameservers` | string[] | `cloudflare: false` 时必填（≥2个NS）。`cloudflare: true` 时禁止传递。 |
| `dns_records` | object[] | 初始DNS记录。仅在 `cloudflare: true` 时有效。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `DOMAIN_NOT_AVAILABLE` | 400 | 该域名不可注册。 |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足。 |
| `VALIDATION_ERROR` | 400 | 请求体无效。 |

**Cloudflare 开启**
```bash
curl -X POST https://app.piv.day/api/v1/domains \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "mysite.com",
    "period": 1,
    "cloudflare": true,
    "auto_renew": true,
    "ssl_mode": "full",
    "dns_records": [
      { "type": "A", "name": "@", "content": "1.2.3.4", "proxied": true }
    ]
  }'
```

**Cloudflare 关闭 — 自定义NS**
```bash
curl -X POST https://app.piv.day/api/v1/domains \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "mysite.com",
    "period": 1,
    "cloudflare": false,
    "auto_renew": false,
    "nameservers": ["ns1.myhost.com", "ns2.myhost.com"]
  }'
```

**202 Accepted**
```json
{
  "success": true,
  "data": {
    "queue_id": "que-uuid-...",
    "domain": {
      "id": "dom-uuid-...",
      "domain_name": "mysite.com",
      "status": "purchasing",
      "period": 1,
      "cloudflare_enabled": true,
      "auto_renew": true,
      "ssl_mode": "full",
      "created_at": "2026-01-01T00:00:00Z"
    }
  }
}
```

### 注册任务状态

`GET /api/v1/domains/queue/{id}`

查询注册或续费队列条目的状态。当状态为 `completed` 时，响应中已包含完整的域名信息——无需再单独调用 `/domains/{id}`。

**curl**
```bash
curl https://app.piv.day/api/v1/domains/queue/que-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**pending / processing**
```json
{
  "success": true,
  "data": {
    "queue_id": "que-uuid-...",
    "domain": "mysite.com",
    "status": "pending"
  }
}
```

**completed — 完整信息**
```json
{
  "success": true,
  "data": {
    "queue_id": "que-uuid-...",
    "status": "completed",
    "domain": {
      "id": "dom-uuid-...",
      "domain_name": "mysite.com",
      "status": "active",
      "registered_at": "2026-01-01T12:00:00Z",
      "expires_at": "2027-01-01T12:00:00Z",
      "auto_renew": true,
      "cloudflare_enabled": true,
      "cloudflare_status": "active",
      "ssl_type": "lets_encrypt",
      "ssl_status": "active",
      "ssl_mode": "full",
      "ssl_expires_at": "2026-04-01T00:00:00Z",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T12:00:00Z",
      "dns_records": [
        { "name": "@", "type": "A", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true }
      ]
    }
  }
}
```

### 获取单个域名

`GET /api/v1/domains/{id}`

获取已注册域名的完整信息。`nameservers` 字段仅在 `cloudflare_enabled: false` 时出现。

**curl**
```bash
curl https://app.piv.day/api/v1/domains/dom-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "domain": {
      "id": "dom-uuid-...",
      "domain_name": "mysite.com",
      "status": "active",
      "registered_at": "2026-01-01T12:00:00Z",
      "expires_at": "2027-01-01T12:00:00Z",
      "auto_renew": true,
      "cloudflare_enabled": true,
      "cloudflare_status": "active",
      "ssl_type": "lets_encrypt",
      "ssl_status": "active",
      "ssl_mode": "full",
      "ssl_expires_at": "2026-04-01T00:00:00Z",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T12:00:00Z",
      "dns_records": [
        { "name": "@", "type": "A", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true },
        { "name": "www", "type": "CNAME", "content": "mysite.com", "ttl": 1, "priority": null, "proxied": true }
      ]
    }
  }
}
```

### 续费域名

`POST /api/v1/domains/{id}/renew`

续费域名注册。返回 `queue_id` 用于跟踪。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `period` * | integer | 续费年数。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../renew \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "period": 1 }'
```

**202 Accepted**
```json
{
  "success": true,
  "data": {
    "queue_id": "que-uuid-...",
    "domain_id": "dom-uuid-...",
    "expires_at": "2027-01-01T12:00:00Z"
  }
}
```

### 自动续费开关

`POST /api/v1/domains/{id}/auto-renew`

开启或关闭域名自动续费。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `auto_renew` * | boolean | 新的标志值。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../auto-renew \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "auto_renew": true }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "id": "dom-uuid-...",
    "auto_renew": true
  }
}
```

### 域名DNS记录

`GET /api/v1/domains/{id}/dns`

列出域名的DNS记录（通过Cloudflare）。

**curl**
```bash
curl https://app.piv.day/api/v1/domains/dom-uuid-.../dns \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "records": [
      {
        "id": "rec-uuid-...",
        "type": "A",
        "name": "@",
        "content": "1.2.3.4",
        "ttl": 1,
        "priority": null,
        "proxied": true
      }
    ]
  }
}
```

### 添加DNS记录

`POST /api/v1/domains/{id}/dns`

创建新的DNS记录。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `type` * | string | 记录类型：`A`、`AAAA`、`CNAME`、`MX`、`TXT` 等。 |
| `name` * | string | 记录名称，例如 `@` 或 `subdomain`。 |
| `content` * | string | 记录值。 |
| `ttl` | integer | TTL（秒）（`1` = 自动）。 |
| `proxied` | boolean | 通过Cloudflare代理。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../dns \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "A",
    "name": "@",
    "content": "1.2.3.4",
    "ttl": 1,
    "proxied": true
  }'
```

**201 Created**
```json
{
  "success": true,
  "data": {
    "record": {
      "id": "rec-uuid-...",
      "type": "A",
      "name": "@",
      "content": "1.2.3.4",
      "ttl": 1,
      "priority": null,
      "proxied": true
    }
  }
}
```

### 修改DNS记录

`PUT /api/v1/domains/{id}/dns/{recordId}`

按ID更新现有DNS记录。只有传递的字段会被覆盖。

**curl**
```bash
curl -X PUT https://app.piv.day/api/v1/domains/dom-uuid-.../dns/rec-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "5.6.7.8" }'
```

### 删除DNS记录

`DELETE /api/v1/domains/{id}/dns/{recordId}`

按ID删除DNS记录。

**curl**
```bash
curl -X DELETE https://app.piv.day/api/v1/domains/dom-uuid-.../dns/rec-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### 启用Cloudflare

`POST /api/v1/domains/{id}/cloudflare`

为域名启用Cloudflare。我们不返回Cloudflare的nameserver——委派由我们这边配置。不支持通过此endpoint禁用Cloudflare。

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../cloudflare \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "domain_id": "dom-uuid-...",
    "ssl_mode": "flexible"
  }
}
```

### 设置NS服务器

`POST /api/v1/domains/{id}/ns-servers`

为域名设置自定义NS服务器。

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../ns-servers \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "nameservers": ["ns1.example.com", "ns2.example.com"] }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "nameservers": [
      { "nameserver": "ns1.example.com", "order_index": 1 },
      { "nameserver": "ns2.example.com", "order_index": 2 }
    ]
  }
}
```

## 白页

按细分领域和tier生成白页。每个站点均独一无二。更换域名和联系信息无需重新生成。

### 获取tier列表

`GET /api/v1/whites/tiers`

可用的生成tier及其价格。`price` 是已按您账户调整（含订阅折扣）的单次生成价格，为单一数值。`quality: "premium"` 费用更高（在创建时计算）。博客功能仅限 `v2_tier3`：前3篇文章已包含，每篇额外文章（最多20篇）按 `extra_article_price` 计费。

**curl**
```bash
curl https://app.piv.day/api/v1/whites/tiers \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "tiers": [
      {
        "tier_key": "v2_tier1",
        "name": "Landing",
        "generator_version": "v2",
        "min_articles": 0,
        "max_articles": 0,
        "price": 3.00,
        "extra_article_price": null
      },
      {
        "tier_key": "v2_tier2",
        "name": "Multi-page",
        "generator_version": "v2",
        "min_articles": 0,
        "max_articles": 0,
        "price": 6.00,
        "extra_article_price": null
      },
      {
        "tier_key": "v2_tier3",
        "name": "Full + Blog",
        "generator_version": "v2",
        "min_articles": 3,
        "max_articles": 20,
        "price": 10.00,
        "extra_article_price": 1.50
      }
    ]
  }
}
```

### 获取white列表

`GET /api/v1/whites`

您的生成任务列表，支持筛选。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `limit` | integer | 每页条数。默认100，最大500。 |
| `offset` | integer | 分页偏移量。 |
| `status` | string | `queued` \| `processing` \| `done` \| `failed`。 |
| `tier_key` | string | `v2_tier1` \| `v2_tier2` \| `v2_tier3`。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/whites?status=done&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "whites": [
      {
        "id": "job-uuid-...",
        "name": "My White",
        "status": 10,
        "tier_key": "v2_tier3",
        "quality": "standard",
        "niche": "IT Consulting",
        "country": "DE",
        "language": "de",
        "domain": "mysite.com",
        "result_url": null,
        "created_at": "2026-01-01T00:00:00Z"
      }
    ],
    "pagination": { "total": 1, "limit": 20, "offset": 0 }
  }
}
```

### 开始生成

`POST /api/v1/whites`

将white-page生成任务加入队列。费用立即扣除。最终状态通过 `white.completed` / `white.failed` webhook 推送，也可通过 `GET /whites/{id}` 轮询。

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `name` * | string | 任务名称（2–20个字符）。 |
| `tier_key` * | string | `v2_tier1` \| `v2_tier2` \| `v2_tier3`。 |
| `niche` * | string | 站点细分领域（最多25个字符）。 |
| `country` * | string | 国家代码（ISO 3166-1 alpha-2）。 |
| `language` * | string | 站点主要语言（ISO 639-1）。 |
| `quality` | string | `standard` \| `premium`（默认 `standard`）。 |
| `languages` | string[] | 语言列表。第一种语言含在价格内，每种额外语言需额外付费。 |
| `domain` | string | 完整域名（如 `example.com`）。不自动补全。 |
| `email` | string | 完整邮箱地址（如 `info@example.com`）。不自动补全。 |
| `phone` | string | 联系电话。 |
| `address` | string | 公司地址。 |
| `legal_name` | string | 法定名称。 |
| `style_hint` | string | 设计风格（Random、简约、企业风等）。 |
| `keywords` | string[] | SEO关键词。 |
| `banned_words` | string[] | 内容中禁止使用的词语。 |
| `blog_count` | integer | 博客文章数量 3–20。仅限 `v2_tier3`。超过3篇的文章需额外付费。 |
| `contacts_mode` | string | `same` \| `template`。 |
| `contacts_template` | string | 联系页面模板（当 `contacts_mode=template` 时）。 |
| `facebook` | string | Facebook页面完整URL。 |
| `instagram` | string | Instagram主页完整URL。 |
| `linkedin` | string | LinkedIn主页完整URL。 |
| `youtube` | string | YouTube频道完整URL。 |
| `tiktok` | string | TikTok主页完整URL。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足。 |
| `INVALID_TIER` | 400 | 未找到对应key的tier。 |
| `VALIDATION_ERROR` | 400 | 请求体无效。 |

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/whites \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Tech Blog DE",
    "tier_key": "v2_tier3",
    "niche": "IT Consulting",
    "country": "DE",
    "language": "de",
    "quality": "premium",
    "languages": ["de", "en"],
    "domain": "techblog-de.com",
    "email": "info@techblog-de.com",
    "phone": "+49 30 123456",
    "address": "Berliner Str. 1, 10115 Berlin",
    "legal_name": "TechBlog GmbH",
    "style_hint": "Корпоративный",
    "keywords": ["IT", "consulting", "cloud"],
    "banned_words": ["cheap", "free"],
    "blog_count": 8,
    "contacts_mode": "same",
    "facebook": "https://facebook.com/techblogde",
    "instagram": "https://instagram.com/techblogde",
    "linkedin": "https://linkedin.com/company/techblogde"
  }'
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "status": "queued",
    "white": {
      "id": "job-uuid-...",
      "name": "Tech Blog DE",
      "status": 0,
      "tier_key": "v2_tier3",
      "quality": "premium",
      "niche": "IT Consulting",
      "country": "DE",
      "language": "de",
      "domain": "techblog-de.com",
      "result_url": null,
      "created_at": "2026-01-01T00:00:00Z"
    }
  }
}
```

### 获取单个white

`GET /api/v1/whites/{id}`

获取生成任务的当前状态。

**curl**
```bash
curl https://app.piv.day/api/v1/whites/job-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "white": {
      "id": "job-uuid-...",
      "name": "Tech Blog DE",
      "status": 10,
      "tier_key": "v2_tier3",
      "quality": "premium",
      "niche": "IT Consulting",
      "country": "DE",
      "language": "de",
      "domain": "techblog-de.com",
      "result_url": null,
      "created_at": "2026-01-01T00:00:00Z"
    }
  }
}
```

### 下载压缩包

`GET /api/v1/whites/{id}/download`

获取已完成white-page压缩包的短期签名链接。链接有效期约5分钟（见 `expires_at`）。若已过期，再次调用 `/download` 即可获取新链接。若white-page尚未生成，返回 `409 NOT_READY`。

**Query parameters**

| Field | Type | Description |
| --- | --- | --- |
| `format` | string | 压缩包格式。默认为 `php`。 |

**Errors**

| Code | HTTP | When it fires |
| --- | --- | --- |
| `NOT_READY` | 409 | white-page仍在生成中——请在 `white.completed` 之后重试。 |

**curl**
```bash
curl "https://app.piv.day/api/v1/whites/job-uuid-.../download?format=php" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**200 OK**
```json
{
  "success": true,
  "data": {
    "url": "https://strg.piv.day/download/<user_id>/<job_id>?format=php&token=<hmac>&filename=<name>.zip",
    "filename": "example.com_2026-05-28_DE_en.zip",
    "format": "php",
    "expires_at": "2026-05-28T14:46:00Z"
  }
}
```

### 更换域名和联系信息

`POST /api/v1/whites/{id}/config`

无需重新生成即可更新white-page中的公司联系数据。

**curl**
```bash
curl -X POST https://app.piv.day/api/v1/whites/job-uuid-.../config \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company": "My Brand",
    "domain": "newdomain.com",
    "email": "info@newdomain.com",
    "phone": "+49 30 123456",
    "address": "Berliner Str. 1, Berlin",
    "legal": "My Brand GmbH"
  }'
```

## Webhooks

我们向您的 URL 发送一个普通的 POST 请求，正文为 JSON。所有事件的格式相同：`event_type`、`timestamp` 和一个 `data` 块。您的服务器应在 5 秒内以任意 2xx 响应。

```
POST <your webhook URL>
Content-Type: application/json
User-Agent: piv.day-webhook/1.0

{
  "event_type": "<event identifier>",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": { ... }
}
```

**Retries.** 在非 2xx 或超时时 — 最多重试 3 次，退避间隔为 1s / 2s / 4s。完整的投递历史记录在 dashboard 的 API 密钥页面中。如果三次都失败，该事件将标记为 failed，可手动重新发送。

**Security.** 使用 HTTPS 端点。每个请求都携带 `User-Agent: piv.day-webhook/1.0` 请求头。Webhook URL 在 API 密钥配置文件中设置。

### All events

| Event | When it fires |
| --- | --- |
| `sms.received` | 一位受信任的发件人刚刚向您的某个号码发送了短信。 |
| `sms.status_updated` | 一条外发短信更改了状态 — 已送达、失败等。 |
| `number.restore_completed` | 一次批量 Restore 已完成 — 最终汇总结果在这里。 |
| `verify.completed` | Google 账户验证已成功完成。 |
| `verify.failed` | 出了点问题 — Google 没有接受。 |
| `proxy.expires_soon` | 代理订单还有大约三天到期。 |
| `domain.registered` | 注册订单成功完成 — 域名已上线。 |
| `domain.failed` | 订单未完成 — 常见原因：域名刚被他人注册。 |
| `domain.expires_soon` | 域名到期前还剩大约一周。 |
| `white.completed` | White 生成任务已成功完成。 |
| `white.failed` | 任务失败 — 资金退回至余额。 |

### 收到您号码的短信

**`sms.received`**

最常见的是广告网络的验证码。Payload 包含原始文本和自动识别的验证码（如有），可直接传入您的工作流而无需解析。来自已知垃圾邮件发件人的消息不会被转发。

```json
{
  "event_type": "sms.received",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "text": "Your verification code is 123456",
    "code": "123456",
    "country": "SE",
    "received_at": "2026-05-22T12:34:56Z"
  }
}
```

### 外发短信状态已更改

**`sms.status_updated`**

当您从自己的号码发送确认消息并需要知道是否真正送达时非常有用。如果状态为 failed，运营商的错误代码和消息包含在 payload 中。

```json
{
  "event_type": "sms.status_updated",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "message_id": "42",
    "old_status": "sent",
    "new_status": "delivered",
    "error_code": null,
    "error_message": null
  }
}
```

### 号码恢复已完成

**`number.restore_completed`**

包含两个列表 — 哪些号码已恢复，哪些未恢复。未恢复号码的退款金额也在 payload 中。方便脚本智能重试。

```json
{
  "event_type": "number.restore_completed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "restored": [
      {
        "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
        "phone_number": "+46764794425",
        "country": "SE"
      }
    ],
    "failed": [
      {
        "piv_num_id": "abc12-defgh-ijklm-nopqr",
        "phone_number": "+46123456789",
        "country": "SE",
        "refunded": 7.50
      }
    ],
    "total_restored": 1,
    "total_failed": 1,
    "total_refunded": 7.50
  }
}
```

### Google QR 验证成功

**`verify.completed`**

如果在流程中收到了验证码短信，它已经在这里了 — 无需额外获取。captured_phone 和 captured_message 包含 Google 发送的内容。

```json
{
  "event_type": "verify.completed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "task_id": 12,
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "status": "sms_sent",
    "captured_phone": "+14155551234",
    "captured_message": "Your Google verification code is 123456",
    "sms_message_id": 42,
    "sms_status": "queued"
  }
}
```

### Google QR 验证失败

**`verify.failed`**

error_code 具体说明了原因 — 超时、拒绝、无效的 URL。验证失败的费用将自动退还至余额。

```json
{
  "event_type": "verify.failed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "task_id": 12,
    "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o",
    "status": "failed",
    "error_code": "VERIFY_TIMEOUT",
    "error_message": "Verification timed out"
  }
}
```

### 代理即将到期

**`proxy.expires_soon`**

专为非自动续期用户设计：您提前看到并决定 — 续期还是结束活动。将其连接到 POST /proxy/orders/{id}/renew 以实现全自动续期。

```json
{
  "event_type": "proxy.expires_soon",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "order_id": "ord-uuid-...",
    "country": "DE",
    "quantity": 10,
    "expires_at": "2026-05-25T00:00:00Z"
  }
}
```

### 域名已注册

**`domain.registered`**

如果您在购买时申请了 Cloudflare 和 SSL，两者均已启用 — cloudflare_enabled 反映了状态。您可以立即添加 DNS 记录或部署网站。

```json
{
  "event_type": "domain.registered",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "domain_id": "dom-uuid-...",
    "domain_name": "mysite.com",
    "registered_at": "2026-05-22T12:34:56Z",
    "expires_at": "2027-05-22T12:34:56Z",
    "cloudflare_enabled": true
  }
}
```

### 域名注册失败

**`domain.failed`**

error 字段包含人类可读的原因。费用退回至余额。选择另一个名称重新下单。

```json
{
  "event_type": "domain.failed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "domain_id": "dom-uuid-...",
    "domain_name": "mysite.com",
    "error": "Domain is no longer available"
  }
}
```

### 域名即将到期

**`domain.expires_soon`**

当关闭自动续期时很有用：您有时间在域名进入赎回期之前手动续期。auto_renew 标志告诉您是否需要干预。

```json
{
  "event_type": "domain.expires_soon",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "domain_id": "dom-uuid-...",
    "domain_name": "mysite.com",
    "expires_at": "2026-05-29T00:00:00Z",
    "auto_renew": false
  }
}
```

### White 已生成

**`white.completed`**

归档文件可通过 GET /whites/{id}/download 获取。如果 White 设置了域名，sitemap 和联系方式已配置好 — 可直接部署。

```json
{
  "event_type": "white.completed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "job_id": "job-uuid-...",
    "name": "My White",
    "tier_key": "t1",
    "country": "DE"
  }
}
```

### White 生成失败

**`white.failed`**

error 字段解释了原因。立即通过 POST /whites 启动新任务 — 不损失资金。

```json
{
  "event_type": "white.failed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "job_id": "job-uuid-...",
    "name": "My White",
    "error": "Generation failed"
  }
}
```

## Error codes

所有错误均采用相同格式：HTTP 状态码 + `error.code` 字段 + `error.message` 中的可读消息。

```json
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Not enough balance: required $5.00, available $1.20"
  }
}
```

| Code | HTTP | When it fires |
| --- | --- | --- |
| `UNAUTHORIZED` | 401 | 密钥缺失、已过期或已被撤销。 |
| `INSUFFICIENT_PERMISSIONS` | 403 | 该密钥没有执行此操作所需的 scope。 |
| `PERMISSION_DENIED` | 403 | 账户级别的访问权限不允许此操作（例如功能已禁用）。 |
| `VALIDATION_ERROR` | 400 | 请求体无效。错误消息会说明是哪个字段以及原因。 |
| `NUMBER_NOT_FOUND` | 404 | 该号码不存在或不属于此账户。 |
| `NUMBER_EXPIRED` | 403 | 该号码已过期——请在 7 天内使用 Restore 恢复，或购买新号码。 |
| `NUMBER_NOT_ACTIVE` | 400 | 该号码处于不允许此操作的状态。 |
| `INSUFFICIENT_BALANCE` | 402 | 余额不足，无法完成此操作。 |
| `INVALID_MESSAGE_FORMAT` | 400 | SMS 内容过长或包含不允许的字符。 |
| `COUNTRY_NOT_AVAILABLE` | 400 | 该国家/地区不支持购买或续费。 |
| `NO_NUMBERS_AVAILABLE` | 400 | 当前所选国家/地区没有可用号码。 |
| `NO_RESTORABLE_NUMBERS` | 404 | 所提供的号码均已无法恢复。 |
| `RATE_LIMITED` | 429 | 超过 rate limit。请等待 `Retry-After` 响应头指定的时间。 |
| `INTERNAL_ERROR` | 500 | 我们这边出现了问题。如果持续发生，请联系技术支持。 |
