1. Docs
  2. API Reference
  3. Replace an Environment's configuration from a JSON payload (destructive)

Replace an Environment's configuration from a JSON payload (destructive)

POST/api/v1/environments/{id}/import

Replaces the configuration of the Environment :id with the supplied export document. This is destructive: existing roles, permissions, nodes, OAuth clients, webhook subscriptions, and pending invites in the target are wiped before the payload is applied within a single transaction; organization role templates are matched by name, a template the target already has updated in place so its organizations' copies keep naming it, and the target's others deleted; identities, memberships, and assignments survive except where cascading role/node deletes remove dangling rows. The payload must declare a supported format_version (400 otherwise) and contain exactly one root node, with duplicate keys, cyclic parents, orphaned nodes, and unknown permission references each rejected as 400. Every imported role lands as a custom role whatever the payload's is_system_role says, as a permission lands as custom unless its key is reserved. Returns 200 with one-time OAuth client and webhook signing-secret rotation receipts and emits an environment.imported audit event; 404 when no Environment of the Account has that id.

Authentication

Bearer TokenAuthorization Option A

JWT access token. Never send alongside X-API-Key: a request carrying both is refused.

API KeyX-API-Key Option B

API key for management-tier access. Never send alongside an Authorization header: a request carrying both is refused.

Requires all of application.manageAccount

Create, update, and delete Applications and Environments, and change Environment settings. Every one of these is checked. A scoped API key must hold each as a scope; a developer's token needs the Console capabilities that cover them.

Requires all of auth_settings.manageAuthentication

Change the Environment's sign-in settings. Held only when named: full access does not include it. Every one of these is checked. A scoped API key must hold each as a scope; a developer's token needs the Console capabilities that cover them.

Path Parameters

idstring Required

Request body

application/json

format_versionnumber Required
source_envobject Required
access_modelenum Required

one of "flat" · "hierarchy"

organizations_enabledboolean Required
hierarchy_schemaobject Required
auth_settingsobject Required

The sign-in policy, replacing the target's: a setting left out returns to its default. The target keeps its web origins, return URLs, sign-in addresses, passkey relying party, machine-token audience and the settings naming its roles.

token_claimsTokenClaimEntryDto[] Required

The custom claims, replacing the target's; an empty list removes them

permissionsany[] Required
rolesany[] Required
organization_role_templatesany[] Required

The organization role templates, replacing the target's: a template whose name the target already has is updated in place, so its organizations' copies keep naming it

nodesany[] Required
oauth_clientsany[] Required
webhooksany[] Required
metadataobject Optional

Responses

application/json

  • dataEnvironmentCloneResponseDto*

application/json

  • errorApiErrorBodyDto*

application/json

  • errorApiErrorBodyDto*

application/json

  • errorApiErrorBodyDto*

application/json

  • errorApiErrorBodyDto*

Errors

When the request can't be completed, the response body includes a stable error code you can branch on, and a correlation_id (also sent as the X-Correlation-Id header). Quote the correlation id when you contact support: it identifies the exact request in Canopy's logs. A request refused by an authorization check answers 403 with the code authorization.denied, and its data names the denial_reason and the permission checked.

403authorization.deniedForbidden
When it happens

The credential does not hold the permission this operation checks: a scoped API key without the scope, a developer without the Console capability that covers it, or a permission granted somewhere other than the node the request targets. The error's data names the permission.

Remediation

Add the permission named in the Authentication section to the key's scopes, or ask an account administrator to grant the covering capability, then retry. For a node-scoped operation, make sure the grant reaches the node you are acting on.

Returned object

Request
curl -X POST "https://auth.canopy-io.com/api/v1/environments/value/import" \
  -H "X-API-Key: $CANOPY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "format_version": 1,
    "source_env": {},
    "access_model": "flat",
    "organizations_enabled": false,
    "hierarchy_schema": {},
    "auth_settings": {
      "mfa_required": false,
      "mfa_grace_period_days": 0,
      "mfa_trusted_device_days": 0,
      "mfa_factor_allowlist": [
        "totp"
      ],
      "mfa_after_sso": "exempt",
      "allow_self_signup": false,
      "self_signup_require_captcha": false,
      "login_require_captcha": false,
      "password_login_enabled": false,
      "email_otp_login_enabled": false,
      "passkey_login_enabled": false,
      "self_signup_daily_cap": 0,
      "access_token_ttl_seconds": 0,
      "refresh_token_ttl_days": 0,
      "public_refresh_token_ttl_days": 0,
      "m2m_access_token_ttl_seconds": 0,
      "organizations_create_on_signup": false,
      "organizations_membership_required": false
    },
    "token_claims": [
      {
        "claim": "plan",
        "source": "identity.metadata.plan",
        "tokens": [
          "access",
          "id"
        ]
      }
    ],
    "permissions": [
      null
    ],
    "roles": [
      null
    ],
    "organization_role_templates": [
      null
    ],
    "nodes": [
      null
    ],
    "oauth_clients": [
      null
    ],
    "webhooks": [
      null
    ],
    "metadata": {}
  }'
Response
{
  "data": {
    "environment": {
      "id": "string",
      "application_id": "string",
      "name": "string",
      "slug": "string",
      "is_production": false,
      "settings": {},
      "version": 0,
      "created_at": "2026-04-20T12:00:00.000Z",
      "updated_at": "2026-04-20T12:00:00.000Z"
    },
    "oauth_client_rotations": [
      {
        "source_client_id": "string",
        "client_id": "string",
        "client_secret": "string"
      }
    ],
    "webhook_subscription_rotations": [
      {
        "id": "string",
        "url": "string",
        "secret": "string"
      }
    ]
  }
}
Related endpoints
GETGet an Environment
PATCHRename, re-slug or promote an Environment
DELETEDelete an Environment
GETExport an Environment's configuration as JSON
Was this page helpful?

Tell us how we can improve this guide.