/projects/{slug}/environments/{environmentSlug}/versions/entriesReads the raw ciphertext of every version entry in the environment, across all versions, so it can be re-encrypted client-side. Together with POST .../versions/entries/reencrypt this is the passphrase rotation pair.
Rotation flow: page through this endpoint, decrypt each value and defaultValue with the old workspace key, re-encrypt with the new one, and post the results back to the reencrypt endpoint keyed by the same id.
Rotating the live variables without also rotating the version entries silently breaks every later rollback. Nothing errors at rotation time. The live variables decrypt fine under the new key, the snapshots still decrypt only under the old one, and the breakage only shows up when someone rolls back and the restored values become undecryptable garbage. Rotate both, in the same run.
The payload is deliberately thin. There is no name and no version id on an entry, because rotation is blind, you decrypt and re-encrypt by id alone. Pagination is applied in memory after loading the environment's entries, so it is stable within a run but not cheap on very large environments. Requires both versions:read and variables:read.
This feed is deliberately not limited by the plan's version history: a Free workspace can rotate the entries of every stored version, so the history it keeps for a later upgrade stays decryptable.
Requires the versions:read or variables:read scope.
curl --request GET \
--url 'https://api.envless.cloud/projects/<slug>/environments/<environmentSlug>/versions/entries' \
--header 'Authorization: Bearer ev_sk_xxxxxxxxxxxx'https://api.envless.cloud/projects/{slug}/environments/{environmentSlug}/versions/entriesResponse 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
slugstringrequiredProject slug or project uniqueId.
environmentSlugstringrequiredEnvironment slug. A uniqueId will not resolve.
Query parameters
productstringProduct slug, to disambiguate a project slug shared across products.
limitintegermin 1max 100Page size, 1 to 100. The reencrypt endpoint accepts up to 200 entries per call, so pages of 100 are the practical maximum round trip.
Default:
25offsetintegermin 0Rows to skip.
Default:
0
Responses
200OK
List version entry ciphertext succeeded.
successbooleanrequiredcodeintegerrequiredThe HTTP status of this response, repeated in the body.
messagestringrequirederrornullrequireddataobjectrequiredShow child attributesHide child attributes
entriesobject[]requiredShow child attributesHide child attributes
idstringrequiredvaluestring | nullCiphertext.
defaultValuestring | nullCiphertext.
paginationobjectrequiredShow child attributesHide child attributes
limitintegerrequiredoffsetintegerrequiredtotalCountintegerrequiredhasMorebooleanrequired
_reqobjectShow child attributesHide child attributes
reqIdstringresTimeinteger | null
{
"success": true,
"code": 200,
"message": "OK",
"error": null,
"data": {
"entries": [
{
"id": "<string>",
"value": "<string>",
"defaultValue": "<string>"
}
],
"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.
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": 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 outside 1 to 100 or either pagination value is not a whole number.
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 project is locked by the plan's project limit. This rotation feed is not history-gated, Free workspaces can rotate the entries of every version.
403Forbidden
auth.scope_missing- the key lacksversions:readorvariables:read, both are required. Alsoauth.key_project_restrictedandauth.product_restrictedfor projects and products the key cannot reach.auth.workspace_two_factor_required- the workspace requires two-factor authentication and the key's owner has not turned it on.
404Not Found
project.not_found - unknown project, or environment.not_found for an unknown environment slug.
409Conflict
project.ambiguous_product - the project slug exists under more than one product.
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.