Skip to content

TLS

Certificates for the service and each alias, issued via ACME or uploaded, plus the redirect from HTTP to HTTPS and HSTS. See API access.

Endpoints

Method Path Key Purpose
GET /services/{fqdn}/aliases/{alias_fqdn}/ssl read Certificate of an alias
POST /services/{fqdn}/aliases/{alias_fqdn}/ssl write Upload a certificate for an alias (ECDSA)
POST /services/{fqdn}/aliases/{alias_fqdn}/ssl/issue write Issue an alias certificate via ACME
POST /services/{fqdn}/aliases/{alias_fqdn}/ssl/renew write Renew an alias certificate
GET /services/{fqdn}/ssl read Certificate of a vService
POST /services/{fqdn}/ssl write Upload a certificate (ECDSA)
POST /services/{fqdn}/ssl/issue write Issue a certificate via ACME
POST /services/{fqdn}/ssl/renew write Renew the ACME certificate

GET /services/{fqdn}/aliases/{alias_fqdn}/ssl

Returns: 200, CertificateStatus

Answer 200
{
  "fqdn": "www.a.example.com",
  "mode": "acme",
  "has_custom_cert": false,
  "cert_status": "none",
  "cert_issued": null,
  "cert_expires": null,
  "cert_last_renewal": null,
  "days_remaining": null,
  "detail": null
}

POST /services/{fqdn}/aliases/{alias_fqdn}/ssl

Body: CertificateUpload
Returns: 200, CertificateStored

Request
{
  "fullchain_pem": "-----BEGIN CERTIFICATE-----\nMIIBszCCAVmgAwIBAgIU...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIBuDCCAV6gAwIBAgIU...\n-----END CERTIFICATE-----\n",
  "privkey_pem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEG...\n-----END PRIVATE KEY-----\n"
}
Answer 200
{
  "fqdn": "www.a.example.com",
  "mode": "custom",
  "cert": {
    "subject": "CN=a.example.com",
    "issuer": "CN=Example CA",
    "not_before": "2026-10-01T00:00:00+00:00",
    "not_after": "2026-12-30T00:00:00+00:00",
    "dns_names": [
      "a.example.com",
      "www.a.example.com"
    ],
    "serial_number": "4f2a",
    "chain_length": 2,
    "key_type": "EC",
    "key_bits": 256,
    "curve": "secp256r1"
  }
}

POST /services/{fqdn}/aliases/{alias_fqdn}/ssl/issue

Returns: 202, AcmeStarted

Answer 202
{
  "status": "started",
  "fqdn": "www.a.example.com"
}

POST /services/{fqdn}/aliases/{alias_fqdn}/ssl/renew

Returns: 202, AcmeStarted

Answer 202
{
  "status": "started",
  "fqdn": "www.a.example.com"
}

GET /services/{fqdn}/ssl

Returns: 200, CertificateStatus

Answer 200
{
  "fqdn": "a.example.com",
  "mode": "acme",
  "has_custom_cert": false,
  "cert_status": "none",
  "cert_issued": null,
  "cert_expires": null,
  "cert_last_renewal": null,
  "days_remaining": null,
  "detail": null
}

POST /services/{fqdn}/ssl

Body: CertificateUpload
Returns: 200, CertificateStored

Request
{
  "fullchain_pem": "-----BEGIN CERTIFICATE-----\nMIIBszCCAVmgAwIBAgIU...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIBuDCCAV6gAwIBAgIU...\n-----END CERTIFICATE-----\n",
  "privkey_pem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEG...\n-----END PRIVATE KEY-----\n"
}
Answer 200
{
  "fqdn": "a.example.com",
  "mode": "custom",
  "cert": {
    "subject": "CN=a.example.com",
    "issuer": "CN=Example CA",
    "not_before": "2026-10-01T00:00:00+00:00",
    "not_after": "2026-12-30T00:00:00+00:00",
    "dns_names": [
      "a.example.com",
      "www.a.example.com"
    ],
    "serial_number": "4f2a",
    "chain_length": 2,
    "key_type": "EC",
    "key_bits": 256,
    "curve": "secp256r1"
  }
}

POST /services/{fqdn}/ssl/issue

Returns: 202, AcmeStarted

Answer 202
{
  "status": "started",
  "fqdn": "a.example.com"
}

POST /services/{fqdn}/ssl/renew

Returns: 202, AcmeStarted

Answer 202
{
  "status": "started",
  "fqdn": "a.example.com"
}

Fields

