{"openapi":"3.1.0","info":{"title":"ByeRadon Inc. Partner API","version":"1.0.0","description":"Read real-time availability and create confirmed bookings for the services the company offers online — call GET /services for the current list.\n\nBookings created here land on the same calendar as the public booking widget: the slot is immediately blocked for every other channel, and the appointment appears in the CRM schedule. All times are local wall-clock times in America/Edmonton — there is no UTC conversion.","contact":{"name":"ByeRadon Inc.","email":"eman@byeradon.ca"}},"servers":[{"url":"https://radoncrm.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key issued by the company: `Authorization: Bearer rk_live_…`. `X-API-Key: <key>` is also accepted."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}},"Slot":{"type":"object","properties":{"start":{"type":"string","example":"10:00"},"label":{"type":"string","example":"10:00 AM"}}},"BookingRequest":{"type":"object","required":["service","customer","property","slot"],"properties":{"service":{"type":"string","example":"test_short","description":"A service key from GET /services. The company controls which services are offered, so read that endpoint rather than hard-coding this."},"customer":{"type":"object","required":["name","email","phone"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}}},"property":{"type":"object","required":["address","city"],"properties":{"address":{"type":"string"},"city":{"type":"string"},"province":{"type":"string","default":"AB"},"postal_code":{"type":"string"}}},"slot":{"type":"object","required":["date","start"],"properties":{"date":{"type":"string","format":"date"},"start":{"type":"string","example":"10:00"}}},"pickup":{"type":"object","description":"Required when the service has requires_pickup — at least 48 h after the placement slot.","properties":{"date":{"type":"string","format":"date"},"start":{"type":"string"}}},"notes":{"type":"string"},"external_ref":{"type":"string","description":"Your own id for this booking; echoed back."}}},"Booking":{"type":"object","properties":{"reference":{"type":"string","example":"J1352","description":"Use this in GET/cancel calls."},"service":{"type":"string"},"status":{"type":"string","example":"scheduled"},"external_ref":{"type":"string","nullable":true},"timezone":{"type":"string"},"appointment":{"type":"object","properties":{"date":{"type":"string"},"start":{"type":"string"},"end":{"type":"string"}}},"pickup":{"type":"object","nullable":true},"customer":{"type":"object"},"property":{"type":"object"},"quote":{"type":"object","nullable":true,"description":"Present when the service opens a draft quote."}}}}},"paths":{"/me":{"get":{"summary":"Verify a key and read its scopes and limits","responses":{"200":{"description":"Key, company and limit details"},"401":{"description":"Invalid key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}}}}},"/services":{"get":{"summary":"List bookable services with their rules","description":"The services the company currently offers for online booking — the same set as its public booking pages — with durations, bookable weekdays, per-day caps and the exact required fields for each. **Call this first and drive your booking off it**: the company turns services on and off in its own admin panel, so a hard-coded list will go stale. A service missing from here returns 400 service_not_bookable.","responses":{"200":{"description":"Service catalogue and business hours"}}}},"/availability":{"get":{"summary":"Open slots across a date range","parameters":[{"name":"service","in":"query","required":true,"schema":{"type":"string"},"description":"A service key from GET /services, e.g. \"test_short\" or \"quote\"."},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Defaults to tomorrow."},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Defaults to 14 days out. Max 62 days per call."}],"responses":{"200":{"description":"Per-day status and open start times"},"404":{"description":"Unknown service","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}}}}},"/availability/{date}":{"get":{"summary":"Open slots on one day","parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","format":"date"}},{"name":"service","in":"query","required":true,"schema":{"type":"string"},"description":"A service key from GET /services, e.g. \"test_short\" or \"quote\"."}],"responses":{"200":{"description":"Slots, or the reason the day is closed"}}}},"/bookings":{"get":{"summary":"List bookings this key created","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}}],"responses":{"200":{"description":"Bookings, newest first"}}},"post":{"summary":"Create a confirmed booking","description":"Creates a real, confirmed appointment — not a lead. The slot is validated against live availability at write time, so a 409 means someone took it between your availability read and this call: re-read and pick another.\n\nSend an `Idempotency-Key` header. A retry with the same key returns the original booking instead of creating a second one.","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string"},"description":"Strongly recommended. Safe retries."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingRequest"}}}},"responses":{"200":{"description":"Idempotent replay of an earlier identical request"},"201":{"description":"Booking confirmed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"booking":{"$ref":"#/components/schemas/Booking"}}}}}},"400":{"description":"Validation failed — `error` names the offending field","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}},"409":{"description":"Slot no longer available (code \"slot_unavailable\")","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}},"429":{"description":"Rate or daily booking limit reached","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}}}}},"/bookings/{reference}":{"get":{"summary":"Read one booking","parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string"},"description":"The job number returned at creation, e.g. J1352."}],"responses":{"200":{"description":"Current state, including live job status"},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}}}}},"/bookings/{reference}/cancel":{"post":{"summary":"Cancel a booking this key created","description":"Frees the slot immediately. Appointments already completed, invoiced or paid cannot be cancelled here.","parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled"},"409":{"description":"Too late to cancel","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable sentence, safe to show a customer."},"code":{"type":"string","description":"Machine-readable code to branch on."}}}}}}}}}}}