PATCH /v1/content/:containerId
Correct the caption on uploaded content. Uploaded items only.
PATCH
/v1/content/:containerIdstableidempotent
- 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
containerIdstring (cnt_uuid)requiredThe uploaded content item to correct.
Body
Body
captionstringrequiredNew caption, max 2,200 characters. May be empty — but must be present.
Request
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." }'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();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
| Status | Code | When |
|---|---|---|
| 422 | VALIDATION | Caption missing, caption over 2,200 chars, or the item is generated content. |
| 404 | NOT_FOUND | Container not in your org. |
| 401 / 403 | UNAUTHENTICATED / FORBIDDEN_SCOPE | Standard auth and content:write scope rules. |
Notes
- The response is the full content item — identical in shape to
GET /v1/content/:containerId, includingassetsandpreview. There is no separateupdatedAtfield: the edit bumps the row, which surfaces as a refreshedcompletedAt. - 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.