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

# 预览套餐降级的影响

> GET /plans/downgrade-impact/

在提交结账前，预览哪些资源会阻碍降级，位于 **Management API** 主机（`api.scanova.io`）上，使用您的原始 Management API 密钥进行身份验证。

```
GET https://api.scanova.io/plans/downgrade-impact/
Authorization: 401f7ac837da42b97f613d789819ff93537bee6a
```

<ParamField query="target_plan" type="string" required>
  目标套餐的 slug（来自[列出可用套餐](/zh/api-reference/management-api/plans/available)的 `slug` 字段）。
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.scanova.io/plans/downgrade-impact/?target_plan=starter-scanova-io" \
    -H "Authorization: 401f7ac837da42b97f613d789819ff93537bee6a"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "violations": [
      {
        "codename": "TOTAL_QR_CODES",
        "quota_name": "Total QR Codes",
        "exceed_value": 12,
        "resolvable": true,
        "total_affected_count": 112,
        "affected_resources": ["Q07afe81aa0034c01", "Q19bd72cc1145d02"]
      }
    ],
    "current_plan_expiry": "2027-08-16",
    "days_remaining": 365
  }
  ```
</ResponseExample>

`violations` 为空数组表示目前降级是干净的——无需事先更改任何内容。此端点完全为只读，不会更改任何内容；它复用与实际结账完全相同的规则引擎，因此不会与真正执行降级时发生的情况有所出入。

### 响应字段

<ResponseField name="violations" type="array">
  针对目标套餐在账户当前使用量下无法满足的每一项配额，各有一条记录。

  <Expandable title="violation 的属性">
    <ResponseField name="codename" type="string">该配额的稳定标识符（例如 `TOTAL_QR_CODES`、`SHARED_USERS`）。</ResponseField>
    <ResponseField name="quota_name" type="string">人类可读的配额名称。</ResponseField>
    <ResponseField name="exceed_value" type="integer">账户当前超出目标套餐限制的数量。</ResponseField>
    <ResponseField name="resolvable" type="boolean">账户在降级前是否可以自行解决此问题（例如删除/停用部分资源）。</ResponseField>
    <ResponseField name="total_affected_count" type="integer">计入此配额的资源总数。</ResponseField>
    <ResponseField name="affected_resources" type="array">被计入的具体资源标识符（例如二维码的 `qrid` 值）——数量较多时可能是截断后的样本。</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="current_plan_expiry" type="string">
  当前套餐的到期日期；若套餐无到期日期，则为 `null`。
</ResponseField>

<ResponseField name="days_remaining" type="integer | null">
  距 `current_plan_expiry` 的剩余天数；若套餐无到期日期，则为 `null`。
</ResponseField>

若缺少 `target_plan`，则返回 `400`。

## 相关内容

* [列出可用套餐](/zh/api-reference/management-api/plans/available)——找到要预览降级的 `slug`。
* [当前套餐](/zh/api-reference/management-api/plans/current)——账户当前的套餐及配额分配情况。
* [Management API 概览](/zh/api-reference/management-api/overview)——适用于此端点的身份验证方案和配额规则。


## OpenAPI

````yaml api-reference/openapi/management-api.json GET /plans/downgrade-impact/
openapi: 3.1.0
info:
  title: Scanova Management API (v2)
  description: >-
    The complete Scanova Management API — every endpoint available at
    api.scanova.io (QR codes, folders, tags, leads, forms, analytics, plans,
    shared users & roles), plus the token-creation and usage-stats endpoints
    used to authenticate against it. Every path and request/response shape below
    was verified live against a real API key and the actual running backend
    (Phase 7, 2026-08-16) — not guessed from reading urls.py alone.
  version: 2.0.0
servers:
  - url: https://api.scanova.io
    description: Management API — QR/folder/tag/lead/form/analytics/plans endpoints
security:
  - apiKeyAuth: []
paths:
  /plans/downgrade-impact/:
    get:
      summary: Preview a plan downgrade's impact
      description: >-
        Read-only preview of which specific resources (e.g. QR codes over a new
        lower limit, shared users beyond a new seat count) would block a
        downgrade to `target_plan`, before committing to checkout. Reuses the
        exact same violation-detection logic real checkout enforces, so this
        preview can never disagree with what actually happens at order creation.
      operationId: getManagedDowngradeImpact
      parameters:
        - name: target_plan
          in: query
          required: true
          schema:
            type: string
          description: The target plan's slug.
      responses:
        '200':
          description: >-
            Violations that would block the downgrade (empty array if none),
            plus the current plan's remaining time.
          content:
            application/json:
              example:
                violations:
                  - codename: TOTAL_QR_CODES
                    quota_name: Total QR Codes
                    exceed_value: 12
                    resolvable: true
                    total_affected_count: 112
                    affected_resources:
                      - Q07afe81aa0034c01
                      - Q19bd72cc1145d02
                current_plan_expiry: '2027-08-16'
                days_remaining: 365
        '400':
          description: Missing `target_plan` query parameter.
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Send your Management API key as the raw value of the Authorization
        header — no "Bearer " or "Token " prefix, and no other characters.
        Example: `Authorization: 401f7ac837da42b97f613d789819ff93537bee6a`. A
        header containing more than one space-separated part is rejected
        outright. Requests also require the request's Host header to be the
        management API host (e.g. api.scanova.io) — the same key sent to the
        regular API host will not authenticate.

````