Variables

List variables

Lists the variables in one environment, sorted by name A to Z.

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

Lists the variables in one environment, sorted by name A to Z. Soft-deleted variables are excluded. Names come back with the casing they were stored with, and no two live variables in one environment can differ only in case.

value and defaultValue come back exactly as they were stored, which means ciphertext. The server holds no key material and cannot decrypt or encrypt anything. Decrypt client-side with the workspace key. Rows written before the ciphertext rule was enforced may still be plaintext, so treat any value that does not start with v1: or v2: as legacy plaintext rather than assuming decryption failed.

The public list takes no search or sort parameters. Paginate with limit and offset.

Requires the variables:read scope.

curl --request GET \
  --url 'https://api.envless.cloud/projects/<slug>/environments/<environmentSlug>/variables' \
  --header 'Authorization: Bearer ev_sk_xxxxxxxxxxxx'
Try itGEThttps://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 the project's uniqueId (uuid v7). An id is tried first and falls back to a slug lookup.

  • environmentSlugstringrequired

    Environment slug. Only the slug is accepted here, an environment uniqueId will not resolve.

Query parameters

  • productstring

    Product slug. Required only when the same project slug exists under more than one product, otherwise the request fails with 409 project.ambiguous_product.

  • limitintegermin 1max 100

    Page size, 1 to 100.

    Default: 25

  • offsetintegermin 0

    Rows to skip.

    Default: 0

Responses

200OK

List variables succeeded.

  • successbooleanrequired
  • codeintegerrequired

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

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

        Returned with the casing it was stored with. Live variables in one environment are unique without regard to case.

      • valuestring | null

        Ciphertext. Decrypt client-side with the workspace key.

      • typeenum<string>required

        Options: "string", "number", "boolean"

      • visibilityenum<string>required

        Options: "server", "client"

      • requiredbooleanrequired
      • defaultValuestring | null

        Ciphertext, encrypted with the same workspace key as value.

      • environmentIdstringrequired
      • createdAtstringrequireddate-time
      • updatedAtstring | nulldate-time
    • paginationobjectrequired
      Show child attributesHide child attributes
      • limitintegerrequired
      • offsetintegerrequired
      • totalCountintegerrequired
      • hasMorebooleanrequired
  • _reqobject
    Show child attributesHide child attributes
    • reqIdstring
    • resTimeinteger | null
{
    "success": true,
    "code": 200,
    "message": "OK",
    "error": null,
    "data": {
        "variables": [
            {
                "id": "<string>",
                "name": "<string>",
                "value": "<string>",
                "type": "string",
                "visibility": "server",
                "required": true,
                "defaultValue": "<string>",
                "environmentId": "<string>",
                "createdAt": "2026-05-30T10:14:22.000Z",
                "updatedAt": "2026-05-30T10:14:22.000Z"
            }
        ],
        "pagination": {
            "limit": 1,
            "offset": 1,
            "totalCount": 1,
            "hasMore": true
        }
    },
    "_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_pagination - limit is not a whole number between 1 and 100, or offset is not a whole number of 0 or greater.

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 because the workspace holds more projects than its plan allows. Locked projects refuse reads as well as writes until the plan is upgraded.

403Forbidden

  • auth.key_project_restricted - the key is pinned to a project allowlist that does not contain this project, or auth.product_restricted when the key owner has no access to the private product the project sits in.
  • 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 is not unique in the workspace. Retry with ?product=<productSlug>.

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.