# Auth Center Machine Artifacts

契约版本：1.0.0 · OpenAPI 3.0.3

Application-scoped bearer API. Stable publication requires the existing administrator UI and session/CSRF API. All data is wrapped in the standard envelope.

## 服务地址

`/api/v1`

## 认证方式

### machineToken



```json
{
  "type": "http",
  "scheme": "bearer",
  "bearerFormat": "acr_256-bit-random"
}
```

### adminSession



```json
{
  "type": "apiKey",
  "in": "cookie",
  "name": "ac_access"
}
```

### csrfCookie



```json
{
  "type": "apiKey",
  "in": "cookie",
  "name": "ac_csrf"
}
```

## GET /admin/release-tokens

List redacted credentials (release-tokens:write)



操作 ID：`listReleaseTokens`

认证：adminSession

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application_id | query | 是 |  {"type":"string","format":"uuid"} |


### 响应

#### HTTP 200

Envelope with data=array of Token, never raw tokens or hashes

#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /admin/release-tokens

Create one application credential; raw token shown once (release-tokens:write)



操作 ID：`createReleaseToken`

认证：adminSession + csrfCookie

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| Origin | header | 是 | Must exactly match APP_ORIGIN {"type":"string"} |
| X-CSRF-Token | header | 是 | Must match ac_csrf cookie {"type":"string","minLength":32} |

### 请求体（必需）



`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| application_id | string | 是 |  |
| name | string | 是 |  |
| scopes | array | 是 |  |
| expires_at | string | 是 | Future, at most 90 days from now |
```json
{
  "type": "object",
  "required": [
    "application_id",
    "name",
    "scopes",
    "expires_at"
  ],
  "properties": {
    "application_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "scopes": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "enum": [
          "releases:read",
          "releases:create",
          "uploads:write",
          "publish:development",
          "publish:staging"
        ]
      }
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Future, at most 90 days from now"
    }
  }
}
```

### 响应

#### HTTP 200

Store token immediately in a secret manager; it cannot be read again

`application/json`
```json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Envelope"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
            "token": {
              "type": "string",
              "pattern": "^acr_[A-Za-z0-9_-]{43}$"
            },
            "credential": {
              "$ref": "#/components/schemas/Token"
            }
          }
        }
      }
    }
  ]
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## DELETE /admin/release-tokens/{token}

Revoke a token immediately for future requests



操作 ID：`revokeReleaseToken`

认证：adminSession + csrfCookie

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| token | path | 是 |  {"type":"string","format":"uuid"} |
| Origin | header | 是 | Must exactly match APP_ORIGIN {"type":"string"} |
| X-CSRF-Token | header | 是 | Must match ac_csrf cookie {"type":"string","minLength":32} |


### 响应

#### HTTP 200

Success with data=null. GET state for current revision before next mutation.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
| data | object | 是 |  |
```json
{
  "$ref": "#/components/schemas/Envelope"
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /admin/release-tokens/{token}/rotate

Atomically revoke old token and create a replacement with same scopes and expiry



操作 ID：`rotateReleaseToken`

认证：adminSession + csrfCookie

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| token | path | 是 |  {"type":"string","format":"uuid"} |
| Origin | header | 是 | Must exactly match APP_ORIGIN {"type":"string"} |
| X-CSRF-Token | header | 是 | Must match ac_csrf cookie {"type":"string","minLength":32} |


### 响应

#### HTTP 200

Store token immediately in a secret manager; it cannot be read again

`application/json`
```json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Envelope"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
            "token": {
              "type": "string",
              "pattern": "^acr_[A-Za-z0-9_-]{43}$"
            },
            "credential": {
              "$ref": "#/components/schemas/Token"
            }
          }
        }
      }
    }
  ]
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## GET /admin/release-tokens/audit

Read machine request intent and result (release-tokens:write)



操作 ID：`listMachineReleaseAudit`

认证：adminSession

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application_id | query | 是 |  {"type":"string","format":"uuid"} |
| page | query | 条件 / 否 |  {"type":"integer","minimum":1,"default":1} |


### 响应

#### HTTP 200

