---
title: "Move retired component clips to their native successors"
method: POST
path: "/v1/projects/{id}/components/native-upgrade"
tags: ["components"]
---

# Move retired component clips to their native successors

`POST /v1/projects/{id}/components/native-upgrade`

## Request

- Base URL: `https://api.cueframe.ai`
- URL: `https://api.cueframe.ai/v1/projects/{id}/components/native-upgrade`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.cueframe.ai/api/auth/mcp/authorize`, token URL `https://api.cueframe.ai/api/auth/mcp/token`, scopes: `projects:write`)
  - API key in header `PAYMENT-SIGNATURE`

Move clips stored in a retired form to their native (version 4) successors: a clip pinning a retired curated TSX (version 3) component, or one stored before execution pins (needsUpgrade kind unpinned-component), moves to the successorSourceVersionId the read or a refusal of such a clip names. Name clip_ids, or omit them to move every clip that has a successor. Every saved input is kept. Clips with no successor are listed in withoutSuccessor, and clips whose stored inputs the successor refuses in inputsRefused; a write never leaves a retired clip in place, so rebuild or remove those in the same edit that upgrades the others.

## Path parameters

- `id` string, required

## Request body

- NativeUpgradeRequest
  - `clip_ids` string[]: The clips (component placements) to move. Omit to move every clip that has a native successor.
  - `composition_id` string: The composition to update; the project's active one when omitted.

## Response `200`

The clips moved.

- NativeUpgradeResponse
  - `moved` object[], required
    - `clipId` string, required
    - `componentId` string, required
    - `from` string: The source version the clip pinned; absent for a clip stored before execution pins.
    - `to` string, required
  - `withoutSuccessor` string[], required: Clips in a retired form no curated release recorded: rebuild them as native components, or remove them, in the same edit that upgrades the others.
  - `inputsRefused` object[], required: Clips whose successor refuses their stored inputs (its input schema), each with why: fix the inputs by rebuilding the clip, or remove it.
    - `clipId` string, required
    - `componentId` string, required
    - `message` string, required
  - `etag` string, nullable, required

## Other responses

- `400`: Bad request — validation_error / invalid_cursor / invalid_query.
- `401`: Missing or invalid Authorization header.
- `402`: Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).
- `403`: Forbidden — permission insufficient.
- `404`: Resource not found.
- `409`: Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.
- `422`: Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.
- `500`: Internal error.

---

[API](https://skmtc.dev/cueframe/apis/cueframe-api.md) · [All operations](https://skmtc.dev/cueframe/apis/cueframe-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cueframe/apis/cueframe-api/revisions/8f9bfe362b4a?raw)
