Products

$envless->products->delete()

Soft delete a product and everything under it

php
/** @return DeletedProductResource */
public function delete(string $slug, int|float|null $timeout = null): array

Soft-deletes a product together with its projects, their environments and every variable in them, in one transaction. There is no has children guard and no undo over the API, so put your own confirmation in front of it. A key holding products:write can clear a whole tree on its own; restrict the key to specific projects when that is not what you want.

Every explicit access grant recorded on the product is cleared in the same transaction, and those are not counted in the response.

The payload is a tombstone with id, name and slug, plus deletedProjects, deletedEnvironments and deletedVariables counting what the cascade removed, not the full product shape. This route deliberately skips the plan lock check, so a product locked by a downgrade can still be deleted, which is how a workspace gets back under its allowance.

Example

php
use Envless\Envless;

$envless = new Envless();

$removed = $envless->products->delete('billing');

echo "{$removed['slug']} {$removed['deletedProjects']}", PHP_EOL;
echo $removed['deletedVariables'], PHP_EOL;

Parameters

ParameterTypeRequiredDescription
$slugstringYesProduct slug, or the product uniqueId when the value is UUID shaped.
$timeoutint|floatNoSeconds each attempt of this call may take, the response body included, before it throws Envless\Exception\NetworkException with isTimeout() true. Overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DeletedProductResource with the id, name and slug of the removed product, and the number of projects, environments and variables that went with it.

Worth knowing

  • The call is not idempotent: a second delete of the same slug reports a missing product, because the deleted row is excluded from lookups.
  • DELETE is retried on a 408, a 429 or a 5xx, a gateway timeout included, and the cascade may have committed before that response was sent, so a retry that comes back product.not_found most likely means the first attempt succeeded.
  • Version snapshots under the deleted environments are not removed and are not counted, they simply stop resolving.

Required scopes

products:write

Underlying endpoint

DELETE /products/{slug}

Request and response schema, every error code, and a live playground.

In TypeScript

envless.products.delete()

The same method in @goenvless/sdk, with the same request, retries and errors.