Envelope with data=array of id, token_id, application_id, route, object_id, outcome, created_at. outcome=0 is interrupted/unknown.

#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /automation/applications/{application}/releases

Create or replay a draft (releases:create)



操作 ID：`createMachineRelease`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| Idempotency-Key | header | 是 |  {"type":"string","pattern":"^[A-Za-z0-9._-]{1,128}$"} |

### 请求体（必需）



`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| version | string | 是 |  |
| version_code | integer | 是 |  |
| platform | string | 是 |  |
| arch | string | 是 |  |
| channel | string | 是 |  |
| git_commit | string | 是 |  |
| metadata | object | 条件 / 否 | JSON representation at most 16 KiB; no secrets |
| notes | string | 条件 / 否 |  |
```json
{
  "$ref": "#/components/schemas/Manifest"
}
```

### 响应

#### HTTP 200

Same release and current state for matching application/key/manifest

`application/json`
```json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Envelope"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "$ref": "#/components/schemas/Release"
        }
      }
    }
  ]
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## GET /automation/applications/{application}/releases/{id}

Read release, build and upload state (releases:read)



操作 ID：`machineReleaseStatus`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |


### 响应

#### HTTP 200

Upload sessions never expose storage secrets or object keys

`application/json`
```json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Envelope"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
            "release": {
              "$ref": "#/components/schemas/Release"
            },
            "assets": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Asset"
              }
            },
            "build": {
              "type": "object",
              "properties": {
                "git_commit": {
                  "type": "string"
                },
                "metadata": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            },
            "production_approval_required": {
              "type": "boolean"
            }
          }
        }
      }
    }
  ]
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /automation/applications/{application}/releases/{id}/uploads

Create or resume an exact matching session (uploads:write)



操作 ID：`startMachineUpload`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |

### 请求体（必需）



`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| filename | string | 是 | ASCII basename; zip/apk/exe/msi/dmg/deb/rpm/appimage |
| size | integer | 是 |  |
| sha256 | string | 是 |  |
| revision | integer | 是 |  |
```json
{
  "type": "object",
  "required": [
    "filename",
    "size",
    "sha256",
    "revision"
  ],
  "properties": {
    "filename": {
      "type": "string",
      "maxLength": 128,
      "description": "ASCII basename; zip/apk/exe/msi/dmg/deb/rpm/appimage"
    },
    "size": {
      "type": "integer",
      "format": "int64",
      "minimum": 1,
      "maximum": 134217728
    },
    "sha256": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$"
    },
    "revision": {
      "type": "integer",
      "format": "int64",
      "minimum": 1
    }
  }
}
```

### 响应

#### HTTP 200

Session valid 24 hours; repeat metadata to resume

`application/json`
```json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Envelope"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
            "asset": {
              "$ref": "#/components/schemas/Asset"
            },
            "part_size": {
              "type": "integer",
              "example": 33554432
            },
            "uploaded_parts": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "part_number": {
                    "type": "integer"
                  },
                  "size": {
                    "type": "integer",
                    "format": "int64"
                  },
                  "sha256": {
                    "type": "string",
                    "description": "Base64 or empty if provider does not return it"
                  }
                }
              }
            }
          }
        }
      }
    }
  ]
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /automation/applications/{application}/releases/{id}/uploads/{asset}/part

Sign one 32 MiB part, or smaller final part (uploads:write)



操作 ID：`signMachineUploadPart`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |
| asset | path | 是 |  {"type":"string","format":"uuid"} |

### 请求体（必需）



`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| part_number | integer | 是 |  |
| sha256 | string | 是 | SHA-256 digest encoded as Base64 |
```json
{
  "type": "object",
  "required": [
    "part_number",
    "sha256"
  ],
  "properties": {
    "part_number": {
      "type": "integer",
      "minimum": 1,
      "maximum": 4
    },
    "sha256": {
      "type": "string",
      "format": "byte",
      "description": "SHA-256 digest encoded as Base64"
    }
  }
}
```

### 响应

#### HTTP 200

PUT file bytes to URL with all returned headers; do not send the machine Token to S3

