---
title: "Create or update a certificate"
method: PUT
path: "/organizations/{orgId}/environments/{envId}/domains/{domainKey}/certificates"
tags: ["Certificates", "Domains"]
---

# Create or update a certificate

`PUT /organizations/{orgId}/environments/{envId}/domains/{domainKey}/certificates`

## Request

- Base URL: `http://localhost:8093/automation`
- URL: `http://localhost:8093/automation/organizations/{orgId}/environments/{envId}/domains/{domainKey}/certificates`
- Auth: HTTP bearer

Idempotent create-or-update. Uses the key field in the body to identify the certificate within the domain. Re-applying an unchanged definition is a no-op. The system flag is immutable; changing it requires deleting and recreating the certificate. When dryRun is true, the endpoint validates the payload without persisting; the returned certificate carries a dryRunErrors list (empty on success, populated with validation errors otherwise).

## Path parameters

- `orgId` string, required
- `envId` string, required
- `domainKey` string, required

## Query parameters

- `dryRun` boolean

## Request body

- AutomationCertificate: A certificate managed under a domain by the Automation API. The key field is the stable, immutable identity used for idempotent create-or-update.
  - `configuration` string: Plugin-specific configuration as a JSON-encoded string. Its shape is defined by the selected certificate type. Sensitive values, as flagged by the plugin, are returned as ******** in every response; an unset sensitive value is omitted. Sending ******** back on update keeps the stored value; sending it on create is rejected. The uploaded keystore file is masked too; sending ******** back keeps it.
  - `createdAt` string, date-time: Creation timestamp (ISO-8601 / RFC 3339, UTC). Read-only.
  - `dryRunErrors` DryRunError[]: Validation errors returned when dryRun is true. Absent when validation succeeds.
    - `message` string
    - `severity` 'error' | 'warning'
  - `expiresAt` string, date-time: Expiry timestamp (ISO-8601 / RFC 3339, UTC), when known for the certificate type. Read-only.
  - `key` string, required: Stable, immutable identifier for the certificate within its domain. Lowercase alphanumeric and hyphens, starting and ending with an alphanumeric character. Used to identify the certificate on create-or-update.
  - `name` string: Human-readable name of the certificate.
  - `system` boolean: Whether this is the domain's system certificate. Immutable after creation. When true, only key is required; the certificate is built from the domains.certificates.default.* system settings and the name, type, and configuration fields are ignored.
  - `type` string: Certificate plugin type identifier. Immutable after creation.
  - `updatedAt` string, date-time: Last-update timestamp (ISO-8601 / RFC 3339, UTC). Read-only.

## Response `200`

The created or updated certificate. When dryRun is true the certificate includes a dryRunErrors field with any validation errors.

- AutomationCertificate: A certificate managed under a domain by the Automation API. The key field is the stable, immutable identity used for idempotent create-or-update.
  - `configuration` string: Plugin-specific configuration as a JSON-encoded string. Its shape is defined by the selected certificate type. Sensitive values, as flagged by the plugin, are returned as ******** in every response; an unset sensitive value is omitted. Sending ******** back on update keeps the stored value; sending it on create is rejected. The uploaded keystore file is masked too; sending ******** back keeps it.
  - `createdAt` string, date-time: Creation timestamp (ISO-8601 / RFC 3339, UTC). Read-only.
  - `dryRunErrors` DryRunError[]: Validation errors returned when dryRun is true. Absent when validation succeeds.
    - `message` string
    - `severity` 'error' | 'warning'
  - `expiresAt` string, date-time: Expiry timestamp (ISO-8601 / RFC 3339, UTC), when known for the certificate type. Read-only.
  - `key` string, required: Stable, immutable identifier for the certificate within its domain. Lowercase alphanumeric and hyphens, starting and ending with an alphanumeric character. Used to identify the certificate on create-or-update.
  - `name` string: Human-readable name of the certificate.
  - `system` boolean: Whether this is the domain's system certificate. Immutable after creation. When true, only key is required; the certificate is built from the domains.certificates.default.* system settings and the name, type, and configuration fields are ignored.
  - `type` string: Certificate plugin type identifier. Immutable after creation.
  - `updatedAt` string, date-time: Last-update timestamp (ISO-8601 / RFC 3339, UTC). Read-only.

## Other responses

- `400`: Invalid request: a key conflict, a missing required field for a non-system certificate, an attempt to change the immutable system flag, or a second system certificate for the domain
- `403`: Permission denied
- `404`: Domain not found, or not managed by the Automation API

## Changes

- **2026-09-29** `821321fb3bcf`: 2 info
  - added the new optional `query` request parameter `dryRun`
  - added the optional property `dryRunErrors` to the response with the `200` status

[Operation history](https://skmtc.dev/gravitee-io/apis/gravitee-io-am-automation-api/changes/organizations/:orgId/environments/:envId/domains/:domainKey/certificates/put.md)

---

[API](https://skmtc.dev/gravitee-io/apis/gravitee-io-am-automation-api.md) - [All operations](https://skmtc.dev/gravitee-io/apis/gravitee-io-am-automation-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gravitee-io/apis/gravitee-io-am-automation-api/revisions/b0b6bdfd65cb?raw)
