Introduction
Welcome to the SSLforSaaS API documentation. These are the current project-scoped APIs for integrating custom-domain SSL automation with your SaaS platform.
Project API requests use a project API key in the Authorization header. Generate or rotate the key from the project API settings in the dashboard.
Authorization: ApiKey {PROJECT_API_KEY} Content-Type: application/json
project:read, domains:read, domains:write, and metrics:read. Never expose a project API key in browser code.Queue a customer domain for SSL provisioning:
curl -X POST \ -H "Authorization: ApiKey {PROJECT_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"domain_name":"customer.example.com"}' \ 'https://api.sslforsaas.io/workspaces/{workspaceId}/projects/{projectId}/domains'
A successful create returns 202 Accepted with a domain_id, operation_id, CNAME target, and provisioning state.
Basics
SSLforSaaS APIs are HTTP-based REST APIs. All request and response payloads are JSON.
- All requests must be issued over HTTPS.
- Project API requests use Authorization: ApiKey {PROJECT_API_KEY}.
- All project API routes include
{workspaceId}and{projectId}. - Domain creation and enable transitions are asynchronous and can return
202 Accepted. - Request and response bodies are application/json.
| Component | Description |
|---|---|
| Base URL | https://api.sslforsaas.io |
| Project path | /workspaces/{workspaceId}/projects/{projectId} |
| Authentication | Authorization: ApiKey {PROJECT_API_KEY} |
| Content-Type header | application/json |
| Supported scopes | project:read, project:write, domains:read, domains:write, metrics:read, metrics:write |
| Status code | Description |
|---|---|
200 | Request completed successfully. |
202 | Domain provisioning or enable work was accepted and queued. |
400 | Invalid request body, identifier, or query parameter. |
402 | Subscription inactive; activate billing before managing domains. |
403 | Missing token, invalid key, inactive key, or insufficient scope. |
404 | Workspace, project, domain, or provider mapping was not found. |
409 | Conflict, duplicate domain, invalid Cloudflare mapping, or disabled-before-delete requirement. |
500 | Server or provider configuration error. |
No plan-specific request throttling contract is currently published. If infrastructure returns 429 Too Many Requests, retry with backoff and preserve idempotency on your side.
Errors
The API uses JSON error bodies. The exact message can vary by endpoint, but the status code and errorCode fields identify the failure class when present.
Validation errors occur when a request body, identifier, or query parameter is missing or invalid.
{
"message": "Invalid request body"
}
Authorization errors occur when the project API key is missing, invalid, revoked, inactive, or lacks the required scope.
{
"message": "Forbidden"
}
| Status code | Description |
|---|---|
402 | Subscription inactive. Activate billing to manage domains. |
409 | Domain already exists, domain must be disabled before delete, or provider mapping is invalid. |
500 | Provider credentials or backend service failed. Keep the returned traceId for support. |
Create a Domain
Create a custom domain under a project and queue it for SSL provisioning.
Requires the domains:write scope.
curl -X POST \ -H "Authorization: ApiKey {PROJECT_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"domain_name":"customer.example.com"}' \ 'https://api.sslforsaas.io/workspaces/{workspaceId}/projects/{projectId}/domains'
domain_id, and queues provider-backed provisioning asynchronously.| Parameter | Type | Required | Description |
|---|---|---|---|
domain_name | string | Required | The customer's custom domain, for example customer.example.com. |
source | string | Optional | Source label for audit/debug context. Defaults to Dashboard. |
{
"message": "Domain creation accepted and queued for asynchronous provisioning.",
"domain_id": "65f000000000000000000001",
"operation_id": "8b39f8a3-6f1b-4e85-8d4e-a8711a9e52d1",
"cname_target": "customer-origin.example.com",
"provisioning": {
"state": "queued",
"hostname_status": "pending",
"certificate_status": "pending"
}
}
Disable or Delete a Domain
Disable a domain before deleting it. Disable removes provider routing/certificate state where applicable; delete removes the project-domain record after it is disabled.
Requires the domains:write scope.
curl -X PUT \ -H "Authorization: ApiKey {PROJECT_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"status":false}' \ 'https://api.sslforsaas.io/workspaces/{workspaceId}/projects/{projectId}/domains/{domainId}'
409 domain_delete_requires_disabled unless the domain is already disabled.Certificate Lifecycle
Cloudflare manages certificate issuance and renewal for domains added through the project-scoped API. SSLforSaaS exposes lifecycle state; it does not expose certificate upload or CA selection.
A project API key can work with domain lifecycle endpoints according to its declared scopes:
- Add a customer domain to a project.
- Read persisted DNS, hostname, and certificate status.
- Request read-only provider status refresh for an already linked hostname.
- Disable a domain before deleting it.
Webhooks
Project webhooks notify your server when SSLforSaaS emits workspace and user events that are subscribable for outbound delivery.
Configure webhooks from the project settings page. Owners and admins can set a webhook URL, enable/disable delivery, set a signing secret, and choose event types.
- Webhook settings are project-scoped.
- System events are visible in the notification catalog but are not project-webhook subscribable by default.
- Webhook secrets are used to sign each delivery attempt.
Outbound webhook deliveries send JSON with the same top-level shape used by notification events:
{
"event_type": "workspace.domain_disabled",
"scope": "workspace_event",
"severity": "high",
"title": "Domain disabled",
"message": "Domain customer.example.com has been disabled.",
"source": "domains.update",
"workspace_id": "{workspaceId}",
"project_id": "{projectId}",
"payload": {
"domain_id": "{domainId}",
"domain_name": "customer.example.com"
},
"occurred_at": "2026-06-22T10:00:00Z"
}
| Header | Description |
|---|---|
X-SSLforSaaS-Event | The event type, for example workspace.domain_disabled. |
X-SSLforSaaS-Timestamp | Unix timestamp used in the signature payload. |
X-SSLforSaaS-Signature | sha256=... HMAC of {timestamp}.{rawBody} using your webhook secret. |
X-SSLforSaaS-Webhook-Key | Optional header key configured for the project. |
| Event | Description |
|---|---|
workspace.domain_disabled | A domain was disabled. |
workspace.domain_enabled | A domain was enabled. |
workspace.domain_ssl_error | A domain SSL/provider issue needs attention. |
workspace.domain_limit_alert | A project is near or over its domain limit. |
workspace.project_provisioning_failed | Project provisioning failed. |
user.team_invite | A team invitation event was emitted. |
user.welcome | A one-time welcome event was emitted. |
Verify signatures
Recompute the HMAC with your webhook secret over {timestamp}.{rawBody} and compare it to X-SSLforSaaS-Signature.
Respond quickly
Return 2xx quickly and process long-running work asynchronously. SSLforSaaS retries transient delivery failures according to the worker retry policy.
Be idempotent
Webhook deliveries can be retried. Record processed event IDs or payload identifiers and skip duplicates gracefully.
Application Endpoint and Origin Routing
Each project has one application endpoint that receives forwarded traffic for the project's customer domains. Configure this in project settings before adding domains.
When a domain is added to a project, SSLforSaaS uses the project's Cloudflare and routing mapping to direct traffic to the configured application endpoint. The domain create API does not currently accept a per-domain target parameter.
- Project application endpoint is the source of truth for origin routing.
- Domain create returns the authoritative CNAME/target information for customer DNS setup.
- Endpoint changes are managed from project settings and reconciled through provider-backed workflow.
Requires the project:read scope.
List Domain Names
Retrieve a paginated list of custom domains in a project. Results can be sorted and filtered by domain-name prefix.
Requires the domains:read scope.
curl -X GET \ -H "Authorization: ApiKey {PROJECT_API_KEY}" \ 'https://api.sslforsaas.io/workspaces/{workspaceId}/projects/{projectId}/domains?page=1&limit=20'
Sample Response
{
"total": 2,
"page": 1,
"pages": 1,
"domains": [
{
"_id": "65f000000000000000000001",
"domain_name": "customer.example.com",
"status": true,
"ssl_status": "active",
"provisioning": {
"state": "active"
}
}
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | Optional | Page number. Defaults to 1. |
limit | integer | Optional | Page size from 1 to 100. Defaults to 20. |
q | string | Optional | Prefix filter for domain_name. |
sortBy | string | Optional | created_at, updated_at, or domain_name. |
sortDir | string | Optional | asc or desc. Defaults to desc. |