Layers
Partner APIAPI referenceContent

PATCH /v1/content/:containerId

Correct the caption on uploaded content. Uploaded items only.

View as Markdown
PATCH/v1/content/:containerId
stableidempotent
Auth
Bearer
Scope
content:write

Updates caption on a content item with creativeType: "uploaded". Returns the full updated item. This is the fix path for a typo'd caption — including after a finalize, whose retry body is ignored.

Restricted to uploaded content on purpose: generated content derives its hook from generation inputs, so a column write there wouldn't round-trip on GET. To change generated content, generate again with a fresh hook.

Path parameters

  • containerId
    string (cnt_uuid)required
    The uploaded content item to correct.

Body

Body
  • caption
    stringrequired
    New caption, max 2,200 characters. May be empty — but must be present.

Request

terminal
curl -X PATCH https://api.layers.com/v1/content/cnt_a3f8c2d1-7b4e-4f0a-9c6d-2e1b5a8f3c70 \
  -H "Authorization: Bearer $LAYERS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "caption": "The roast that started it all — now in stores." }'
patch-content.ts
const res = await fetch(
  `https://api.layers.com/v1/content/${containerId}`,
  {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${process.env.LAYERS_API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID(),
    },
    body: JSON.stringify({
      caption: 'The roast that started it all — now in stores.',
    }),
  },
);
const item = await res.json();
patch_content.py
import os, uuid, httpx

r = httpx.patch(
    f"https://api.layers.com/v1/content/{container_id}",
    headers={
        "Authorization": f"Bearer {os.environ['LAYERS_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"caption": "The roast that started it all — now in stores."},
)
item = r.json()

Responses

200The full updated content item — same shape as GET.
{
  "id": "cnt_a3f8c2d1-7b4e-4f0a-9c6d-2e1b5a8f3c70",
  "projectId": "prj_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39",
  "status": "completed",
  "format": null,
  "hook": null,
  "influencerId": null,
  "sourceTiktokId": null,
  "mediaId": null,
  "caption": "The roast that started it all — now in stores.",
  "firstComment": null,
  "assets": [
    {
      "assetId": "upload-1",
      "kind": "video",
      "url": "https://media.layers.com/public-media/content-container/a3f8c2d1-.../media/upload-1.mp4",
      "thumbnailUrl": null,
      "width": 1080,
      "height": 1920,
      "durationMs": 31000,
      "mimeType": "video/mp4",
      "sizeBytes": 18874368
    }
  ],
  "preview": {
    "kind": "video",
    "primaryUrl": "https://media.layers.com/public-media/content-container/a3f8c2d1-.../media/upload-1.mp4",
    "thumbnailUrl": null,
    "imageUrls": [],
    "videoUrl": "https://media.layers.com/public-media/content-container/a3f8c2d1-.../media/upload-1.mp4",
    "hlsUrl": null,
    "durationMs": 31000,
    "aspectRatio": "9:16"
  },
  "approvalStatus": "not_required",
  "creativeType": "uploaded",
  "adsEnrollment": "opted_out",
  "platformFit": [
    { "platform": "tiktok", "ok": true, "issues": [] },
    { "platform": "instagram", "ok": true, "issues": [] }
  ],
  "createdAt": "2026-06-12T14:02:11Z",
  "completedAt": "2026-06-12T16:40:02Z",
  "failedAt": null,
  "lastError": null
}
422The item is generated content — PATCH is uploads-only.
{
  "error": {
    "code": "VALIDATION",
    "message": "PATCH is available for uploaded content only. Generated content is corrected by regenerating.",
    "requestId": "req_...",
    "details": { "creativeType": "generated" }
  }
}

Errors

StatusCodeWhen
422VALIDATIONCaption missing, caption over 2,200 chars, or the item is generated content.
404NOT_FOUNDContainer not in your org.
401 / 403UNAUTHENTICATED / FORBIDDEN_SCOPEStandard auth and content:write scope rules.

Notes

  • The response is the full content item — identical in shape to GET /v1/content/:containerId, including assets and preview. There is no separate updatedAt field: the edit bumps the row, which surfaces as a refreshed completedAt.
  • The caption you set here is what publishes — byte-for-byte, no AI edits. Posts already published keep the caption they went out with; the PATCH affects future scheduling.
  • Media is immutable. There is no PATCH for the file itself — upload a new item if the media is wrong.

See also

On this page