πͺAPI
Version: 2 Last Updated: September 2025
This document describes the public API endpoints available for merchants to integrate with the platform. All endpoints follow RESTful conventions and use JSON for data exchange.
π Quick Start
For authentication and API key management, please refer to the Quick Start Guide.
Base URL: https://platform.rekaz.io/api/public
π Authentication
All API endpoints require:
Authorization: Passed in
Authorization
headerTenant ID: Passed in
__tenant
header
Example Headers
Authorization: Basic YOUR-ENCODED-AUTHORIZATION-KEY
__tenant: YOUR_TENANT_ID
Content-Type: application/json
π Attendances API
Manage customer check-ins and attendance tracking for reservations and subscriptions.
GET
/api/public/attendances
GET
/api/public/attendancesRetrieves a paginated list of recent customer attendances with optional filtering.
Query Parameters
customerId
Guid
No
null
Filter by specific customer ID
mobileNumber
string
No
null
Filter by customer mobile number
customerNumber
long
No
null
Filter by customer number
skipCount
int
No
0
Number of records to skip
maxResultCount
int
No
100
Maximum records to return (max: 100)
Example Requests
# Search by customer ID
GET /api/public/attendances?customerId=3fa85f64-5717-4562-b3fc-2c963f66afa6
# Search by mobile number
GET /api/public/attendances?mobileNumber=+966501234567
# Search by customer number
GET /api/public/attendances?customerNumber=12345
# Combined with pagination
GET /api/public/attendances?mobileNumber=+966501234567&skipCount=0&maxResultCount=20
Response
{
"items": [
{
"type": "CheckIn",
"actionType": "Subscription",
"customerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"customerName": "John Doe",
"customerMobileNumber": "+966501234567",
"providers": ["Provider A", "Provider B"],
"customerImageUrl": "https://example.com/image.jpg",
"actionName": "Premium Membership",
"actionId": "7fa85f64-5717-4562-b3fc-2c963f66afa6",
"actionDateFrom": "2025-01-15T09:00:00Z",
"actionDateTo": "2025-01-15T10:00:00Z",
"isActive": true,
"canDoCheckIn": true,
"isFirstCheckIn": false,
"customFields": [
{
"label": "Membership Level",
"value": "Gold"
}
],
"isPackage": false
}
],
"totalCount": 150
}
POST
/api/public/attendances
POST
/api/public/attendancesRecords a new attendance entry for a customer action.
Request Body
{
"type": 1, // 0 = Reservation, 1 = Subscription
"actionType": 0, // 0 = Check-In, 1 = Check-Out
"customerId": "3a1c29af-6c55-0661-5e51-8403ff2b9288",
"actionId": "3a1c29af-928e-e595-ac07-9dce32224136" // ReservationId or SubscriptionId
}
Response
Returns the created attendance record with all populated fields (same structure as GET response item).
π’ Branches API
Manage and retrieve branch information for your merchant account.
GET
/api/public/branches
GET
/api/public/branchesRetrieves all branches associated with your merchant account.
Example Request
GET /api/public/branches
Response
[
{
"id": "3a1bfd57-1b9d-0f99-c9d2-446b6aec5dc4",
"name": "Main Branch",
"addressUrl": null
},
{
"id": "4b2cf47g-5e86-4251-641g-2d67ge9a8886",
"name": "Secondary Branch",
"addressUrl": "https://maps.example.com/branch2"
}
]
GET
/api/public/branches/{id}
GET
/api/public/branches/{id}Retrieves a specific branch by its ID.
Example Request
GET /api/public/branches/3a1bfd57-1b9d-0f99-c9d2-446b6aec5dc4
Response
{
"id": "3a1bfd57-1b9d-0f99-c9d2-446b6aec5dc4",
"name": "Main Branch",
"addressUrl": null
}
π¦ Products API
Get all available services (referred to as products in the API).
GET
/api/public/products
GET
/api/public/productsRetrieves all products available for public consumption.
Example Request
GET /api/public/products
Response
[
{
"id": "bf344bc3-5b1b-4760-b23d-cf3135d437ca",
"name": "Car Wash Service",
"description": "<p>External and internal car wash service...</p>",
"shortDescription": "",
"amount": 30,
"duration": null,
"slots": null,
"productProviders": [
{
"id": "72bbb3ed-3160-485b-a48f-a90e909602e2",
"image": null,
"name": "Default Service Provider",
"description": ""
}
],
"pricing": [
{
"id": "3a1bf3a6-8d25-4a0d-16b6-069be6c0f248",
"name": "Small Car",
"model": 0,
"billingCycle": 0,
"amount": 30,
"discountedAmount": 30,
"hasMinimum": false,
"hasDeposit": false,
"hasOccurrence": false,
"duration": null,
"sku": null
}
],
"maximumQuantityPerOrder": 1,
"customFields": [
{
"id": "3a1bf3a4-2f9f-e479-bcd9-7835d99eaf04",
"name": "location_field",
"label": "Wash Location",
"placeholder": "Choose your location",
"showInCheckout": true,
"amount": 0
}
],
"type": 0,
"typeString": "Reservation",
"branchIds": ["3a1bf36f-4d75-3140-530f-1c56fd89e775"]
}
]
π₯ Customers API
Get all your customers.
GET
/api/public/customers
GET
/api/public/customersRetrieves all customers.
Query Parameters
skipCount
int
No
0
Number of records to skip (for pagination)
maxResultCount
int
No
100
Maximum records to return (max: 100)
Example Request
GET /api/public/customers?skipCount=0&maxResultCount=20
Response
{
"items": [
{
"id": "3a1c11b5-3fc3-2016-1890-1a285e601de7",
"name": "John Doe",
"customerNumber": 123778,
"mobileNumber": "966502493366",
"email": "[email protected]",
"customerType": 1,
"address": null,
"companyName": null,
"customFields": {},
"branchIds": ["3a1bfd57-1b9d-0f99-c9d2-446b6aec5dc4"],
"isBlocked": false
}
],
"totalCount": 13
}
GET
/api/public/customers/{id}
GET
/api/public/customers/{id}Get a specific customer by ID.
Example Request
GET /api/public/customers/3a1bf3b5-b54f-34c7-db92-5ff28ff22315
Response
{
"id": "3a1c11b5-3fc3-2016-1890-1a285e601de7",
"name": "John Doe",
"customerNumber": 123778,
"mobileNumber": "966502493366",
"email": "[email protected]",
"customerType": 1,
"address": null,
"companyName": null,
"customFields": {},
"branchIds": ["3a1bfd57-1b9d-0f99-c9d2-446b6aec5dc4"],
"isBlocked": false
}
POST
/api/public/customers
POST
/api/public/customersCreates a new customer record in the system.
Request Body
{
"name": "John Smith",
"mobileNumber": "+966501233567",
"email": "[email protected]",
"address": "123 Main Street, Riyadh",
"type": 1, // 1 = Individual, 2 = Company
"branchId": "3a1bf36f-4d75-3140-530f-1c56fd89e775",
"companyName": "ABC Company Ltd",
"customFields": {
"field1": "value1",
"field2": "value2"
}
}
Response
Returns the created customer ID:
"3a1bf3d6-1c84-d69e-e2d5-eb6b4f08f6d8"
π
Subscriptions API
Manage recurring subscription services for customers.
GET
/api/public/subscriptions
GET
/api/public/subscriptionsRetrieves a paginated list of customer subscriptions with custom field support.
Query Parameters
skipCount
int
No
Number of records to skip (for pagination)
maxResultCount
int
No
Maximum records to return (max: 100)
customerId
Guid
No
Filter by specific customer ID
customerMobile
string
No
Filter by customer mobile number
startAtMin
datetime
No
Filter subscriptions starting from this date
startAtMax
datetime
No
Filter subscriptions starting until this date
statuses
array
No
Filter by statuses (e.g., "Active", "Paused")
branchId
Guid
No
Filter by branch ID
keyword
string
No
Search keyword across subscription details
Example Request
GET /api/public/subscriptions?customerId=7fa85f64-5717-4562-b3fc-2c963f66afa6&skipCount=0&maxResultCount=20
Response
{
"totalCount": 45,
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"customerId": "7fa85f64-5717-4562-b3fc-2c963f66afa6",
"startAt": "2025-01-01T00:00:00Z",
"endAt": "2025-02-01T00:00:00Z",
"status": "Active",
"items": [
{
"id": "8fa85f64-5717-4562-b3fc-2c963f66afa6",
"priceId": "9fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Monthly Gym Access",
"productName": "Gym Membership",
"quantity": 1,
"billingCycle": "Monthly"
}
],
"discount": {
"type": "Percentage",
"value": 10
},
"branchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"occurenceDays": ["Monday", "Wednesday", "Friday"],
"customFields": [
{
"name": "trainer_assigned",
"label": "Personal Trainer",
"type": "String",
"value": "Mike Johnson"
}
],
"paidAmount": 500.0,
"totalAmount": 500.0,
"remainingAmount": 0.0,
"lastInvoiceCode": "INV-2025-001",
"lastInvoiceStatus": "Paid",
"isPaused": false,
"pausedAt": null,
"resumeAt": null
}
]
}
GET
/api/public/subscriptions/{id}
GET
/api/public/subscriptions/{id}Returns detailed information about a specific subscription.
POST
/api/public/subscriptions
POST
/api/public/subscriptionsCreates a new subscription, optionally creating a new customer.
Request Body (Existing Customer)
{
"customerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"startAt": "2025-02-01T00:00:00Z",
"discount": {
"type": "Fixed",
"value": 50
},
"branchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"items": [
{
"priceId": "9fa85f64-5717-4562-b3fc-2c963f66afa6",
"quantity": 1
}
],
"occurenceDays": ["Monday", "Wednesday", "Friday"]
}
Request Body (New Customer)
{
"customerDetails": {
"name": "Jane Smith",
"mobileNumber": "+966501234567",
"email": "[email protected]",
"type": 1, // 1 = Individual, 2 = Company
"companyName": ""
},
"branchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"startAt": "2025-02-01T00:00:00Z",
"items": [
{
"priceId": "9fa85f64-5717-4562-b3fc-2c963f66afa6",
"quantity": 1
}
]
}
Response
{
"invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
POST
/api/public/subscriptions/{id}/pause
POST
/api/public/subscriptions/{id}/pauseTemporarily pauses an active subscription.
Request Body
{
"pausedAt": "2025-01-20T00:00:00Z",
"resumeAt": "2025-02-01T00:00:00Z"
}
Response
{
"subscriptionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"pausedAt": "2025-01-20T00:00:00Z",
"resumeAt": "2025-02-01T00:00:00Z"
}
POST
/api/public/subscriptions/{id}/resume
POST
/api/public/subscriptions/{id}/resumeResumes a paused subscription.
Request Body
{
"resumeAt": "2025-01-25T00:00:00Z"
}
Response
Returns the full subscription object with updated status.
π― Reservations API
Manage time-based bookings and appointments with availability checking.
GET
/api/public/reservations
GET
/api/public/reservationsRetrieves a paginated list of reservations with custom field support.
Query Parameters
skipCount
int
No
Number of records to skip (for pagination)
maxResultCount
int
No
Maximum records to return (max: 100)
dateMin
datetime
No
Filter reservations from this date
dateMax
datetime
No
Filter reservations until this date
statuses
array
No
Filter by statuses (e.g., "Confirmed")
customerId
Guid
No
Filter by specific customer ID
customerMobile
string
No
Filter by customer mobile number
upcoming
boolean
No
Filter for upcoming reservations
keyword
string
No
Search keyword across reservation details
branchId
Guid
No
Filter by branch ID
Example Request
GET /api/public/reservations?customerId=7fa85f64-5717-4562-b3fc-2c963f66afa6&upcoming=true
Response
{
"totalCount": 89,
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"date": "2025-01-20",
"toDate": "2025-01-20",
"startAt": "2025-01-20T14:00:00Z",
"endAt": "2025-01-20T15:00:00Z",
"from": "14:00",
"to": "15:00",
"slotFormatted": "2:00 PM - 3:00 PM",
"status": "Confirmed",
"customStatus": "VIP",
"customerName": "John Doe",
"customerMobile": "+966501234567",
"customerId": "7fa85f64-5717-4562-b3fc-2c963f66afa6",
"reservationNumber": 10234,
"productName": "Tennis Court",
"priceName": "Peak Hours",
"quantity": 1,
"providers": ["Court A"],
"customFields": [
{
"name": "equipment_needed",
"label": "Equipment Required",
"type": "Boolean",
"value": true
}
],
"invoiceTotalAmount": 150.0,
"reservationTotalAmount": 150.0,
"reservationRemainingAmount": 0.0,
"branchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"branchName": "Main Branch",
"meetingUrl": "https://meet.example.com/abc123",
"source": "WebBooking",
"isZeroPrice": false,
"isWalkInCustomer": false
}
]
}
Note: The remaining amount field is now named
reservationRemainingAmount
for consistency with other reservation amount fields.
GET
/api/public/reservations/slots
GET
/api/public/reservations/slotsRetrieves available time slots for reservations.
Query Parameters
StartDate
datetime
Yes
Your desired start date for slot search (format: 2025-08-10T20:00:00
)
EndDate
datetime
Yes
Your desired end date for slot search (format: 2025-08-25T21:00:00
)
PriceId
Guid
Yes
Price configuration ID from products
MinQuantity
int
Yes
Minimum quantity required (must be β₯ 1)
MinProvidersCount
int
No
Minimum number of providers required
ProvidersIds
Guid[]
No
Specific provider IDs to filter by
Example Request
GET /api/public/reservations/slots?StartDate=2025-08-10T20:00:00&EndDate=2025-08-25T21:00:00&PriceId=3a1c12e6-c66b-6ac5-90a7-8b791791af3c&MinQuantity=1&MinProvidersCount=1
How to set dates:
StartDate
: When you want to start looking for available slots (e.g., today or tomorrow)EndDate
: How far ahead you want to search (e.g., next week or month)
Common Issues:
Ensure
MinQuantity
is at least 1 (required validation)DateTime format should be
YYYY-MM-DDTHH:mm:ss
(without timezone)PriceId
must be a valid GUID from the products endpoint
Response
[
{
"from": "2025-09-09T06:00:00Z",
"to": "2025-10-12T06:00:00Z",
"availableReservationsCount": 1,
"availableProvidersCount": 0,
"availableProviderIds": [],
"isOutDated": false,
"isAvailable": false,
"amounts": {
"totalPrice": 382.95,
"effectiveQuantity": 1,
"totalAfterDiscount": 382.95,
"depositAmount": null
},
"maxConnectedTo": "2025-10-12T06:00:00Z",
"allProvidersAvailability": {
"45bb3834-9869-4d12-83af-fa347448aa60": false
}
}
]
POST
/api/public/reservations/bulk
POST
/api/public/reservations/bulkCreates multiple reservations in a single request.
Request Body (Existing Customer)
{
"customerId": "3a1c2245-564d-84ec-af57-c7b85af1441f",
"branchId": "3a1c1320-ef97-fa70-ddb6-15ad0832397f",
"items": [
{
"quantity": 1,
"priceId": "3a1c2281-1154-f9d2-f96f-210b7021eedb",
"from": "2025-09-04T17:00:00Z",
"to": "2025-09-04T18:00:00Z",
"customFields": {},
"discount": {
"type": "percentage",
"value": 0
}
}
]
}
Request Body (New Customer)
{
"customerDetails": {
"name": "Final Test",
"mobileNumber": "+966502203642",
"email": "",
"type": 1,
"companyName": ""
},
"branchId": "3a1c1320-ef97-fa70-ddb6-15ad0832397f",
"items": [
{
"quantity": 1,
"priceId": "3a1c2281-1154-f9d2-f96f-210b7021eedb",
"from": "2025-09-04T17:00:00Z",
"to": "2025-09-04T18:00:00Z",
"customFields": {},
"discount": {
"type": "percentage",
"value": 0
}
}
]
}
Response
{
"invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
β οΈ Error Handling
All endpoints follow standard HTTP status codes and return consistent error responses.
Error Response Format
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request validation failed",
"details": "The mobile number format is invalid",
"validationErrors": [
{
"field": "mobileNumber",
"message": "Must be a valid Saudi mobile number"
}
]
}
}
HTTP Status Codes
200
Success
201
Created successfully
400
Bad request - validation error
401
Unauthorized - invalid API key
403
Forbidden - missing branch ID or permissions
404
Resource not found
500
Internal server error
Common Error Codes
ValidationError
Request data validation failed
NotFound
Requested resource does not exist
Unauthorized
Invalid or missing authentication
RateLimit
Too many requests
BusinessLogicError
Business rule violation
Last updated: September 2025 | Version 2
Last updated