Skip to content

DelegatedSSL API

A REST API for delegated domain-control validation and automated SSL. The same API powers the console — create domains, hand out delegation records, verify, issue certificates and receive webhooks.

Overview

The API is served from https://api.delegatedssl.com. All authenticated endpoints live under /v1 and speak JSON. Successful responses return the resource directly; errors return a structured envelope (see Errors). Every response carries an x-request-id header for support.

Base URLhttps://api.delegatedssl.com
Version prefix/v1
Content typeapplication/json
AuthBearer API key (dssl_…) or Auth0 access token

Authentication

Programmatic requests authenticate with an organization API key. Create one in the console under Settings → API keys; the secret (prefixed dssl_) is shown once at creation and stored only as a hash. Send it as a bearer token:

Authorization header
Authorization: Bearer dssl_your_api_key

Keys carry least-privilege scopes. Grant only what an integration needs:

domains:readdomains:writeclients:readclients:writereports:readwebhooks:write

Optional headers: x-org-id to disambiguate an organization, and Idempotency-Key to make writes safely retryable (see rate limits & idempotency).

Quickstart

Delegate a domain end to end in four calls.

bash
# 1. Create a domain (returns the delegation record)
curl https://api.delegatedssl.com/v1/domains \
  -H "Authorization: Bearer dssl_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"apex":"example.com","tags":["care-plan"]}'

# 2. Give the CNAME to the domain owner
#    Host:  _acme-challenge.example.com
#    Value: example.com.a1b9f0e.dcv.delegatedssl.com
#    Type:  CNAME   TTL: 300

# 3. Once the CNAME resolves, verify delegation
curl -X POST https://api.delegatedssl.com/v1/domains/6f9b2a1e-3c4d-4e5f-8a90-1b2c3d4e5f60/verify-delegation \
  -H "Authorization: Bearer dssl_your_api_key"

# 4. Request issuance (or let it happen automatically on verify)
curl -X POST https://api.delegatedssl.com/v1/domains/6f9b2a1e-3c4d-4e5f-8a90-1b2c3d4e5f60/certificates/issue \
  -H "Authorization: Bearer dssl_your_api_key"

The create call responds with the exact record the domain owner must publish:

201 Created
{
  "id": "6f9b2a1e-3c4d-4e5f-8a90-1b2c3d4e5f60",
  "apex": "example.com",
  "validation": {
    "status": "pending",
    "delegation": {
      "type": "CNAME",
      "host": "_acme-challenge.example.com",
      "value": "example.com.a1b9f0e.dcv.delegatedssl.com",
      "ttl": 300
    }
  },
  "cert": { "status": "pending" },
  "opsStatus": "awaiting_dns"
}

Delegated DCV

Domain-control validation normally has to be repeated on every renewal. DelegatedSSL delegates it: the domain owner publishes a single stable _acme-challenge CNAME pointing at a per-domain target on dcv.delegatedssl.com. Validation for the initial issuance and every future renewal resolves through that one record — so the owner acts once and never again. Their DNS can live anywhere; only that one record changes.

Domains

A domain represents an apex you manage for a client. It carries a validation block (status pending / verified / error plus the delegation record) and a cert block (status pending / active / error, issuer and validity). Domains can be grouped under a clientId and carry tags and notes.

Certificates

Certificates are issued and rotated through Cloudflare for SaaS as domain-validated (DV) certificates. The API exposes certificate metadata — issuer, status, validity window and trace IDs — and a metadata bundle for handoff. Private keys are never exported; key material stays at Cloudflare's edge.

Domains API

MethodEndpoint
POST /v1/domains
POST /v1/domains/bulk
POST /v1/domains/query
GET /v1/domains/:id
GET /v1/domains/:id/delegation-record
POST /v1/domains/:id/verify-delegation
POST /v1/domains/:id/recheck
POST /v1/domains/:id/certificates/issue
PATCH /v1/domains/:id
DELETE /v1/domains/:id

Certificates API

MethodEndpoint
POST /v1/domains/:id/certificates/query
GET /v1/certificates/:id
GET /v1/certificates/:id/bundle

Webhooks

Register HTTPS endpoints and manage their signing secrets over the API. On creation you receive a signing secret (whsec_…, shown once) which you rotate independently of the endpoint.

Endpoint registration and secret management are available today. Event delivery is rolling out — the event catalog and signed-payload contract below are the format deliveries will use, so you can build against them now.
MethodEndpoint
GET /v1/webhooks
POST /v1/webhooks
POST /v1/webhooks/:id/rotate-secret
DELETE /v1/webhooks/:id

Events

domain.createddomain.validation_verifieddomain.validation_errorcertificate.activecertificate.blockedverification_link.openedverification_link.completed
Example payload
{
  "event": "certificate.active",
  "createdAt": "2026-07-21T10:20:00Z",
  "data": {
    "domainId": "6f9b2a1e-3c4d-4e5f-8a90-1b2c3d4e5f60",
    "apex": "example.com",
    "certificate": { "status": "active", "issuer": "Cloudflare" }
  }
}
Verify the signature · Node.js
// Verify the HMAC-SHA256 signature on every delivery.
// The signing secret (whsec_...) is shown once when you create the endpoint.
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, signatureHeader, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader || "");
  return a.length === b.length && timingSafeEqual(a, b);
}

Errors & rate limits

Errors return a consistent envelope with a machine-readable code, a human message and the requestId.

400 Bad Request
{
  "code": "validation_error",
  "message": "A valid domain apex is required",
  "requestId": "b3d9c1e0-7a42-4f13-9c5e-2a1b0c8d4e6f"
}
StatusMeaning
400Validation error — check message.
401Missing or invalid credentials.
403Key lacks the required scope or role.
404Resource not found in your organization.
409Duplicate — the domain already exists.
429Rate limited — honor the Retry-After header.
502Upstream Cloudflare error during hostname operations.

Rate limits. Authenticated /v1 traffic is limited to 240 requests/minute; public verification endpoints to 30/minute. Limits are enforced globally by a Cloudflare Durable Object and surfaced via X-RateLimit-Remaining, X-RateLimit-Reset and Retry-After.

Idempotency. Send an Idempotency-Key on writes to make retries safe; a replayed key returns the original result with an Idempotency-Cache-Hit header.

Ready to build?

Create an API key in the console and delegate your first domain.

Get an API key