---
title: "Declare an avatar's clip library"
method: PUT
path: "/v1/avatars/{avatarId}/clips"
tags: ["Avatars"]
---

# Declare an avatar's clip library

`PUT /v1/avatars/{avatarId}/clips`

## Request

- Base URL: `https://realtimeavatar.ai/api`
- URL: `https://realtimeavatar.ai/api/v1/avatars/{avatarId}/clips`
- Auth: HTTP bearer

Declare the avatar's full desired clip library; see https://realtimeavatar.ai/docs/editing. The platform reconciles: unchanged clips are kept, changed or new ones re-render in the background against the avatar's pose anchor, absent ones soft-retire. 202 returns the post-apply library plus the reconcile plan. Supports Idempotency-Key replay and expectedRevision compare-and-set.

Requires an API key with the `avatars:write` scope.

## Path parameters

- `avatarId` string, required

## Headers

- `Idempotency-Key` string

## Request body

- PutAvatarClipsRequest
  - `expectedRevision` integer, required
  - `clips` object, required
  - `idle` object
    - `clips` string[], required
    - `weight` number
    - `weights` object
  - `on` object
    - `userSpeechStarted` object
      - `clips` string[], required
  - `actions` object

## Response `202`

Declaration accepted

- PutAvatarClipsResponse
  - `data` object[], required
    - `clipId` string, required
    - `status` 'queued' | 'generating' | 'ready' | 'failed', required
    - `url` string, uri, nullable, required
    - `source` 'generated' | 'uploaded', required
    - `uploadAssetId` string, nullable, required
    - `motionPrompt` string, nullable, required
    - `durationSeconds` integer, nullable, required
    - `anchorVersion` integer, required
    - `poseCheck` object, nullable, required
      - `verdict` object, required
        - `sameSubject` boolean, required
        - `firstFrameMatchesAnchor` boolean, required
        - `lastFrameMatchesAnchor` boolean, required
        - `framingComparable` boolean, required
        - `confidence` number, required
      - `issues` string[], required
      - `firstFrameUrl` string, uri, nullable, required
      - `lastFrameUrl` string, uri, nullable, required
    - `error` object, nullable, required
      - `code` string, required
      - `message` string, required
    - `createdAt` string, required
    - `updatedAt` string, required
  - `avatarId` string, required
  - `revision` integer, required
  - `anchorVersion` integer, required
  - `anchor` object, nullable, required
    - `url` string, uri, required
    - `source` 'portrait' | 'source_frame', required
    - `timeMs` integer, nullable, required
  - `clipLibraryEligible` boolean, required
  - `defaultSourceAssetId` string, nullable, required
  - `behavior` object, required
    - `idle` object
      - `clips` string[], required
      - `weight` number
      - `weights` object
    - `on` object
      - `userSpeechStarted` object
        - `clips` string[], required
    - `actions` object
  - `plan` object, required
    - `kept` string[], required
    - `queued` string[], required
    - `retired` string[], required

## Other responses

- `401`: Missing, malformed, revoked, or expired key.
- `403`: The key lacks the scope for this operation, the tenant is not active, or clip-library editing has been disabled for the workspace — code "clip_library_not_enabled". Editing is enabled by default for active workspaces; an administrator may explicitly disable it.
- `default`: Error. Route-dependent: 400 (a field this route cannot honour — see `portraitUrl` on `UpdateAvatarRequest`), 402 (insufficient credits or spend limit), 404 (no such avatar, voice, or key for this tenant — the message often reads "does not belong to this tenant", which is a missing id and not a permission failure), 408 (the request was cancelled), 409 (the resource is not in a state that accepts this write — a stale `expectedRevision`, a render already in flight, or a mint that asked for a clip library still building), 411 (`POST /v1/assets/remote` only — the origin serving `remoteUrl` sent no `content-length`, so the platform will not stream it), 422 (strict schema rejection, or a motion description the safety screen refused), 429 (rate limited), 502 (upstream render failed), 503 (a dependency this route needs is unavailable — retryable, and nothing was written), 504 (the upstream request budget expired), 500 (unhandled). Switch on `code` where present, else `status`.

---

[API](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api.md) · [All operations](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api/llms.txt) · [OpenAPI document](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api/revisions/e9e3e998e673?raw)
