All routes use your deployment's application host, shown here with the reserved example https://pki.example.com.

Administrative routes require an administrator session cookie and use the console's role checks. API keys and service accounts are not yet supported. Enrollment routes use protocol credentials; public revocation routes require none.

Enrollment — SCEP (RFC 8894)

GET  /scep/{endpoint-id}?operation=GetCACaps
GET  /scep/{endpoint-id}?operation=GetCACert
GET  /scep/{endpoint-id}?operation=PKIOperation&message=…
POST /scep/{endpoint-id}

Windows appends /pkiclient.exe; do not include it in the configured URL.

Enrollment — ACME (RFC 8555)

GET  /acme/{endpoint-id}/directory
GET  /acme/{endpoint-id}/new-nonce
POST /acme/{endpoint-id}/new-account
POST /acme/{endpoint-id}/new-order
POST /acme/{endpoint-id}/orders/{order-id}
POST /acme/{endpoint-id}/orders/{order-id}/finalize
POST /acme/{endpoint-id}/authorizations/{authz-id}
POST /acme/{endpoint-id}/challenges/{challenge-id}
POST /acme/{endpoint-id}/certificates/{order-id}
POST /acme/{endpoint-id}/key-change
POST /acme/{endpoint-id}/revoke-cert

Clients discover these routes from /directory. ARI is not implemented.

Enrollment — EST (RFC 7030)

GET  /.well-known/est/{endpoint-id}/cacerts        (no credentials)
GET  /.well-known/est/{endpoint-id}/csrattrs
POST /.well-known/est/{endpoint-id}/simpleenroll
POST /.well-known/est/{endpoint-id}/simplereenroll

HTTP Basic over TLS. /serverkeygen and /fullcmc return 404.

Revocation — public, unauthenticated

GET      /pki/{organization-id}/{ca-id}/crl       application/pkix-crl
GET/POST /pki/{organization-id}/{ca-id}/ocsp      application/ocsp-response
GET      /pki/{organization-id}/{ca-id}/issuer    application/pkix-cert

Issued certificates include these URLs.

Administration — SCEP

POST /api/scep/endpoints
POST /api/scep/endpoints/{endpoint-id}/policy
POST /api/scep/endpoints/{endpoint-id}/enabled
POST /api/scep/endpoints/{endpoint-id}/delete
POST /api/scep/endpoints/{endpoint-id}/challenges
POST /api/scep/endpoints/{endpoint-id}/auth/static
POST /api/scep/endpoints/{endpoint-id}/auth/jamf
POST /api/scep/endpoints/{endpoint-id}/auth/{method}/enabled
GET  /api/scep/endpoints/{endpoint-id}/ca
POST /api/scep/intune/connect
POST /api/scep/intune/disconnect

Mint a one-time challenge with JSON:

curl -sS -X POST \
  https://pki.example.com/api/scep/endpoints/{endpoint-id}/challenges \
  -H 'Content-Type: application/json' \
  -d '{
        "expectedSubject": "CN=laptop-4193.corp.example.com",
        "expectedSANs": "laptop-4193.corp.example.com",
        "expectedEKUs": ["client_auth"],
        "externalId": "asset-4193",
        "ttlSeconds": 900
      }'

# → {"challenge":"…","expiresIn":"15m0s"}

All fields optional. ttlSeconds defaults to 900 and is capped at 24 hours. expectedEKUs may only narrow the endpoint's permitted list.

Endpoint deletion requires its name in confirm_name.

Administration — ACME

POST /api/acme/endpoints
POST /api/acme/endpoints/{endpoint-id}/policy
POST /api/acme/endpoints/{endpoint-id}/enabled
POST /api/acme/endpoints/{endpoint-id}/delete
POST /api/acme/endpoints/{endpoint-id}/credentials
POST /api/acme/endpoints/{endpoint-id}/credentials/{credential-id}/revoke
curl -sS -X POST \
  https://pki.example.com/api/acme/endpoints/{endpoint-id}/credentials \
  -H 'Content-Type: application/json' \
  -d '{"label":"ingress-prod","identifiers":["ingress.example.internal"],"single_use":false,"ttl_hours":24}'

# → {"directory":"…","kid":"…","hmac_key":"…","single_use":false}

The hmac_key is returned once.

Administration — EST

POST /api/est/endpoints
POST /api/est/endpoints/{endpoint-id}/policy
POST /api/est/endpoints/{endpoint-id}/enabled
POST /api/est/endpoints/{endpoint-id}/delete
POST /api/est/endpoints/{endpoint-id}/credentials
POST /api/est/endpoints/{endpoint-id}/credentials/{credential-id}/revoke
curl -sS -X POST \
  https://pki.example.com/api/est/endpoints/{endpoint-id}/credentials \
  -H 'Content-Type: application/json' \
  -d '{"username":"branch-gateways","label":"EMEA branches","identifiers":"gw-muc-01.example.internal","ttl_hours":720}'

# → {"url":"…","username":"branch-gateways","password":"…"}

The password is returned once.

Certificate authorities and certificates

POST /certificate-authorities
POST /certificate-authorities/{id}/status
POST /certificate-authorities/{id}/rotate
POST /certificate-authorities/{id}/delete
GET  /certificate-authorities/{id}/download
POST /certificate-authorities/import
POST /certificate-authorities/import/{id}/wrapped-key
POST /certificate-authorities/import/{id}/cancel
GET  /certificate-authorities/import/{id}/status

POST /certificates/issue          generate the keypair here
POST /certificates/csr            sign a CSR you supply
POST /certificates/{id}/revoke
GET  /certificates/{id}/download

Integrations

POST /integrations/jamf/scep-challenge/{endpoint-id}    HTTP Basic, per-device challenge

Audit

GET /audit
GET /audit.csv       same query, as a CSV attachment

Both accept the page's filter query parameters.

Status codes

Code Where Means
404 Any enrollment endpoint The endpoint does not exist or is disabled. These states are deliberately indistinguishable
403 EST The request arrived over plaintext. No WWW-Authenticate is sent, so a client cannot be tricked into resending its password in the clear
401 EST Wrong username, wrong password, or a revoked credential. Identical in all three cases, by design
400 + problem document ACME An RFC 8555 error; the reason is also recorded on the order
429 Any enrollment endpoint Rate limited, per endpoint and source address