# GET /v1/projects/:projectId/content (/docs/api/reference/content/list-containers)



<Endpoint method="GET" path="/v1/projects/:projectId/content" scope="content:read" phase="1" />

Cursor-paginated list of containers, newest first. Filter by generation status, format, or a time window.

## Path parameters [#path-parameters]

<Parameters
  rows="[
  { name: 'projectId', type: 'string (uuid)', required: true, description: 'Project to list containers for.' },
]"
/>

## Query parameters [#query-parameters]

<Parameters
  rows="[
  { name: 'status', type: 'string | string[]', description: 'Filter on generation status. Repeat the param to combine.', enum: ['queued', 'generating', 'completed', 'failed', 'canceled'] },
  { name: 'format', type: 'string | string[]', description: 'Filter on format.', enum: ['video_remix', 'slideshow_remix', 'ugc_remix', 'auto'] },
  { name: 'since', type: 'string (ISO-8601)', description: 'Only containers created at or after this timestamp.' },
  { name: 'until', type: 'string (ISO-8601)', description: 'Only containers created at or before this timestamp.' },
  { name: 'cursor', type: 'string', description: 'Opaque cursor from the previous page. Pass the `nextCursor` value verbatim — do not decode or modify it. Cursors are bound to the original sort (created_at desc).' },
  { name: 'limit', type: 'integer', default: '25', description: 'Max 200.' },
]"
/>

## Request [#request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```sh title="terminal"
    curl "https://api.layers.com/v1/projects/{projectId}/content?status=completed&limit=20" \
      -H "X-Api-Key: $LAYERS_API_KEY"
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts title="list-containers.ts"
    const params = new URLSearchParams({
      status: 'completed',
      limit: '50',
    });
    const res = await fetch(
      `https://api.layers.com/v1/projects/${projectId}/content?${params}`,
      { headers: { 'X-Api-Key': process.env.LAYERS_API_KEY! } },
    );
    const { items, nextCursor } = await res.json();
    ```
  </Tab>

  <Tab value="Python">
    ```py title="list_containers.py"
    import os, httpx

    r = httpx.get(
        f"https://api.layers.com/v1/projects/{project_id}/content",
        params={"status": ["completed", "failed"], "format": ["video_remix"]},
        headers={"X-Api-Key": os.environ["LAYERS_API_KEY"]},
    )
    data = r.json()
    ```
  </Tab>
</Tabs>

## Responses [#responses]

<Response status="200" description="Page of containers.">
  ```json
  {
    "items": [
      {
        "id": "cnt_01HXZ9...",
        "status": "completed",
        "format": "video_remix",
        "caption": "Your first 30 days of running.",
        "approvalStatus": "pending",
        "createdAt": "2026-04-17T13:10:00Z",
        "completedAt": "2026-04-17T13:14:22Z",
        "primaryAsset": {
          "assetId": "ast_01HXZ9...",
          "kind": "video",
          "thumbnailUrl": "https://media.layers.com/.../cnt_01HXZ9/thumb.jpg",
          "durationMs": 9200
        }
      }
    ],
    "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTA0LTE3VDEzOjEwOjAwWiIsImlkIjoiNzg5NGIxZDUtMmFhNy00MWY5LWE4NTktMjgwMzA2ZWE1NjcyIn0"
  }
  ```
</Response>

## Common filters [#common-filters]

* **Rescue failed jobs.** `status=failed&since=2026-04-01T00:00:00Z` — sweep for broken containers to regenerate.
* **In-flight work.** `status=queued&status=generating` — everything currently being produced.
* **UGC-only.** `format=ugc_remix` — if you're running a separate UGC review flow from brand content.

## Errors [#errors]

| Code                | When                           |
| ------------------- | ------------------------------ |
| `VALIDATION_FAILED` | Bad enum value, `limit > 200`. |
| `NOT_FOUND`         | Project id not in this org.    |

## See also [#see-also]

* [Read one container](/docs/api/reference/content/get-container)
* [Approve pending containers](/docs/api/reference/approval/approve-content)
* [Regenerate failed containers](/docs/api/reference/content/regenerate-content)
