duplicate(slug: string, options?: RequestScope): Promise<ProductResource>Clones a product together with every project, environment and variable underneath it. Ciphertext is copied verbatim, so the clone decrypts with the same workspace passphrase and needs no re-encryption pass.
The name and slug of the clone are derived from the source and are not predictable, so read them off the response rather than guessing at a suffix. Version history is not carried over, so the cloned environments start with no versions.
A key restricted to specific projects is refused outright, because the clone creates project ids outside that allowlist. Both the product cap and the project cap of the plan are enforced, and either one being full rejects the call.
Example
const clone = await envless.products.duplicate('billing')
const projects = await envless.products.listAllProjects(clone.slug)
console.log(clone.slug, projects.length)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Yes | Slug or uniqueId of the product to copy. |
options.signal | AbortSignal | No | Cancels the request. |
Returns
ProductResource for the clone, including the generated name and slug.
Worth knowing
- Duplicating a private product keeps the privacy flag and copies the grants recorded on the source.
- The whole copy runs in one transaction, so a rejection leaves no half-built product behind.
Required scopes
products:write and projects:write and variables:write
Underlying endpoint
POST /products/{slug}/duplicate
Request and response schema, every error code, and a live playground.
In Python
envless.products.duplicate()
The same method in envless-sdk, the Python SDK, with the same request, retries and errors.
In Ruby
Envless.products.duplicate
The same method in envless-sdk, the Ruby gem, with the same request, retries and errors.
In PHP
$envless->products->duplicate()
The same method in envless/sdk, the PHP SDK, with the same request, retries and errors.