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

# Create Environment

> Create an environment in one of your connected cloud accounts.

Provisioning runs asynchronously. Follow it by polling `GET /v1/environments/{envId}` until `state` is `available` or `create_failed`, or by following the returned `op_id`.

<Warning>
  This endpoint is not live yet. The shapes below show how it is expected to work so you can plan your
  integration, and may change before release. Calls to this path return `404` today.
</Warning>


## OpenAPI

````yaml /openapi.json post /v1/environments
openapi: 3.0.0
info:
  title: LocalOps API
  version: 1.0.0
  description: >-
    API for programmatically managing LocalOps environments and services.


    Every successful response (except `GET /health` and `DELETE
    /v1/environments/{envId}/services/{serviceId}`) is wrapped in an envelope:
    `{ "message": "success", "data": { ... } }`. Errors are returned unwrapped
    as `{ "error_code": "...", "message": "...", "errors": [...] }`.


    Deploys, deletes, secret writes and custom domain deploys are asynchronous.
    A 2xx confirms that the request was accepted and passed synchronous
    validation - observe the outcome by polling deployment state, service state
    or custom domain state.


    Endpoints badged **COMING SOON** are not live yet. Their request and
    response shapes are published so you can plan an integration, and may change
    before release - calls to those paths return `404` today.
servers:
  - url: https://sdk.localops.co
security:
  - bearerAuth: []
tags:
  - name: Health
    description: Liveness probe.
  - name: Environments
    description: Read an environment's identity, network edges and workload identity.
  - name: Services
    description: Create, read, update and delete services inside an environment.
  - name: Deployments
    description: Trigger deployments and poll their state.
  - name: Operations
    description: Track asynchronous work, with per operation status, error and logs.
  - name: Custom Domains
    description: Attach and verify custom domains for a service.
  - name: Secrets
    description: Read and replace environment level and service level secrets.
paths:
  /v1/environments:
    post:
      tags:
        - Environments
      summary: Create Environment
      description: >-
        Create an environment in one of your connected cloud accounts.


        Provisioning runs asynchronously. Follow it by polling `GET
        /v1/environments/{envId}` until `state` is `available` or
        `create_failed`, or by following the returned `op_id`.
      operationId: createEnvironment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - project_id
                - cloud_connection_id
                - cloud_region_code
              properties:
                name:
                  type: string
                  description: Name of the environment
                project_id:
                  type: string
                  format: uuid
                  description: The LocalOps project the environment belongs to
                cloud_connection_id:
                  type: string
                  format: uuid
                  description: The cloud account connection to create the environment in
                cloud_region_code:
                  type: string
                  description: For example `aws-us-east-1` or `gcp-us-central1`
                custom_cidr:
                  type: string
                  description: VPC CIDR block. LocalOps picks one when omitted.
            example:
              name: production
              project_id: 5b0d1e2f-0000-0000-0000-000000000000
              cloud_connection_id: c9e10a3b-0000-0000-0000-000000000000
              cloud_region_code: aws-us-east-1
              custom_cidr: 10.20.0.0/16
      responses:
        '202':
          description: Environment create accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      environment:
                        $ref: '#/components/schemas/Environment'
                      op_id:
                        type: string
                        format: uuid
              example:
                message: success
                data:
                  environment:
                    id: 6a1f7e0c-0000-0000-0000-000000000000
                    name: production
                    state: create_queued
                    cloud_region_code: aws-us-east-1
                    ingress_host: ''
                    public_nat_ips: []
                    svc_role_arn: ''
                    default_origin: https://production-a1b2.localops.co
                    created_at: '2026-10-01T10:00:00Z'
                  op_id: 7f3a9b20-0000-0000-0000-000000000000
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    Environment:
      type: object
      description: >-
        A LocalOps environment. `ingress_host`, `public_nat_ips` and
        `svc_role_arn` are read live from the environment's infrastructure on
        every request.
      properties:
        id:
          type: string
          format: uuid
          description: The environment identifier used as `envId` across this API
        name:
          type: string
        state:
          type: string
          enum:
            - create_queued
            - creating
            - create_failed
            - available
            - unavailable
            - archive_queued
            - archiving
            - archived
            - archive_failed
        cloud_region_code:
          type: string
          description: >-
            Cloud and region the environment runs in, for example
            `aws-us-east-1` or `gcp-us-central1`
        ingress_host:
          type: string
          description: >-
            Load balancer in front of the environment's ingress. A hostname on
            AWS, an IP address on GCP - create a `CNAME` for a hostname and an
            `A` record for an IP. Empty until the environment is provisioned.
        public_nat_ips:
          type: array
          items:
            type: string
          description: >-
            NAT gateway addresses the environment's outbound traffic leaves
            from. Allowlist them in your own firewalls and database security
            groups. Empty until the environment is provisioned, and for any
            provider or environment with no NAT addresses. The list can change,
            so re-read it after infrastructure changes rather than caching it
            indefinitely.
        svc_role_arn:
          type: string
          description: >-
            **AWS only.** IAM role the environment's pods assume. Name it as a
            principal in your own bucket, queue and KMS key policies. It is an
            identifier, not a credential - naming it grants nothing until you
            also set up the trust in your own account. Empty until the
            environment is provisioned, and always empty on GCP, where the
            equivalent identity is a service account.
        default_origin:
          type: string
          description: >-
            The LocalOps managed origin for the environment, ignoring any custom
            domain
        created_at:
          type: string
          format: date-time
    Error:
      type: object
      properties:
        error_code:
          type: string
          enum:
            - unauthorized
            - forbidden
            - notfound
            - conflict
            - validation
            - unknown
          description: >-
            Machine readable error code. Treat this, and not the HTTP status, as
            the signal for whether the request was at fault - some business rule
            violations are returned as `500` with `error_code: validation`.
        message:
          type: string
          description: Human readable error message
        errors:
          type: array
          nullable: true
          description: >-
            Per field details. Present only on validation errors, and can be
            null when the failure has no field level detail.
          items:
            $ref: '#/components/schemas/FieldError'
    FieldError:
      type: object
      properties:
        field:
          type: string
          description: Name of the request field that failed validation
        error:
          type: string
          description: Reason the field was rejected
  responses:
    Unauthorized:
      description: Missing, malformed or unknown API token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error_code: unauthorized
            message: You are not authorized to do this action
    Forbidden:
      description: >-
        The account has no active plan, the plan does not include the requested
        feature, or the service is being deleted
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error_code: forbidden
            message: You don't have an active plan
    NotFound:
      description: >-
        The environment, service, deployment, custom domain or connection does
        not exist, or belongs to another account
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error_code: notfound
            message: Service not found
    ValidationError:
      description: >-
        Field validation failed, or the request body was missing or malformed.
        Endpoints that take a body always need at least `{}` - a zero byte body
        fails to bind.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            field:
              summary: Field validation
              value:
                error_code: validation
                message: Invalid data
                errors:
                  - field: replica_count
                    error: replica_count is a required field
            body:
              summary: Missing or malformed body
              value:
                error_code: validation
                message: Please check your request body
    ServerError:
      description: >-
        Unexpected failure. Some business rule violations are also returned here
        with `error_code: validation` - check `error_code` rather than the
        status to decide whether the request was at fault.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unknown:
              summary: Unexpected failure
              value:
                error_code: unknown
                message: Something went wrong. Please try again later
            rule:
              summary: Business rule violation
              value:
                error_code: validation
                message: Ops Json is only supported for docker image source
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: UUID
      description: >-
        Your account API token, sent as `Authorization: Bearer <api_token>`.
        Owners and admins can read the token from the LocalOps console.

````