---
title: "Upload a TLS certificate"
method: POST
path: "/v2/domains/{domain}/certificates"
tags: ["domains"]
---

# Upload a TLS certificate

`POST /v2/domains/{domain}/certificates`

Upload a PEM-encoded certificate and private key. The server validates that the certificate covers the domain and that the key algorithm is RSA-2048 or EC P-256. Accepts the domain id or name.

## Path parameters

- `domain` string, required

## Request body

- object
  - `certificate` string, required — PEM-encoded certificate (full chain)
  - `private_key` string, required — PEM-encoded private key matching the certificate

## Response `200`

OK

- Domain
  - `id` string, required — Unique domain identifier (UUID)
  - `organization_id` string, required — Organization that owns the domain
  - `domain` string, required — The bare hostname (e.g. `shop.acme.com`). Wildcard coverage is reported via `kind`, never as a `*.` literal in this field.
  - `kind` 'base_only' | 'wildcard_only' | 'base_and_wildcard', required — Whether the domain covers the apex, a wildcard, or both
  - `verification_token` string, required — Token to publish under `_acme-challenge.<domain>` for ownership verification
  - `is_validated` boolean, required — True once DNS-based ownership has been confirmed
  - `dns_records` array[], required — Alternative sets of DNS records to publish for verification and routing. Each inner array is one complete, self-sufficient option — publish every record from a single option (e.g. the `CNAME` option *or* the `A`/`AAAA` option), not a mix across options. The `_acme-challenge` verification record is required regardless of the option chosen, so it is included in every option.
    - DnsRecord[]
      - `name` string, required — DNS record name (e.g. `@` for apex, or a subdomain label)
      - `base` string, required — Apex zone the record belongs to
      - `type` string, required — DNS record type (e.g. `CNAME`, `A`)
      - `value` string, required — Target value (hostname, IP, etc.)
  - `provisioning_status` ProvisioningStatus, required
    - `code` 'success' | 'failed' | 'pending' | 'manual', required — Aggregate state of the most recent TLS provisioning attempt.
    - `message` string — Non-internal error detail when `code` is `failed`
  - `certificates` DomainCertificate[], required — Currently stored certificates for this domain
    - `id` string, required — Certificate identifier
    - `kind` 'automatic' | 'manual', required — `automatic` for ACME-provisioned certificates, `manual` for user-uploaded ones
    - `subject_alt_names` string[], required — All hostnames covered by this certificate
    - `private_key_algorithm` 'ec-p256' | 'ec-p384' | 'ec-p521' | 'rsa-2048' | 'rsa-3072' | 'rsa-4096', required — Private key algorithm
    - `not_valid_before` string, required — ISO 8601 start of validity window
    - `not_valid_after` string, required — ISO 8601 end of validity window
    - `created_at` string, required — ISO 8601 timestamp of when the certificate was stored
  - `created_at` string, required — ISO 8601 timestamp of creation
  - `updated_at` string, required — ISO 8601 timestamp of last modification

---

[API](https://skmtc.net/deno/apis/deploy.md) · [All operations](https://skmtc.net/deno/apis/deploy/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/deno/deploy/revisions/5a56038d108e/schema)