`application/json`
```json
{
  "allOf": [
    {
      "$ref": "#/components/schemas/Envelope"
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "type": "object",
          "properties": {
            "url": {
              "type": "string",
              "format": "uri",
              "description": "Secret capability valid at most 15 minutes; do not log"
            },
            "headers": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  ]
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /automation/applications/{application}/releases/{id}/uploads/{asset}/file

Upload a single file at most 32 MiB (uploads:write)



操作 ID：`uploadSmallMachineFile`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |
| asset | path | 是 |  {"type":"string","format":"uuid"} |

### 请求体（必需）



`multipart/form-data`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| file | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "file"
  ],
  "properties": {
    "file": {
      "type": "string",
      "format": "binary"
    }
  }
}
```

### 响应

#### HTTP 200

uploaded=true, completion_required=true; call complete before publication

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
| data | object | 是 |  |
```json
{
  "$ref": "#/components/schemas/Envelope"
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /automation/applications/{application}/releases/{id}/uploads/{asset}/complete

Merge and synchronously verify full digest and file policy (uploads:write)



操作 ID：`completeMachineUpload`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |
| asset | path | 是 |  {"type":"string","format":"uuid"} |


### 响应

#### HTTP 200

Success with data=null. GET state for current revision before next mutation.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
| data | object | 是 |  |
```json
{
  "$ref": "#/components/schemas/Envelope"
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## DELETE /automation/applications/{application}/releases/{id}/uploads/{asset}

Queue unfinished upload cleanup (uploads:write)



操作 ID：`cancelMachineUpload`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |
| asset | path | 是 |  {"type":"string","format":"uuid"} |


### 响应

#### HTTP 200

Success with data=null. GET state for current revision before next mutation.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
| data | object | 是 |  |
```json
{
  "$ref": "#/components/schemas/Envelope"
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```
## POST /automation/applications/{application}/releases/{id}/state

alpha requires publish:development; beta requires publish:staging; stable always denied



操作 ID：`publishOrCancelMachineRelease`

认证：machineToken

### 参数

| 名称 | 位置 | 必需 | 说明与约束 |
| --- | --- | --- | --- |
| application | path | 是 |  {"type":"string","format":"uuid"} |
| id | path | 是 |  {"type":"string","format":"uuid"} |

### 请求体（必需）



`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| action | string | 是 |  |
| revision | integer | 是 |  |
```json
{
  "type": "object",
  "required": [
    "action",
    "revision"
  ],
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "publish",
        "cancel"
      ]
    },
    "revision": {
      "type": "integer",
      "format": "int64",
      "minimum": 1
    }
  }
}
```

### 响应

#### HTTP 200

Success with data=null. GET state for current revision before next mutation.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
| data | object | 是 |  |
```json
{
  "$ref": "#/components/schemas/Envelope"
}
```
#### HTTP default

400/40000 input or integrity; 401/40100 credentials; 403/40300 authorization; 404/40400 missing; 409/40900 conflict; 429/42900 rate/quota; 503/50300 unavailable. Retry-After may be present on capacity or rate errors.

`application/json`

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
```json
{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}
```

## 数据结构字典

上文的 $ref 指向以下命名结构。条件字段以说明中的 scope 和流程为准。

### Token



| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| id | string | 条件 / 否 |  |
| application_id | string | 条件 / 否 |  |
| name | string | 条件 / 否 |  |
| scopes | string | 条件 / 否 | Space-separated scope list |
| created_by | string | 条件 / 否 |  |
| expires_at | string | 条件 / 否 |  |
| revoked_at | string | 条件 / 否 |  |

完整结构与约束：

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "application_id": {
      "type": "string",
      "format": "uuid"
    },
    "name": {
      "type": "string"
    },
    "scopes": {
      "type": "string",
      "description": "Space-separated scope list"
    },
    "created_by": {
      "type": "string",
      "format": "uuid"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    },
    "revoked_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true
    }
  }
}
```

### Envelope



| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| code | integer | 是 |  |
| message | string | 是 |  |
| data | object | 是 |  |

完整结构与约束：

