# POST /v1/content/:containerId/clone-from-post (/docs/api/reference/content/clone-from-post)



<Endpoint method="POST" path="/v1/content/:containerId/clone-from-post" scope="content:write" phase="1">
  Takes a platform post (one of yours or one of the top-performers we surface)
  and produces a new generated container inspired by it.
</Endpoint>

This is the "clone a top performer" workflow. The `:containerId` in the URL is the **target** — pass a fresh UUID for idempotency. Pass a `sourcePlatformPostId` we already track — typically one surfaced by [`top-performers`](/docs/api/reference/metrics/top-performers) — along with the `projectId` the new container belongs to. We run a content job that uses the source's hook, pacing, and visual structure as input.

Two modes:

* **`"fork"`** (default) — structurally close to the source. Same hook shape, same length, same CTA position. The generator treats the source as a template.
* **`"reimagine"`** — uses the source's premise but lets the generator diverge on structure, voice, and visuals. More variance in output. Higher chance the generator improves on the source.

## Path parameters [#path-parameters]

<Parameters
  rows="[
  { name: 'containerId', type: 'string (uuid)', required: true, description: 'The new container id (partner-supplied UUID). Used as an idempotency key — replaying with the same id returns the prior response.' },
]"
/>

## Body [#body]

<Parameters
  title="Body"
  rows="[
  { name: 'projectId', type: 'string (uuid)', required: true, description: 'Project the new container belongs to. Must be in this org.' },
  { name: 'projectLayerId', type: 'string (uuid)', description: 'Which content layer to run through. Omit if the project only has one.' },
  { name: 'sourcePlatformPostId', type: 'string', required: true, description: 'Id of a post Layers tracks. Accepts the internal `platform_posts.id` or the platform-native `external_id`.' },
  { name: 'mode', type: 'string', default: '&#x22;fork&#x22;', description: 'Generation posture.', enum: ['fork', 'reimagine'] },
  { name: 'variations', type: 'integer', default: '1', description: 'Number of variations to produce. Max 10.' },
  { name: 'overrides', type: 'object', description: 'Caption, CTA, or voice-over script overrides for the clone.' },
  { name: 'overrides.caption', type: 'string', description: 'Override the source caption.' },
  { name: 'overrides.cta', type: 'string', description: 'Override the source CTA.' },
  { name: 'overrides.voiceOverScript', type: 'string', description: 'Replace the voice-over script.' },
]"
/>

## Request [#request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```sh title="terminal"
    curl -X POST https://api.layers.com/v1/content/{newContainerId}/clone-from-post \
      -H "X-Api-Key: $LAYERS_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 8d2f1a3e-0b4c-4a11-9f7e-33c0a2c1bd55" \
      -d '{
        "projectId": "proj_01HX...",
        "sourcePlatformPostId": "pp_01HX...",
        "mode": "reimagine",
        "variations": 3
      }'
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts title="clone-from-post.ts"
    const newContainerId = crypto.randomUUID();
    const res = await fetch(
      `https://api.layers.com/v1/content/${newContainerId}/clone-from-post`,
      {
        method: 'POST',
        headers: {
          'X-Api-Key': process.env.LAYERS_API_KEY!,
          'Content-Type': 'application/json',
          'Idempotency-Key': crypto.randomUUID(),
        },
        body: JSON.stringify({
          projectId,
          sourcePlatformPostId,
          mode: 'fork',
        }),
      },
    );
    const { jobId, containerId } = await res.json();
    ```
  </Tab>

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

    new_container_id = str(uuid.uuid4())
    r = httpx.post(
        f"https://api.layers.com/v1/content/{new_container_id}/clone-from-post",
        headers={
            "X-Api-Key": os.environ["LAYERS_API_KEY"],
            "Content-Type": "application/json",
            "Idempotency-Key": str(uuid.uuid4()),
        },
        json={
            "projectId": project_id,
            "sourcePlatformPostId": source_id,
            "mode": "reimagine",
            "variations": 2,
        },
    )
    data = r.json()
    ```
  </Tab>
</Tabs>

## Responses [#responses]

<Response status="202" description="One job for the clone. The workflow produces variations as part of that single job.">
  ```json
  {
    "jobId": "job_01HXZ9G7KMV2QX8Y1S5RJW3B7T",
    "kind": "content_clone_from_post",
    "status": "running",
    "containerId": "cnt_01HXZ9...",
    "locationUrl": "/v1/jobs/job_01HXZ9G7KMV2QX8Y1S5RJW3B7T"
  }
  ```
</Response>

<Response status="404" description="Source post not in this org's scope, or project not found.">
  ```json
  {
    "error": {
      "code": "NOT_FOUND",
      "message": "Source post not found.",
      "requestId": "req_..."
    }
  }
  ```
</Response>

<Response status="409" description="Project has no active content layers, or multiple layers with no projectLayerId.">
  ```json
  {
    "error": {
      "code": "CONFLICT",
      "message": "Multiple content layers — pass projectLayerId to disambiguate.",
      "requestId": "req_...",
      "details": { "layerCount": 2 }
    }
  }
  ```
</Response>

## Notes [#notes]

<Callout type="info">
  Clone-from-post does not republish or repost the source. It produces a new,
  generated container with your project's brand voice. The source is an
  input, not a direct reference in the output.
</Callout>

* **Source selection.** Only posts we already track (via SIFT or your ad accounts) are valid sources. If you want to seed from an arbitrary URL, upload the media first and use [`generate-content`](/docs/api/reference/content/generate-content) with `brief.referenceMediaIds`.
* **Rights.** You are responsible for whether cloning a given source is appropriate for your customer.

## Errors [#errors]

| Code                | When                                                       |
| ------------------- | ---------------------------------------------------------- |
| `NOT_FOUND`         | Source post not in this org's scope, or project not found. |
| `VALIDATION_FAILED` | Bad mode, `variations > 10`.                               |
| `CONFLICT`          | Layer ambiguity or container id already exists.            |
| `BILLING_EXHAUSTED` | Credits insufficient.                                      |

## See also [#see-also]

* [Find top-performing source posts](/docs/api/reference/metrics/top-performers)
* [Generate from scratch](/docs/api/reference/content/generate-content)
* [The jobs envelope](/docs/api/concepts/jobs)
