GET /v1/content/:containerId
Read one content container - status, approval, hook, and generated assets.
/v1/content/:containerId- Auth
- Bearer
- Scope
- content:read
Returns the full container record: generation status, approval status, hook, caption, and the rendered media assets. Safe to call while a generation job is in-flight - fields that aren't populated yet are present as null or empty arrays. For live progress, prefer GET /v1/content/:containerId/progress or GET /v1/jobs/:jobId.
Path parameters
containerIdstring (cnt_uuid)requiredThe container id β the `cnt_`-prefixed id returned by create/list (the bare uuid is also accepted).
Request
curl https://api.layers.com/v1/content/{containerId} \
-H "Authorization: Bearer $LAYERS_API_KEY"const res = await fetch(
`https://api.layers.com/v1/content/${containerId}`,
{ headers: { 'Authorization': `Bearer ${process.env.LAYERS_API_KEY}` } },
);
const container = await res.json();import os, httpx
r = httpx.get(
f"https://api.layers.com/v1/content/{container_id}",
headers={"Authorization": f"Bearer {os.environ[\'LAYERS_API_KEY\']}"},
)
container = r.json()Responses
{
"id": "cnt_7d18b9a1...",
"projectId": "prj_01HX...",
"status": "completed",
"format": "ugc-remix",
"hook": "wait for it...\nthis simple habit changed everything about my mindset π§ ",
"influencerId": "inf_4a8e1bc2...",
"sourceTiktokId": null,
"mediaId": "med_01HZ...",
"caption": "Thirty days, one run at a timeβ¦",
"firstComment": null,
"preview": {
"kind": "video",
"primaryUrl": "https://media.layers.com/.../ast_01HXZ9/video.mp4",
"videoUrl": "https://media.layers.com/.../ast_01HXZ9/video.mp4",
"thumbnailUrl": "https://media.layers.com/.../ast_01HXZ9/thumb.jpg",
"hlsUrl": null,
"durationMs": 9200,
"aspectRatio": "9:16"
},
"assets": [
{
"assetId": "ast_01HXZ9...",
"kind": "video",
"url": "https://media.layers.com/.../ast_01HXZ9/video.mp4",
"thumbnailUrl": "https://media.layers.com/.../ast_01HXZ9/thumb.jpg"
}
],
"approvalStatus": "approved",
"creativeType": "generated",
"adsEnrollment": "auto",
"createdAt": "2026-04-17T13:10:00Z",
"completedAt": "2026-04-17T13:14:22Z",
"failedAt": null,
"lastError": null
}{ "error": { "code": "NOT_FOUND", "message": "Container not found.", "requestId": "req_..." } }Echo fields
The partner's creative inputs are echoed back on read so you can drive your own UI off a single GET without keeping a side-table.
| Field | Populates for | Notes |
|---|---|---|
hook | slideshow-builder, ugc-remix | The literal string you sent on POST β line breaks and emoji round-trip exactly. null on remix formats (they adapt source overlays internally). |
influencerId | every format that took an influencerId or resolved one via a wired social account | Prefixed inf_<uuid>. |
sourceTiktokId | video-remix, slideshow-remix | The raw TikTok id you sent. null on builder / ugc formats. |
mediaId | ugc-remix only | Partner-uploaded app-demo source clip, prefixed med_<uuid>. null on every other format. |
Origin fields
Every container carries two origin fields:
| Field | Values | Notes |
|---|---|---|
creativeType | generated | uploaded | How the container was filled. Uploaded content is partner- or user-supplied finished media; everything else is generated. |
adsEnrollment | auto | opted_in | opted_out | Generated content is auto (legacy enrollment). Uploads are born opted_out and are not used in paid campaigns. |
Uploaded containers additionally carry platformFit β computed per-platform fit from the probed media:
"platformFit": [
{ "platform": "tiktok", "ok": false, "issues": ["800x800 image resolution too low (min 1080px on the short edge)"] },
{ "platform": "instagram", "ok": false, "issues": ["800x800 image resolution too low (min 1080px on the short edge)"] }
]platformFit is advisory; scheduling or publishing to an unfit platform returns 422 with the same issues. It is absent on generated containers (no probe metadata). On uploaded containers, format is null and hook is always null β hook is a generation-only field and never applies to uploaded media. See Upload finished content for the full semantics.
Container status
queuedstatusoptionalCreated, awaiting the generator.processingstatusoptionalGeneration in-flight. Assets populate on completion.completedstatusoptionalReady to approve and schedule.failedstatusoptionalSee `lastError.code` and `lastError.message`. Call generate again with a fresh `hook` to retry.canceledstatusoptionalWorkflow was canceled. Call generate again to try again.
Approval status
not_requiredstatusoptionalProject policy does not require approval - content can be scheduled immediately.pendingstatusoptionalDefault when the project requires approval. Blocks scheduling.approvedstatusoptionalCleared for scheduling and publishing.rejectedstatusoptionalBlocked from scheduling. Call generate again with a fresh `hook` to try again.
Errors
| Code | When |
|---|---|
NOT_FOUND | Container id not in this org. |
FORBIDDEN_SCOPE | Key lacks content:read. |
The preview object
Every completed container carries a normalized preview object β the canonical "render this in my UI" surface. Render off preview, not off assets[] (which is the underlying file inventory). See Preview object for the per-kind field-population matrix.
| Field | Type | Notes |
|---|---|---|
kind | "slideshow" | "video" | "image" | Discriminator. Pick rendering mode off this. |
primaryUrl | string | The first/hero URL β fine to drop directly into <img> or <video> based on kind. |
thumbnailUrl | string | null | First slide for slideshows. For video kinds the poster-frame extraction is best-effort and may be null on a freshly completed container β render the videoUrl directly and let the browser produce a frame. |
imageUrls | string[] | Populated when kind = "slideshow". Ordered. |
videoUrl | string | Populated when kind = "video". Direct MP4 URL. |
hlsUrl | string | null | Adaptive-bitrate HLS manifest. Returns null until the HLS pipeline ships. |
durationMs | integer | null | Video duration in milliseconds. null for slideshow/image kinds and on video kinds when probing didn't run (treat as informational; the asset is still playable). |
aspectRatio | string | "9:16" for verticals, "1:1" for squares, etc. |