HTTP API

Overview

A REST API for managing your encrypted environment variables: values stay encrypted, and the server never sees plaintext.

The Envless HTTP API lets you read and write your workspace, products, projects, environments, variables, and versions from any language or platform. Variable values are always returned (and must be sent) as ciphertext; decryption and encryption happen client-side with your workspace key. The server never holds plaintext.

Authenticate every request with a personal access key (ev_sk_...) as a bearer token. Keys carry per-resource scopes (11 resources, each none, read or write) and an optional project allowlist, and a key is permanently bound to the one workspace it was created in. See Authentication.

Base URL

plaintext
https://api.envless.cloud

The root above is canonical, and it is what the SDKs and the CLI use by default. The /v1 prefix remains a permanent alias for every endpoint, so clients written against it keep working. Every response also carries an Envless-Api-Version: v1 header.

The machine-readable OpenAPI 3.1 description of every endpoint is published at https://envless.cloud/openapi.json. It is generated from the API's route table, the same source as the endpoint pages in these docs, so you can feed it to a client generator, a mock server or an LLM.

What you can do today

ResourceReadCreateUpdateDelete
Workspace✅✅✅✅
Custom domain✅✅ (claim)✅ (verify)✅ (remove)
Products✅✅ + ✅ (duplicate)✅✅
Product access✅✅ (grant)n/a✅ (revoke)
Projects✅✅ + ✅ (duplicate)✅✅
Environments✅✅ + ✅ (duplicate)✅ + ✅ (expose)✅
Variables✅ (ciphertext)✅ (single, bulk, atomic apply)✅ (ciphertext)✅ (single + bulk)
Versions✅ (ciphertext)✅ + ✅ (rollback)✅ (re-encrypt entries)❌
Members✅✅ (invite)✅ (role)✅
Invites✅n/a✅ (resend)✅ (revoke)
Roles✅✅✅✅
API keys✅✅✅✅
Webhooks✅✅✅ + ✅ (rotate secret)✅
Webhook deliveries✅✅ (redeliver)n/a❌

Almost everything a team can do in the dashboard can be driven over the API. Variable value must be encrypted client-side or the request is rejected with variable.ciphertext_invalid (see Encrypting Values); defaultValue is held to the same rule on the bulk and apply endpoints. Deliberately dashboard-only: account deletion, API-key rotation (create a new key and delete the old one), and product icon uploads, which PATCH /products/:slug rejects with a 400. Billing and subscriptions have no public endpoints.

Two writes carry extra preconditions. POST /projects/:slug/environments/:environmentSlug/expose needs virtualEnvsEnabled turned on for the workspace first (PATCH /workspace), and it refuses environments inside a private product, both with a 409. DELETE /workspace requires the owner, refuses your last workspace, a workspace younger than 7 days, and one that still has projects, and it cancels any live subscription as it goes.

Deletes are destructive and cascade down (deleting a project hides its environments → variables → versions). There is no undo via the public API. Mint keys with the narrowest scopes that get the job done (read-only, or limited to specific projects), so a leaked key can't delete anything it shouldn't.

Quick example

bash
curl https://api.envless.cloud/projects \
    -H "Authorization: Bearer ev_sk_xxxxxxxxxxxx"
json
{
    "success": true,
    "code": 200,
    "message": "OK",
    "error": null,
    "data": {
        "projects": [
            {
                "id": "0b0d3f1e-6c1a-4f2b-9a5e-2b7f0c9d4a13",
                "name": "my-app",
                "slug": "my-app",
                "icon": null,
                "product": {
                    "id": "7c2b8a41-9e35-4d70-bd18-5f6a1c3e9042",
                    "slug": "platform",
                    "name": "Platform"
                },
                "createdAt": "2026-05-30T10:14:22.000Z",
                "updatedAt": "2026-05-30T10:14:22.000Z"
            }
        ],
        "pagination": { "limit": 25, "offset": 0, "totalCount": 1, "hasMore": false }
    }
}

Every response uses that envelope: error is null on success and an object on failure, and _req carries the response time plus the Request-Id you sent, if you sent one. Ids are UUIDs, not prefixed strings. Paginated lists default to limit=25, and a limit above 100 is rejected with 400 request.invalid_pagination rather than clamped.

Where to go from here

End-to-end encryption note

Variable values returned by the API are always ciphertext. To use them, decrypt locally with the workspace key, the same key the CLI and runtime use. The Envless API server cannot decrypt your data and never has. This is the same e2e model that protects you in the dashboard.

You do not have to write that crypto yourself. @goenvless/env/crypto ships the exact primitives the dashboard and CLI use (encrypt, decrypt, encryptWithKey, decryptWithKey, workspaceKey, importWorkspaceKey, passphraseStrength, ENCRYPTION_PARAMETERS) on pure Web Crypto, with no Node built-ins and no Buffer, so it runs anywhere this API does. When you want the whole environment rather than the primitives, @goenvless/env/edge calls these same endpoints with your ev_sk_ key and returns a decrypted plain record: it needs no filesystem, does not touch process.env, and keeps no cache.