Skip to main content
This document explains the non-obvious business logic hidden within the Partner API. Understanding these rules is critical to building a robust integration.

Booking Creation

Payment Responsibility Determines the Entire Flow

Your partner account’s paymentResponsibility setting governs what happens after you create a booking: For PARTNER responsibility partners: Your booking will always start as in progress. CleanLife does not send any payment request. You must call POST /partners/bookings/:bookingId/confirm-payment after collecting payment. For CLEANOS responsibility partners: The booking may start as waiting payment. Poll GET /partners/bookings/:bookingId/status to track payment outcome.

Contact and Address IDs

Obtain contactId and addressId from POST /partners/contacts before creating a booking. Use the same addressId with GET /partners/services to list services available at that location.

Service Catalog Is Address-Scoped

GET /partners/services requires an addressId and returns categories, each with a nested services array. Only services that:
  • Are enabled for your partner account (when restrictions are configured), and
  • Are offered in the service zone covering the address coordinates
…are included. Pick serviceId from services[].id inside the category you display to the customer. An empty data array means the address is outside service coverage or no enabled service is available there — not an error.

Partner-Specific Pricing

Each service returned by GET /partners/services includes a price field. For your partner account, CleanLife may configure a custom price per service. Key rules:
  • You do not send a price in the booking request. The platform applies the configured partner price automatically based on the serviceId you choose.
  • When price is 0 in the catalog, the service uses deferred payment — the booking is created and confirmed immediately (success) with no upfront payment required.
  • Always display the price from GET /partners/services to your customers — it is the authoritative amount for your integration.
  • The price is locked when the booking is created and does not change afterward.

External Reference Is Your Safety Net

The externalReference field is the most important tool for preventing duplicate bookings:
  • It is unique per partner account.
  • If you attempt to create a booking with a duplicate externalReference, the API returns 409 DUPLICATE_EXTERNAL_REFERENCE.
  • You should generate a unique externalReference from your own order system before calling the API.
  • In the event of a timeout or network error on your side, you can retry the creation request with the same externalReference — if the first attempt succeeded, you will receive the conflict error; if it failed, the unique constraint was never recorded and you can safely retry.
If a booking creation fails with 422 BOOKING_CREATION_FAILED, the externalReference was not saved. You can reuse it in a retry.

Failed Reference Save

In the rare scenario where a booking is created but the partner reference cannot be saved:
  1. The system automatically marks the booking as FAILED.
  2. The externalReference is not saved.
  3. You can safely retry the create request with the same externalReference.
If the issue persists, contact support with the requestId from the error response.

Booking Cancellation

Before cancelling via the Partner API, call GET /partners/bookings/cancellation-reasons and pass the selected reasonId in PATCH /partners/bookings/:bookingId/cancel.

Refund Behavior on Cancellation


Payment Confirmation

Only PARTNER Responsibility Can Confirm

The confirm-payment endpoint is exclusively available to partners with paymentResponsibility = PARTNER. Attempting to call it with CLEANOS responsibility returns 422 PAYMENT_RESPONSIBILITY_MISMATCH.

One-Time Confirmation

Once payment is confirmed, it cannot be undone. Attempting to confirm again returns 422 PAYMENT_ALREADY_CONFIRMED. This is by design — treat it as a safe idempotency check.

Confirmation After Cancellation Is Blocked

You cannot confirm payment for a canceled or failed booking. Cancel the booking only after resolving any payment disputes with your customer.

Timeslot Interpretation

All timeslot times are treated as Asia/Riyadh local time (UTC+3). Send times in HH:MM or HH:MM:SS format together with the service date. If your systems operate in a different timezone, always convert to Riyadh local time before building booking requests.

Domain Validation

Domain validation is a two-layer system:
  1. Allowed domain whitelist — configured by the CleanLife team per partner.
  2. Request domain check — if your partner account has configured domains and a request includes an Origin or Referer header, it is validated against the whitelist. Server-to-server requests (no Origin/Referer) bypass this check.

Immutable Fields

Once set, the following fields cannot be changed: