Skip to main content

Overview

Creates a new webhook subscription. After creation, CleanLife will send a POST request to your specified URL whenever the subscribed events occur on bookings associated with your partner account.
The webhook secret is only returned once — in the response to this request. Store it securely. You cannot retrieve it again (only rotate it).

Endpoint

POST /partners/webhooks/subscriptions

Authentication

Requires a valid API Key with the partner_webhooks_manage permission.

Request Body

{
  "url": "https://yourplatform.com/webhooks/cleanlife",
  "events": [
    "booking.created",
    "booking.updated",
    "booking.cancelled",
    "booking.payment_confirmed",
    "booking.appointment_status_changed"
  ]
}
FieldTypeRequiredDescription
urlstring (URL)YesYour HTTPS endpoint that will receive webhook deliveries. Must match your registered allowed domain.
eventsstring[]YesArray of event types to subscribe to. At least one event is required.

Valid Event Values

ValueDescription
booking.createdFired when a booking is successfully created
booking.updatedFired when a booking is rescheduled or updated
booking.cancelledFired when a booking is cancelled
booking.payment_failedFired when async payment processing fails (CLEANOS responsibility)
booking.payment_confirmedFired when a partner confirms payment (PARTNER responsibility)
booking.appointment_status_changedFired when the service appointment status changes

Example Request

curl -X POST "https://apiv3.thecleanlife.dev/v1/partners/webhooks/subscriptions" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourplatform.com/webhooks/cleanlife",
    "events": ["booking.created", "booking.cancelled", "booking.appointment_status_changed"]
  }'

Success Response

HTTP Status: 200 OK
{
  "success": true,
  "data": {
    "id": "gggggggg-0000-0000-0000-000000000001",
    "partnerClientId": "hhhhhhhh-0000-0000-0000-000000000001",
    "url": "https://yourplatform.com/webhooks/cleanlife",
    "events": ["booking.created", "booking.cancelled", "booking.appointment_status_changed"],
    "secret": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
    "status": "ACTIVE",
    "createdAt": "2026-06-15T10:00:00+03:00",
    "updatedAt": "2026-06-15T10:00:00+03:00"
  }
}
Critical: Save the secret field immediately. It is a 64-character hex string (32 random bytes). It will never be returned again after this response. If you lose it, you must rotate it.

Error Responses

HTTP StatusCodeDescription
400VALIDATION_ERRORInvalid URL, invalid event name, or URL does not match allowed domain
400VALIDATION_ERROR (msg: “Webhook URL must use HTTPS”)URL uses HTTP, not HTTPS
400VALIDATION_ERROR (msg: “Webhook URL host is not allowed”)URL points to a blocked/private host
400VALIDATION_ERROR (msg: “Partner has no allowed webhook domains configured”)Your partner account has no registered domains
400VALIDATION_ERROR (msg: “Webhook domain is not allowed for this partner”)URL hostname not in your allowed domains
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENMissing partner_webhooks_manage permission

Notes

  • You can create multiple subscriptions with different URLs and/or different event sets.
  • A subscription is immediately ACTIVE upon creation.
  • If you need to change the subscribed events or URL later, use PATCH /partners/webhooks/subscriptions/:id.
  • Deleting a subscription stops future deliveries. Past delivery history remains available via GET /partners/webhooks/deliveries.