Part of the service: send them with PATCH /services/{fqdn}. ssl exists on the service and on each alias; hsts sits in response_headers.

Ssl

Field Type Notes
mode string one of acme, custom; default "acme"; acme: ZERO-PROTECT issues and renews the certificate, validating through the edge, so DNS must point here first. custom: you upload it and renew it yourself
acme_provider string one of letsencrypt, buypass, zerossl, google; default "zerossl"; Certificate authority for acme: letsencrypt, buypass, zerossl or google (Google Trust Services)
acme_email string may be null; Contact address for the certificate authority. Empty: the account's acme_email, then your tenant's contact address
https_redirect boolean default false; Redirect HTTP to HTTPS with 301 for this hostname: the vService's own name, or the alias under aliases[]. ACME validation stays on HTTP. Needs a certificate for that name
cert_status string one of issued, expiring, expired, error, pending, none; read-only; Derived from the certificate the edges serve; expiring = renewal not done yet, the certificate is still valid. Set by the server
cert_issued string may be null; read-only; Set by the server
cert_expires string may be null; read-only; Set by the server
cert_last_renewal string may be null; read-only; Set by the server
days_remaining integer may be null; read-only; Set by the server

Hsts

Field Type Notes
enabled boolean default false; Set Strict-Transport-Security on the responses the edge passes on, replacing your origin's
max_age integer 0–63072000; default 31536000; Seconds browsers remember to use HTTPS only, 0 to 63072000
include_subdomains boolean default false; Add includeSubDomains: browsers use HTTPS for every subdomain as well
preload boolean default false; Add preload, the condition for the browsers' preload lists

CertificateStatus

Field Type Notes
fqdn (required) string The vService or alias
mode (required) string one of acme, custom; acme: issued and renewed by ZERO-PROTECT. custom: uploaded by you
has_custom_cert boolean A certificate is stored and served
cert_status (required) string one of issued, expiring, expired, error, pending, none; Derived from the certificate the edges serve; expiring = renewal not done yet, the certificate is still valid
cert_issued string may be null; When ZERO-PROTECT last obtained the certificate via ACME; null without ACME issuance
cert_expires string may be null; Expiry of the certificate last obtained via ACME; cert.not_after is read from the stored certificate itself
cert_last_renewal string may be null; When ZERO-PROTECT last renewed the certificate via ACME; null without ACME issuance
cert CertificateDetails The stored certificate; absent when none is stored or it cannot be read
days_remaining integer may be null; Days until the certificate expires, rounded up; 0 or less once expired; null when unknown
detail string may be null; What the state means for you

CertificateUpload

Field Type Notes
fullchain_pem (required) string Leaf certificate first, then the intermediates, PEM
privkey_pem (required) string Unencrypted private key, PEM

Example

Issue a certificate, check it, then redirect to HTTPS and send HSTS:

curl -s -X PATCH -H "Authorization: Bearer $ZP_KEY" -H 'Content-Type: application/json' \
  $API/services/www.example.com -d '{"ssl": {"mode": "acme", "acme_provider": "letsencrypt"}}'
curl -s -X POST -H "Authorization: Bearer $ZP_KEY" $API/services/www.example.com/ssl/issue
curl -s -H "Authorization: Bearer $ZP_KEY" $API/services/www.example.com/ssl
curl -s -X PATCH -H "Authorization: Bearer $ZP_KEY" -H 'Content-Type: application/json' \
  $API/services/www.example.com -d '{"ssl": {"https_redirect": true},
    "response_headers": {"hsts": {"enabled": true, "max_age": 31536000}}}'

Behaviour

  • ACME validates with HTTP-01 through the edge, so DNS must point at the service first. Issuance takes minutes after the DNS check passes.
  • ACME certificates renew daily once less than 30 days remain.
  • Own certificate (mode: custom): upload certificate and key; you handle renewal.
  • Uploads accept ECDSA only: an edge core completes about 2850 handshakes per second with ECDSA P-256 against 535 with RSA-4096, capacity you need during a flood. If your CA issued RSA, request ECDSA P-256 or use ACME.
  • cert_status and days_remaining come from the certificate the edges serve; detail says what a state means for you. A failed issuance shows as error; support sees the reason.
  • Each alias has its own certificate settings, under /services/{fqdn}/aliases/{alias_fqdn}/ssl.
  • https_redirect sends port 80 to 443 with a 301, for the vService and all its aliases; an alias has no setting of its own.
  • TCP services can use the certificate for TLS at the edge, see Ports.