Upload Certificate

POST /v1/certificates/self

Upload a PEM-encoded certificate plus its private key for use on custom-domain endpoints. Once uploaded, attach the cert to one or more endpoints via PUT /v1/endpoints/{id}/certificate.

The private key is encrypted at rest with the platform's certificate encryption key (set via SECURITY_CERT_ENCRYPTION_KEY on the api-server). It can never be retrieved through the API — to rotate, delete and re-upload.

Both PEM blocks must parse cleanly. The cert's public key must match the supplied private key (verified server-side). Intermediate CA chains can be appended to the cert_pem as additional -----BEGIN CERTIFICATE----- blocks; the platform serves the full chain in the TLS handshake.

Requires the custom_ssl entitlement on your plan.

Request body

name string Req
Friendly label for the cert. Shown in the dashboard. Max 128 chars.
cert_pem string Req
PEM-encoded leaf certificate, optionally followed by intermediate CA certs (concatenated, in order). Headers -----BEGIN CERTIFICATE----- required.
key_pem string Req
PEM-encoded private key matching the leaf cert. Supports RSA (PKCS#1, PKCS#8) and ECDSA (SEC1, PKCS#8). Encrypted keys (DEK-Info) not supported — decrypt locally before uploading.

Response (200 OK)

An acknowledgement object. To retrieve the stored certificate object, call GET /v1/certificates/self.

ok boolean
Always true on success.
domain_id int
ID of the domain the certificate was attached to (and set as default for).
message string
Human-readable confirmation.

Errors

400 Bad Request
Missing fields, malformed PEM, cert/key mismatch, expired cert (not_after in the past), or unsupported key algorithm.
401 Unauthorized
Missing auth.
403 Forbidden
Plan doesn't include the custom_ssl entitlement.
409 Conflict
Cert with the same fingerprint already uploaded.
Request
curl -X POST "https://api.ngris.com/v1/certificates/self" \ -H "X-API-KEY: <your_api_key>" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg name "wildcard.example.com" \ --arg cert "$(cat fullchain.pem)" \ --arg key "$(cat privkey.pem)" \ '{name: $name, cert_pem: $cert, key_pem: $key}')"
Python
from ngris import Ngris client = Ngris(api_key="<your_api_key>") with open("fullchain.pem") as f: cert_pem = f.read() with open("privkey.pem") as f: key_pem = f.read() resp = client.certificates.upload({ "name": "wildcard.example.com", "cert_pem": cert_pem, "key_pem": key_pem, }) print(resp["message"])
Response — 200 OK
{ "ok": true, "domain_id": 42, "message": "Certificate uploaded and set as default for this domain." }
On this page
Upload Certificate
Iris