Variables

Delete variables by name

Bulk soft-deletes variables by name, matched without regard to case, so api_key deletes a live API_KEY.

DELETE/projects/{slug}/environments/{environmentSlug}/variables

Bulk soft-deletes variables by name, matched without regard to case, so api_key deletes a live API_KEY. Takes a JSON body on DELETE, which some HTTP clients suppress by default.

Unknown names are not an error. They come back in notFound and the rest are still deleted, so the call is idempotent enough to retry. If none of the names match, the response is still 200 with count: 0 and every name in notFound.

At most 200 names per request. Deletes are soft, so the rows stay available to version snapshots taken earlier and to rollback.

Requires the variables:write scope.

curl --request DELETE \
  --url 'https://api.envless.cloud/projects/<slug>/environments/<environmentSlug>/variables' \
  --header 'Authorization: Bearer ev_sk_xxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{
  "names": [
    "STRIPE_SECRET_KEY",
    "SENTRY_DSN"
  ]
}'
Try itDELETEhttps://api.envless.cloud/projects/{slug}/environments/{environmentSlug}/variables
Path parameters
Query parameters

Authorization

  • Authorizationstringrequiredheader

    Bearer token: an Envless API key (ev_sk_…), created in the dashboard or with POST /keys. The key is bound to one workspace; every request runs inside it.

Path parameters

  • slugstringrequired

    Project slug or project uniqueId.

  • environmentSlugstringrequired

    Environment slug.

Query parameters

  • productstring

    Product slug, to disambiguate a project slug shared across products.

Request body

application/json · required

  • namesstring[]requiredmin items 1max items 200

    Variable names to delete. Matching ignores case, so api_key deletes a live API_KEY. Names that match nothing come back in notFound.

Responses

200OK

Delete variables by name succeeded.

  • successbooleanrequired
  • codeintegerrequired

    The HTTP status of this response, repeated in the body.

  • messagestringrequired
  • errornullrequired
  • dataobjectrequired
    Show child attributesHide child attributes
    • deletedobject[]required
      Show child attributesHide child attributes
      • idstringrequired
      • namestringrequired
    • countintegerrequired

      Rows actually soft-deleted.

    • notFoundstring[]required

      Names from the request that matched no live variable.

  • _reqobject
    Show child attributesHide child attributes
    • reqIdstring
    • resTimeinteger | null
{
    "success": true,
    "code": 200,
    "message": "OK",
    "error": null,
    "data": {
        "deleted": [
            {
                "id": "<string>",
                "name": "STRIPE_SECRET_KEY"
            }
        ],
        "count": 1,
        "notFound": [
            "<string>"
        ]
    },
    "_req": {
        "reqId": "<string>",
        "resTime": 1
    }
}

Error envelope

Every failure below returns the same shape with success: false; branch on error.code, never on message.

  • successbooleanrequired
  • codeintegerrequired

    The HTTP status of this response, repeated in the body.

  • messagestringrequired
  • errorobjectrequired

    Machine-readable failure detail. Null on success.

    Show child attributesHide child attributes
    • codeenum<string>required

      Stable error code. Branch on this, never on message.

      Options: "auth.api_key_required", "auth.api_key_not_found", "auth.api_key_user_missing", "auth.api_key_owner_not_member", "auth.scope_missing", "auth.scope_ceiling_exceeded", "auth.key_project_restricted", "auth.product_restricted", "auth.permission_denied", "auth.self_mutation_forbidden", "auth.step_up_required", "auth.step_up_fresh_required", "auth.cli_token_not_accepted", "auth.two_factor_required", "auth.workspace_two_factor_required", "auth.two_factor_invalid", "auth.two_factor_replayed", "auth.two_factor_locked", "auth.two_factor_not_enabled", "auth.two_factor_already_enabled", "request.body_must_be_json", "request.body_invalid", "request.body_too_large", "request.rate_limited", "request.invalid_pagination", "workspace.not_found", "workspace.slug_conflict", "workspace.limit_reached", "workspace.delete_last", "workspace.delete_too_early", "workspace.delete_has_projects", "domain.not_configured", "domain.not_found", "domain.invalid", "domain.taken", "domain.attempt_limit", "product.not_found", "product.slug_conflict", "product.locked", "project.not_found", "project.ambiguous_product", "project.slug_conflict", "environment.not_found", "environment.slug_conflict", "environment.expose_disabled", "environment.expose_private_product", "variable.not_found", "variable.name_conflict", "variable.ciphertext_invalid", "variable.baseline_drifted", "version.not_found", "member.not_found", "member.already_exists", "member.self_invite", "member.self_mutation", "member.owner_immutable", "member.owner_cannot_leave", "member.seat_limit", "invite.already_pending", "role.owner_not_assignable", "role.limit_reached", "role.immutable", "role.in_use", "invite.not_found", "invite.expired", "role.not_found", "role.name_conflict", "key.not_found", "key.limit_reached", "webhook.not_found", "webhook.delivery_not_found", "plan.limit_reached", "plan.upgrade_required", "request.not_found", "request.method_not_allowed", "request.conflict", "auth.unauthorized", "auth.forbidden", "request.invalid", "server.error"

    • resourcestring

      The resource or scope the failure relates to.

    • fieldstring

      The request field that caused the failure.

  • dataobject | nullrequired

    Null on most failures. A plan limit carries { limit, current }.

  • _reqobject
    Show child attributesHide child attributes
    • reqIdstring
    • resTimeinteger | null
{
    "success": false,
    "code": 400,
    "message": "Something went wrong.",
    "error": {
        "code": "auth.api_key_required",
        "resource": "<string>",
        "field": "<string>"
    },
    "data": {},
    "_req": {
        "reqId": "<string>",
        "resTime": 1
    }
}

400Bad Request

request.invalid - the body is not JSON, or names is missing, empty, holds a non-string or empty string, or more than 200 entries; message says which.

401Unauthorized

  • auth.api_key_required - the Authorization header is missing, or its value does not start with ev_sk_.
  • auth.api_key_not_found - the key is unknown, inactive or revoked.
  • auth.api_key_user_missing - the key is valid but its owner no longer exists.
  • auth.api_key_owner_not_member - the key's owner is no longer a member of the key's workspace.

402Payment Required

plan.upgrade_required - the project is locked by the plan's project limit.

403Forbidden

  • auth.key_project_restricted - the key's project allowlist excludes this project, or auth.product_restricted for an inaccessible private product.
  • auth.workspace_two_factor_required - the workspace requires two-factor authentication and the key's owner has not turned it on.
  • auth.scope_missing - the key lacks a scope this operation requires; error.resource names it.

404Not Found

  • project.not_found - no project with that slug in the workspace.
  • request.not_found - the environment slug does not exist in the project.

409Conflict

project.ambiguous_product - the project slug exists under more than one product.

413Payload Too Large

request.body_too_large - the request body is larger than 1 MiB (1,048,576 bytes).

500Internal Server Error

server.error - an unexpected error; retry with backoff.

503Service Unavailable

server.error - the API is in maintenance mode or is missing its configuration; retry with backoff.