GET /v1/content/:containerId/assets/:assetId
Read one asset descriptor - public URL plus per-asset metadata.
/v1/content/:containerId/assets/:assetId- Auth
- Bearer
- Scope
- content:read
Returns the asset descriptor for a single media file on the container: the public CDN URL, kind, and any per-asset metadata (width, height, durationMs, mimeType, sizeBytes).
URLs are durable, not short-lived signatures, so it's safe to embed them in your own UI for the lifetime of the container. They do go away when the container is deleted, so always serve from the current container state rather than caching the URL itself.
The assets array on GET /v1/content/:containerId carries the same shape as the body below. This endpoint exists for direct asset addressing (e.g. you have an assetId from primaryAsset and don't want to re-pull the whole container).
Path parameters
containerIdstringrequiredThe container id (UUID; both raw and `cnt_<id>` accepted).assetIdstringrequiredThe asset id, taken from `container.assets[].assetId` or `primaryAsset.assetId`. Treat it as opaque.
Request
curl https://api.layers.com/v1/content/{containerId}/assets/{assetId} \
-H "Authorization: Bearer $LAYERS_API_KEY"const res = await fetch(
`https://api.layers.com/v1/content/${containerId}/assets/${assetId}`,
{ headers: { 'Authorization': `Bearer ${process.env.LAYERS_API_KEY}` } },
);
const { url, mimeType, expiresAt } = await res.json();import os, httpx
r = httpx.get(
f"https://api.layers.com/v1/content/{container_id}/assets/{asset_id}",
headers={"Authorization": f"Bearer {os.environ[\'LAYERS_API_KEY\']}"},
)
asset = r.json()Responses
{
"containerId": "cnt_7d18b9a1...",
"assetId": "video-9c855048-b470-42e7-8f1b-032324d48555",
"kind": "video",
"url": "https://media.layers.com/public-media/content-container/.../media/video-9c855048-b470-42e7-8f1b-032324d48555.mp4",
"thumbnailUrl": null
}Optional fields are typically present on newer containers and may be absent on legacy data:
{
"mimeType": "video/mp4",
"sizeBytes": 1843200,
"durationMs": 9200,
"width": 1080,
"height": 1920,
"checksumSha256": "e3b0c44298fc1c...",
"expiresAt": "2026-04-18T10:45:00Z"
}{
"error": {
"code": "NOT_FOUND",
"message": "Asset not on this container.",
"requestId": "req_..."
}
}Notes
URLs are durable, not pre-signed. They're stable CDN paths - fine to
embed in your UI or pass to a video player without expiresAt bookkeeping.
When expiresAt is included, honor it. Otherwise treat the URL as valid
until the asset is replaced or the container is deleted.
checksumSha256is stable across re-fetches when present. Use it to dedupe downloads or verify integrity after upload to a third-party CDN. Not all rows carry it - older containers may omit the field.
Errors
| Code | When |
|---|---|
NOT_FOUND | Asset id not on this container, or container not in this org. |
FORBIDDEN_SCOPE | Key lacks content:read. |