```json
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "type": "integer",
      "enum": [
        0
      ]
    },
    "message": {
      "type": "string",
      "example": "success"
    },
    "data": {
      "nullable": true
    }
  }
}
```

### Manifest



| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| version | string | 是 |  |
| version_code | integer | 是 |  |
| platform | string | 是 |  |
| arch | string | 是 |  |
| channel | string | 是 |  |
| git_commit | string | 是 |  |
| metadata | object | 条件 / 否 | JSON representation at most 16 KiB; no secrets |
| notes | string | 条件 / 否 |  |

完整结构与约束：

```json
{
  "type": "object",
  "required": [
    "version",
    "version_code",
    "platform",
    "arch",
    "channel",
    "git_commit"
  ],
  "properties": {
    "version": {
      "type": "string",
      "pattern": "^[0-9A-Za-z][0-9A-Za-z.+_-]{0,63}$"
    },
    "version_code": {
      "type": "integer",
      "format": "int64",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "platform": {
      "type": "string",
      "enum": [
        "windows",
        "macos",
        "linux",
        "android",
        "ios"
      ]
    },
    "arch": {
      "type": "string",
      "enum": [
        "x64",
        "arm64",
        "x86",
        "universal"
      ]
    },
    "channel": {
      "type": "string",
      "enum": [
        "alpha",
        "beta",
        "stable"
      ]
    },
    "git_commit": {
      "type": "string",
      "pattern": "^(?:[a-f0-9]{40}|[a-f0-9]{64})$"
    },
    "metadata": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "JSON representation at most 16 KiB; no secrets"
    },
    "notes": {
      "type": "string",
      "maxLength": 10000
    }
  }
}
```

### Release



| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| id | string | 条件 / 否 |  |
| application_id | string | 条件 / 否 |  |
| version | string | 条件 / 否 |  |
| version_code | integer | 条件 / 否 |  |
| platform | string | 条件 / 否 |  |
| arch | string | 条件 / 否 |  |
| channel | string | 条件 / 否 |  |
| notes | string | 条件 / 否 |  |
| mandatory | boolean | 条件 / 否 |  |
| status | string | 条件 / 否 |  |
| revision | integer | 条件 / 否 |  |
| asset_id | string | 条件 / 否 |  |
| ever_published | boolean | 条件 / 否 |  |
| published_at | string | 条件 / 否 |  |
| scheduled_at | string | 条件 / 否 |  |

完整结构与约束：

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "application_id": {
      "type": "string",
      "format": "uuid"
    },
    "version": {
      "type": "string"
    },
    "version_code": {
      "type": "integer",
      "format": "int64"
    },
    "platform": {
      "type": "string"
    },
    "arch": {
      "type": "string"
    },
    "channel": {
      "type": "string"
    },
    "notes": {
      "type": "string"
    },
    "mandatory": {
      "type": "boolean"
    },
    "status": {
      "type": "string",
      "enum": [
        "draft",
        "scheduled",
        "published",
        "cancelled",
        "deleted"
      ]
    },
    "revision": {
      "type": "integer",
      "format": "int64"
    },
    "asset_id": {
      "type": "string",
      "format": "uuid",
      "nullable": true
    },
    "ever_published": {
      "type": "boolean"
    },
    "published_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true
    },
    "scheduled_at": {
      "type": "string",
      "format": "date-time",
      "nullable": true
    }
  }
}
```

### Asset



| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| id | string | 条件 / 否 |  |
| release_id | string | 条件 / 否 |  |
| filename | string | 条件 / 否 |  |
| size | integer | 条件 / 否 |  |
| sha256 | string | 条件 / 否 |  |
| status | string | 条件 / 否 |  |
| expires_at | string | 条件 / 否 |  |

完整结构与约束：

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "release_id": {
      "type": "string",
      "format": "uuid"
    },
    "filename": {
      "type": "string"
    },
    "size": {
      "type": "integer",
      "format": "int64"
    },
    "sha256": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$"
    },
    "status": {
      "type": "string",
      "enum": [
        "uploading",
        "ready",
        "deleting",
        "deleted"
      ]
    },
    "expires_at": {
      "type": "string",
      "format": "date-time"
    }
  }
}
```
