Developers

Schedulr API

Check availability and create bookings from your own website or app.

Version v1 REST · JSON

Introduction

The Schedulr API powers the booking widget and is open for you to build your own booking flow. It is organised around REST, accepts and returns JSON, and uses standard HTTP status codes.

Every request is scoped to one business through its slug, the last part of its widget URL: /widget/my-salon.

💡 Note

Endpoints are rate-limited per IP and business. See Rate limits. Need help? Email support@schedulr.com.
Base URL
https://schedulr.haomaytech.com

Authentication

These endpoints are public. No API key is needed, so they are safe to call from a browser. The only requirement is that the business has an active Schedulr subscription; otherwise bookings return 403.

Rate limits

Limits apply per IP address and business. Going over returns 429 Too Many Requests.

GET /api/availability/{slug}60 / minute
POST /api/book/{slug}20 / minute

Get availability

API Endpoint
https://schedulr.haomaytech.com/api/availability/{slug}
Request Type
GET
Content Type
JSON

Returns the open time slots for a service on a date, along with the service details and any deposit requirement.

Headers

Accept string
Set to application/json

Query parameters

date string required
Date to check, as YYYY-MM-DD. Today or later.
service_id integer required
ID of a service that belongs to the business.

Response

slots string[]
Available start times, HH:MM. Pass one as time when booking.
service object
The service: id, name, duration (minutes), price, pricing_type, rate_per_hour.
deposit object | null
null when no deposit is required, otherwise required, amount and type.
curl -G "https://schedulr.haomaytech.com/api/availability/my-salon" \
  -H "Accept: application/json" \
  -d date=2026-11-05 \
  -d service_id=3
const res = await fetch(
  "https://schedulr.haomaytech.com/api/availability/my-salon?date=2026-11-05&service_id=3",
  { headers: { Accept: "application/json" } }
);
const data = await res.json();
$res = Http::acceptJson()->get(
    'https://schedulr.haomaytech.com/api/availability/my-salon',
    ['date' => '2026-11-05', 'service_id' => 3]
);
$data = $res->json();
import requests

res = requests.get(
    "https://schedulr.haomaytech.com/api/availability/my-salon",
    params={"date": "2026-11-05", "service_id": 3},
    headers={"Accept": "application/json"},
)
data = res.json()
200 OK
{
  "slots": ["09:00", "09:30", "10:00"],
  "service": {
    "id": 3,
    "name": "Haircut",
    "duration": 30,
    "price": "50.00",
    "pricing_type": "fixed",
    "rate_per_hour": null
  },
  "deposit": {
    "required": true,
    "amount": 10,
    "type": "percentage"
  }
}

Create a booking

API Endpoint
https://schedulr.haomaytech.com/api/book/{slug}
Request Type
POST
Content Type
JSON

Books an appointment and sends the client an SMS confirmation. Overlapping bookings are rejected based on the service duration.

Headers

Content-Type string
Set to application/json
Accept string
Set to application/json

Body parameters

service_id integer required
The service being booked.
date string required
Appointment date, YYYY-MM-DD. Today or later.
time string required
A slot returned by the availability endpoint.
name string required
Client full name. Max 255 characters.
phone string required
Client phone number, used for SMS. Max 20 characters.
email string optional
Client email address.

Deposits

If the business requires a deposit, the booking is created as pending and the response contains requires_deposit: true, the deposit_amount and a Paystack payment_url. Redirect the client there to pay.

curl -X POST "https://schedulr.haomaytech.com/api/book/my-salon" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "service_id": 3,
    "date": "2026-11-05",
    "time": "09:30",
    "name": "Ama Mensah",
    "phone": "0241234567",
    "email": "ama@example.com"
  }'
const res = await fetch("https://schedulr.haomaytech.com/api/book/my-salon", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json",
  },
  body: JSON.stringify({
    service_id: 3,
    date: "2026-11-05",
    time: "09:30",
    name: "Ama Mensah",
    phone: "0241234567",
    email: "ama@example.com",
  }),
});
const data = await res.json();
$res = Http::acceptJson()->post('https://schedulr.haomaytech.com/api/book/my-salon', [
    'service_id' => 3,
    'date' => '2026-11-05',
    'time' => '09:30',
    'name' => 'Ama Mensah',
    'phone' => '0241234567',
    'email' => 'ama@example.com',
]);
$data = $res->json();
import requests

res = requests.post(
    "https://schedulr.haomaytech.com/api/book/my-salon",
    headers={"Accept": "application/json"},
    json={
        "service_id": 3,
        "date": "2026-11-05",
        "time": "09:30",
        "name": "Ama Mensah",
        "phone": "0241234567",
        "email": "ama@example.com",
    },
)
data = res.json()
201 Created
{
  "message": "Appointment booked successfully!",
  "requires_deposit": false,
  "appointment": {
    "id": 42,
    "date": "2026-11-05",
    "time": "09:30",
    "service": "Haircut"
  }
}
201 Created · deposit required
{
  "message": "Deposit payment required.",
  "requires_deposit": true,
  "deposit_amount": 10,
  "payment_url": "https://checkout.paystack.com/...",
  "appointment": { "id": 42, "date": "2026-11-05", "time": "09:30", "service": "Haircut" }
}

Errors

Schedulr uses conventional HTTP status codes. Codes in the 4xx range indicate a problem with the request.

403

The business's subscription is inactive; bookings are unavailable.

404

Unknown business slug.

409

The slot overlaps another booking. The message may suggest the next free time.

422

Validation failed, or the service does not belong to the business.

429

Rate limit exceeded. Retry after a minute.

409 Conflict
{
  "error": "This time slot is unavailable as it overlaps with another booking. The next available time for this service is 10:00."
}

Validation errors (422) use Laravel's standard message + errors object, keyed by field.

Embeddable widget

Don't need a custom UI? Embed the ready-made booking widget on any page. It uses your branding, services and business hours.

HTML
<iframe src="https://schedulr.haomaytech.com/widget/my-salon" width="100%" height="600" frameborder="0"></iframe>

Building something with Schedulr?

Tell us what you need.

support@schedulr.com