> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livry.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments in the Livry Public API

> List and read the Environments you hold a grant on, including their cache lifetime, labels and your role in each.

An Environment is the isolation boundary — sandbox, staging or production. Themes belong to one, and
nothing crosses between them.

This API **reads** Environments and does not create, rename or delete them. Those are account-plane
acts; see [what the API deliberately does not do](/api/introduction).

## List Environments

```http theme={null}
GET /public/v1/environments
```

Returns **only the Environments you hold a grant on**, not the Team's Environments with yours marked.

<ParamField query="orderDir" type="string" default="ascending">
  `ascending` or `descending`, by slug.
</ParamField>

<ParamField query="pageNumber" default="1" type="integer" />

<ParamField query="pageSize" default="100" type="integer" />

<ParamField query="includeTotals" default="false" type="boolean" />

<CodeGroup>
  ```bash Request theme={null}
  curl "https://api.livry.dev/public/v1/environments?includeTotals=true" \
    -H "Authorization: Bearer $ACCESS_TOKEN"
  ```

  ```json Response 200 theme={null}
  {
    "totalCount": 2,
    "totalPages": 1,
    "pageSize": 100,
    "pageNumber": 1,
    "pageCount": 2,
    "items": [
      {
        "id": "nR7xL2vB:production",
        "slug": "production",
        "displayName": "Production",
        "kind": "production",
        "description": "Customer-facing. Changes here are reviewed.",
        "metadata": {
          "owner": "platform-team"
        },
        "cacheLifetime": 300,
        "role": "editor",
        "createdAt": "2026-08-21T02:14:55Z",
        "updatedAt": "2026-09-15T23:01:02Z"
      },
      {
        "id": "nR7xL2vB:sandbox",
        "slug": "sandbox",
        "displayName": "Sandbox",
        "kind": "sandbox",
        "description": null,
        "metadata": {},
        "cacheLifetime": 60,
        "role": "admin",
        "createdAt": "2026-08-21T02:14:55Z",
        "updatedAt": "2026-08-21T02:14:55Z"
      }
    ]
  }
  ```
</CodeGroup>

## Read one Environment

```http theme={null}
GET /public/v1/environments/{environmentID}
```

<ParamField path="environmentID" type="string" required>
  The Environment's `id`, as returned by the list. Not its slug.
</ParamField>

Answers `404` when it does not exist **or** belongs to a Team you are not in, and `403` when you are
in the Team but hold no grant on it.

## The Environment resource

<ResponseField name="id" type="string" required>
  The addressable key. Put this in a URL, not the slug.
</ResponseField>

<ResponseField name="slug" type="string" required>
  The URL segment a person sees in the portal. Unique within the Team.
</ResponseField>

<ResponseField name="displayName" type="string" required />

<ResponseField name="kind" type="string" required>
  `sandbox`, `staging` or `production`.
</ResponseField>

<ResponseField name="description" type="string | null">
  What the Environment is for, in the customer's own words.
</ResponseField>

<ResponseField name="metadata" type="object" required>
  Free key/value labels for your own tooling, as a flat object.

  The portal sends these as a list of pairs because GraphQL has no map type. JSON has one, so this
  API returns an object — reading a label by key should not mean scanning an array.

  <Warning>
    **Never put a secret in a label.** They are readable by anyone who can read the Environment.
  </Warning>
</ResponseField>

<ResponseField name="cacheLifetime" type="integer" required>
  How many seconds a `latest` answer for any Theme here may be reused by the edge.

  Operationally: it is how long after a publish the CDN may still be serving the previous version to
  an app that asks for `latest`. Pinned version URLs are unaffected — they never change. See
  [Caching](/serving/caching).
</ResponseField>

<ResponseField name="role" type="string" required>
  Your grant on this Environment: `viewer`, `editor` or `admin`. Always present, because this API
  only ever returns an Environment you hold a grant on.
</ResponseField>

<ResponseField name="createdAt" type="string" required />

<ResponseField name="updatedAt" type="string" required />

<Note>
  `createdBy` and `updatedBy` are deliberately withheld. They name a user, and this API has no member
  endpoints to resolve one with — publishing an internal user id you cannot look up would be a
  promise we would then have to keep.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.