/versions/{id}Returns one snapshot with its captured variables, addressed by version id and scoped to the workspace behind the API key. There is no environment-scoped read for a single version, ids are the only way in.
Each entry is { name, value } and value is the ciphertext exactly as it stood when the version was taken. The server cannot decrypt it. Decrypt with the workspace key that was in force at snapshot time, which is the reason a passphrase rotation must rewrite version entries as well as live variables.
The snapshot also stores defaultValue, type, isSecret, visibility and required per entry, and a rollback restores all of them, but this response deliberately exposes only name and value. Use GET .../versions/entries if you need the stored defaultValue ciphertext.
Entries are sorted by name. Requires both versions:read and variables:read.
Plan gate. Free workspaces can read only the latest version of each environment. Any older version returns 402 plan.upgrade_required with error.resource: "version" and data: null; the check runs after the existence check, so a 402 confirms the version exists. Dev, Team and Enterprise read every version.
Requires the versions:read or variables:read scope.
curl --request GET \
--url 'https://api.envless.cloud/versions/<id>' \
--header 'Authorization: Bearer ev_sk_xxxxxxxxxxxx'https://api.envless.cloud/versions/{id}Response headers
Authorization
AuthorizationstringrequiredheaderBearer token: an Envless API key (
ev_sk_…), created in the dashboard or withPOST /keys. The key is bound to one workspace; every request runs inside it.
Path parameters
idstringrequireduuidVersion uniqueId (uuid v7). Labels such as
v3are not accepted.
Responses
200OK
Get a version succeeded.
successbooleanrequiredcodeintegerrequiredThe HTTP status of this response, repeated in the body.
messagestringrequirederrornullrequireddataobjectrequiredShow child attributesHide child attributes
idstringrequiredlabelstringrequirednotestring | nullvariableCountintegerrequiredenvironmentIdstringrequiredcreatedAtstringrequireddate-timevariablesobject[]requiredShow child attributesHide child attributes
namestringrequiredvaluestring | nullCIPHERTEXT as captured. Decrypt with the workspace key in force when the version was taken.
_reqobjectShow child attributesHide child attributes
reqIdstringresTimeinteger | null
{
"success": true,
"code": 200,
"message": "OK",
"error": null,
"data": {
"id": "<string>",
"label": "<string>",
"note": "<string>",
"variableCount": 1,
"environmentId": "<string>",
"createdAt": "2026-05-30T10:14:22.000Z",
"variables": [
{
"name": "STRIPE_SECRET_KEY",
"value": "<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.
successbooleanrequiredcodeintegerrequiredThe HTTP status of this response, repeated in the body.
messagestringrequirederrorobjectrequiredMachine-readable failure detail. Null on success.
Show child attributesHide child attributes
codeenum<string>requiredStable 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"resourcestringThe resource or scope the failure relates to.
fieldstringThe request field that caused the failure.
dataobject | nullrequiredNull on most failures. A plan limit carries
{ limit, current }._reqobjectShow child attributesHide child attributes
reqIdstringresTimeinteger | null
{
"success": false,
"code": 401,
"message": "Something went wrong.",
"error": {
"code": "auth.api_key_required",
"resource": "<string>",
"field": "<string>"
},
"data": {},
"_req": {
"reqId": "<string>",
"resTime": 1
}
}401Unauthorized
auth.api_key_required- theAuthorizationheader is missing, or its value does not start withev_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 version's project is locked by the plan's project limit, or the workspace is on the Free plan and the version is not the latest one in its environment. In the second case error.resource is version and data is null; upgrade to read older versions.
403Forbidden
auth.scope_missing- the key lacksversions:readorvariables:read, both are required. Alsoauth.key_project_restrictedandauth.product_restrictedwhen the key or its owner cannot reach the version's project or product.auth.workspace_two_factor_required- the workspace requires two-factor authentication and the key's owner has not turned it on.
404Not Found
request.not_found - no version with that id in this workspace. The check runs before any project restriction, so a 403 on this route confirms the version exists.
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.
On the Free plan only the latest version of an environment is readable. Any older id answers 402 with error.code plan.upgrade_required, error.resource version and Your plan keeps only the latest version. Upgrade to browse, compare or restore earlier versions. Older versions and rollback need Dev or above. See Plans and billing.