---
title: "Creates an environment in the resolved project."
method: POST
path: "/api/v1/orgs/{org}/projects/{project}/environments"
tags: ["Environments"]
---

# Creates an environment in the resolved project.

`POST /api/v1/orgs/{org}/projects/{project}/environments`

## Request

- Base URL: `https://api.featureflip.io`
- URL: `https://api.featureflip.io/api/v1/orgs/{org}/projects/{project}/environments`
- Auth: API key in header `Authorization`

Requires at least Member. An environment past
the plan's per-project environment cap is a 403 `plan_limit_reached`.

## Path parameters

- `org` string, required
- `project` string, required

## Request body

- PublicCreateEnvironmentRequest: Request body for `POST /api/v1/orgs/{org}/projects/{project}/environments`. Named distinctly from the dashboard's own `CreateEnvironmentRequest` — both controllers share one Swagger document (see `Program.cs`'s `AddSwaggerGen``DocInclusionPredicate` override), and Swashbuckle's default schemaId is the bare type name, so an identical name in either namespace throws a schemaId collision at `--export-openapi` time.
  - `key` string, nullable, required
  - `name` string, nullable, required
  - `color` string, nullable
  - `sortOrder` integer

## Response `201`

Created

- PublicEnvironmentResponse: Public representation of an environment, returned by `GET /api/v1/orgs/{org}/projects/{project}/environments` (list), `GET .../environments/{env}` (detail), and the body of a successful create/update. Drops internal fields (e.g. `ProjectId` is implicit in the route) — mirrors `ProjectResponse`'s minimal shape. Named `PublicEnvironmentResponse` rather than `EnvironmentResponse` (unlike the sibling `ProjectResponse`, which didn't collide) because the dashboard already has its own `EnvironmentResponse` — see PublicCreateEnvironmentRequest for the schemaId-collision rationale.
  - `id` string, uuid, required
  - `key` string, nullable, required
  - `name` string, nullable, required
  - `color` string, nullable
  - `sortOrder` integer, required
  - `_actions` object: Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller's role and the resource's state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it.

## Other responses

- `400`: The request is malformed, or it carries an If-Match header, which this endpoint can't evaluate. Send no If-Match, or `*`.
- `401`: Authentication is required, or the supplied API token is invalid or expired.
- `403`: Forbidden
- `404`: Not Found
- `429`: Rate limit exceeded. Retry after the interval indicated by the Retry-After header.

---

[API](https://skmtc.dev/featureflip/apis/management-api.md) · [All operations](https://skmtc.dev/featureflip/apis/management-api/llms.txt) · [OpenAPI document](https://skmtc.dev/featureflip/apis/management-api/revisions/8a77e8581a45?raw)
