# OrgOrg API v1 — Environment Variables — instructions for AI agents

This document describes the Environment Variables endpoints of the OrgOrg v1 REST API. Fetch it from https://orgorg.com/docs/api/v1/env/agents.md. The full API is documented at https://orgorg.com/docs/api/v1/agents.md.

## Basics

- Base URL: `https://orgorg.com`. All endpoint paths below are relative to it.
- Every request requires an `Authorization: Bearer <token>` header.
- `GET` endpoints take parameters in the URL query string. `POST` endpoints take a JSON body with a `Content-Type: application/json` header.
- All responses are JSON. A non-2xx status means the request failed; the body describes the problem.
- Endpoints are stable, but new response fields may be added without notice — ignore fields you do not recognize.

## Getting a token

Tokens are created by a signed-in user at https://orgorg.com/docs/credentials and inherit that user's permissions in their organization. If you do not have a token, ask your user to create one there. Verify a token works with:

```sh
curl "https://orgorg.com/api/v1/auth/test" \
  -H "Authorization: Bearer $ORGORG_API_TOKEN"
```

A valid token returns `{ "ok": true, ... }`.

## Environment Variables

The environments of the Environment Variables app. Resolve the variables of an environment, names only or with values, import an env file, and run a provider sync. The orgorg CLI uses these endpoints for its env commands. Human-readable docs: https://orgorg.com/docs/api/v1/env

### Resolve an environment

`GET /api/v1/env/resolve`

The variables of one environment of the Environment Variables app, resolved along its parent chain. Without reveal, the names and their defining environment. With reveal=1, the values too: the store decrypts them, logs the read to your token, and the response is never cached. With key, only the named keys: the store decrypts only those, and the read log lists only those. An API token needs the env:read scope and Read access to the environment. A service token reads the one environment it is bound to, and needs no project and no environment. The response lists the services of the project, the consumers of its values, and each variable names the services of its key by slug. With service, only the keys of the named services: the CLI materializes what the command runs.

Parameters:

- `project` (string, optional) — The project slug, for example orgorg. Required with an API token.
- `environment` (string, optional) — The environment slug, for example development. Required with an API token.
- `reveal` (string, optional) — 1 to include the values. Anything else returns names only.
- `key` (string, optional) — Only this variable. Repeat the parameter for several variables, 100 at most.
- `service` (string, optional) — Only the keys of this service, by slug. Repeat the parameter for several services.

Example request:

```sh
curl -X GET "https://orgorg.com/api/v1/env/resolve?project=orgorg&environment=development" \
  -H "Authorization: Bearer $ORGORG_API_TOKEN"
```

Response shape:

```ts
{
  project: { slug: string; name: string };
  environment: { slug: string; name: string };
  variables: {
    key: string;
    value?: string;
    definedIn: string;
    public: boolean;
    services: string[]; // slugs of the services below
  }[];
  services: { slug: string; name: string }[];
}
```

### List the environments of a project

`GET /api/v1/env/project`

What the picker of `orgorg env run` shows: each environment of the project that you may read and that is not protected, with its parent, its owner, the number of values it sets itself, and the required names that it does not resolve. Also the key names of the project, and whether your token can make an environment. Nothing is decrypted. Needs an API token with the env:read scope.

Parameters:

- `project` (string, required) — The project slug, for example orgorg.
- `require` (string, optional) — A variable name that your command needs. Repeat the parameter for several names, 100 at most. Each environment lists the names that it does not resolve.

Example request:

```sh
curl -X GET "https://orgorg.com/api/v1/env/project?project=orgorg&require=CONVEX_DEPLOY_KEY" \
  -H "Authorization: Bearer $ORGORG_API_TOKEN"
```

Response shape:

```ts
{
  project: { slug: string; name: string };
  me: { profileId: number; name: string };
  devParent: string | null;
  canCreate: boolean;
  keyNames: string[];
  environments: {
    slug: string;
    name: string;
    parent: string | null;
    isParent: boolean;
    protected: boolean;
    owner: string | null;
    mine: boolean;
    ownValues: number;
    missing: string[];
  }[];
}
```

### Make a development environment

`POST /api/v1/env/dev-environment`

Make an environment of your own that extends development, with its first values, in one step. An environment is never empty: pass at least one entry of a key that the project has. A key that the project does not have sets nothing, and the response names it. When the step fails, nothing stays behind. Needs an API token with the env:dev scope and Read access to the development environment. This scope cannot write to an environment that exists.

Parameters:

- `project` (string, required) — The project slug, for example orgorg.
- `name` (string, required) — The name of the new environment, for example dev-alex.
- `entries` (object, required) — The first values: a list of { key, value } pairs of strings, 1 to 1000 entries.

Example request:

```sh
curl -X POST "https://orgorg.com/api/v1/env/dev-environment" \
  -H "Authorization: Bearer $ORGORG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "orgorg",
    "name": "dev-example",
    "entries": [
      {
        "key": "EXAMPLE_KEY",
        "value": "example value"
      }
    ]
  }'
```

Response shape:

```ts
{
  environment: { slug: string };
  written: number;
  unknown: string[];
}
```

### Import an env file

`POST /api/v1/env/import`

Write the entries of an env file into the environment of a service token. A key that exists gets the new value, and a new key is added for the CLI. The store encrypts each value, and the response carries counts only. Needs a service token as the bearer, not an API token.

Parameters:

- `entries` (object, required) — A list of { key, value } pairs of strings, 1 to 1000 entries.

Example request:

```sh
curl -X POST "https://orgorg.com/api/v1/env/import" \
  -H "Authorization: Bearer $ORGORG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entries": [
      {
        "key": "EXAMPLE_KEY",
        "value": "example value"
      }
    ]
  }'
```

Response shape:

```ts
{
  project: { slug: string };
  environment: { slug: string };
  created: number;
  updated: number;
  keysAdded: number;
}
```

### Sync an environment with a provider

`POST /api/v1/env/sync`

Run the sync target of one service in a service token environment. A pull imports the variables of the provider into the environment. A push sends the variables of the environment to the provider. The store does the provider work, and no value comes back. Needs a service token as the bearer, not an API token.

Parameters:

- `direction` (`pull` | `push`, required) — pull or push.
- `service` (string, optional) — The slug of the service, from the services of the resolve response. Required unless provider is given.
- `provider` (`vercel` | `convex` | `github` | `cloudflare` | `gcp`, optional) — The transport kind, for a caller from before the services: it names the service the migration made for that kind.

Example request:

```sh
curl -X POST "https://orgorg.com/api/v1/env/sync" \
  -H "Authorization: Bearer $ORGORG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "direction": "pull",
    "provider": "vercel"
  }'
```

Response shape:

```ts
// pull
{
  pulled: number;
  nameOnly: string[];
  created: number;
  updated: number;
  keysAdded: number;
}
// push
{
  pushed: number;
}
```
