Files
delivery-desk/.agents/skills/upload-delivery-desk-work/references/api-contract.md

119 lines
4.9 KiB
Markdown

# Delivery Desk upload contract
## Current hierarchy and identity
`operation group -> project -> work -> review round`
- A project belongs to exactly one operation group.
- A work belongs to exactly one project.
- A review round belongs to exactly one work and contains exactly one proposal.
- `externalId` is unique within a project and is the only supported idempotency key for agent-created works.
- Product-facing operations do not accept a collection/delivery-set ID.
## Authentication and scope
Send `Authorization: Bearer <DELIVERY_DESK_API_KEY>`.
| Key scope | Readable projects | Create work | Create round |
|---|---|---|---|
| `project` | Its bound active project | Only in that project | Only for works in that project |
| `platform` | All non-archived projects | Any active project | Any work in an active project |
Prefer `project`. Do not store the token in a plan file.
## Discovery endpoints
### `GET /api/projects`
Returns accessible projects. Relevant fields:
```json
{
"id": 12,
"group_id": 3,
"group_name": "示例运营组",
"name": "光影内容计划",
"slug": "light-notes",
"status": "active",
"review_status": "reviewing"
}
```
### `GET /api/projects/:projectId/works`
Returns works in the exact project. Use `?externalId=<value>` for exact external-ID lookup.
### `GET /api/works/:workId`
Returns current work content, project identity, images, and rounds. Use `?round=N` only when inspecting a historical round.
## Mutation endpoints
### `POST /api/projects/:projectId/works`
URL mode uses a JSON body:
```json
{
"externalId": "client-2026-001",
"title": "作品标题",
"description": "正文",
"tags": ["#夏日"],
"images": ["https://cdn.example.com/01.jpg"]
}
```
Constraints:
- `title` is required.
- `images` contains 1-30 public HTTP/HTTPS URLs.
- Array order is display order; item 1 is the cover.
- An active Tencent COS configuration is required. URLs on its configured public/CDN origin are reused; other public images are downloaded, validated, and stored in that COS before the work is created.
- Cross-origin images must be supported image responses no larger than 20 MB. Local, private, reserved, and non-standard-port targets are rejected.
- Repeating the same `projectId + externalId` returns the existing work with `idempotent: true`.
Local-file mode uses `multipart/form-data` with text fields `externalId`, `title`, `description`, `tags` and repeated file field `images`.
- Send `tags` as a JSON array string.
- Send 1-30 JPEG, PNG, GIF, WebP, or AVIF files, each no larger than 20 MB.
- File order is display order; file 1 is the cover.
- The server validates actual image content instead of trusting only the filename or declared MIME.
- With active Tencent COS configuration, accepted files are streamed from server temporary storage into COS.
- Do not send Base64 in JSON. The agent script reads local files directly into the multipart request; binary bytes never belong in the plan or conversation.
### `POST /api/works/:workId/rounds`
JSON body:
```json
{
"title": "修改后的标题",
"description": "修改后的正文",
"tags": ["#第二轮"],
"images": ["https://cdn.example.com/round-2.jpg"]
}
```
This endpoint is not idempotent. One successful call creates exactly one new round. Never blindly retry after a timeout.
It applies the same COS reuse/import rules as work creation.
It also accepts the same local-file multipart fields, except `externalId` is omitted.
## State guards
- Only `active` projects accept new works or rounds.
- Closed or archived projects are read-only.
- A completed project may require an authorized administrator to reopen the relevant workflow before another round can be created.
| Status | Script action | Required next step |
|---|---|---|
| `400` | `revise` | Correct malformed input, regenerate the plan, and obtain a new confirmation. |
| `401` | `ask_operator` | Ask the operator to configure or replace `DELIVERY_DESK_API_KEY`. |
| `403` | `ask_operator` | Report the exact group/project and ask an administrator to correct Key scope. Never select another target. |
| `404` | `ask_operator` | Re-run read-only discovery, then ask the operator if the confirmed target is gone or inaccessible. |
| `409` | `ask_operator` | Report the target state and wait for the operator or administrator to resolve it. |
| `413` | `revise` | Replace or reduce the image, regenerate the plan, and obtain a new confirmation. |
| `422` | `revise` | Replace the unreachable or unsupported public image URL, regenerate the plan, and obtain a new confirmation. |
| `502` | `ask_operator` for writes | Do not retry the write automatically; inspect state and ask the operator to check Tencent COS. |
| `429`, `503`, `504` | `retry` for reads only | Wait and retry the same read-only command without changing the target. Writes require `ask_operator`. |
Do not work around `403` or `409` by selecting a different project. Report the exact target and ask the operator or administrator to resolve access/state.