Skip to main content
Complete the Let’s Encrypt certificate after user adds TXT record. This validates the DNS challenge, issues the certificate, imports it to ACM, and attaches it to CloudFront. After this, the user can switch their www CNAME to CloudFront with zero downtime.

Path Parameters

ParameterTypeRequiredDescription
org_idstringYesClerk organization slug

Example Request

curl -X POST https://searchcompany-main.up.railway.app/api/domain/complete-certificate/my-company-123456 \
  -H "Authorization: Bearer $TOKEN"

Example Response

{
  "status": "success",
  "proxy_status": "SSL_VALIDATED",
  "certificate_arn": "arn:aws:acm:us-east-1:123456:certificate/abc-123",
  "message": "SSL certificate is ready. You can now switch your www CNAME to CloudFront."
}

Response Fields

FieldTypeDescription
statusstring”success” if certificate was issued
proxy_statusstringUpdated to β€œSSL_VALIDATED”
certificate_arnstringACM certificate ARN
messagestringHuman-readable status

What This Endpoint Does

  1. Triggers ACME validation: Tells Let’s Encrypt to check the TXT record
  2. Waits for validation: Polls until the challenge is validated (usually 10-30 seconds)
  3. Issues certificate: Finalizes the ACME order and downloads the certificate
  4. Imports to ACM: Uploads the certificate to AWS Certificate Manager
  5. Attaches to CloudFront: Updates the CloudFront distribution with the new certificate
  6. Updates database: Sets proxy_status to SSL_VALIDATED

Error Handling

If the TXT record is not found or incorrect, the endpoint will return an error:
{
  "detail": "DNS challenge validation failed. Make sure TXT record is correctly added."
}
In this case, the user should verify the TXT record was added correctly and try again.

What Happens Next

After this endpoint succeeds:
  1. CloudFront has a valid SSL certificate
  2. User completes Step 2: Switch www CNAME to CloudFront via Entri
  3. Frontend calls /mark-step-complete with step=2
  4. Status becomes β€œDEPLOYED” - fully operational!

Frontend Integration

// Called after Entri closes successfully for Step 1
if (entriEvent.detail.success && pendingStep === 1) {
  setIsValidating(true);
  try {
    await completeCertificate(orgSlug, token);
    // Certificate issued! Refresh UI to show Step 2
  } catch (error) {
    setErrorMessage("Certificate validation failed. Please try again.");
  } finally {
    setIsValidating(false);
  }
}