{"openapi":"3.1.0","info":{"title":"Jalopy API","version":"1","description":"Book fleet vehicles, and read bookings, trips, prestarts, defects and the fleet itself.\n\n**Authentication.** Make an API key in the portal (Settings → Developers; owners only), tick what it may do, and send it as `Authorization: Bearer jy_…`. Keys are shown once.\n\n**Limits.** 120 requests a minute per key; `X-RateLimit-Limit`, `-Remaining` and `-Reset` say where you're at, and a 429 comes with `Retry-After`.\n\n**Lists** are oldest change first, up to 100 at a time. Pass `next_cursor` back as `cursor` for the next page, and `updated_since` to sync only what changed.\n\n**Creates** accept an `Idempotency-Key` header: a retry with the same key gets the first answer back instead of a second booking.\n\n**Errors** look like `{ \"error\": { \"status\", \"message\", \"fields\" } }`, where `fields` has a sentence per field.\n\n**Webhooks** (below) push events to you as they happen. Set them up in Settings → Developers."},"servers":[{"url":"https://app.jalopy.app/api/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"bookings","description":"Bookings: make, read and cancel. The same rules as the apps."},{"name":"trips","description":"The live part of a booking: start and end odometer, fuel, km."},{"name":"prestarts","description":"Prestart checks, as submitted. Never changed after."},{"name":"defects","description":"Problems raised from prestarts, trip ends or by hand."},{"name":"vehicles","description":"The fleet."},{"name":"trailers","description":"Bookable trailers."},{"name":"people","description":"People in the org, by user ID (the ID bookings and trips use)."},{"name":"locations","description":"Offices, houses, depots and client sites."},{"name":"services","description":"Service records (Fleet admins and owners see costs)."}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"jy_… from Settings → Developers"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"status":{"type":"integer"},"message":{"type":"string"},"fields":{"type":["object","null"],"additionalProperties":{"type":"string"}}}}}},"Person":{"type":"object","properties":{"id":{"type":"string","description":"The user ID (bookings and trips refer to it)"},"membership_id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"roles":{"type":"array","items":{"type":"string","enum":["owner","fleet_admin","approver","coordinator","driver","passenger"]}},"status":{"type":"string","enum":["invited","active","disabled"]},"employee_id":{"type":"string"},"location_scope":{"type":"array","items":{"type":"string"}},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Vehicle":{"type":"object","properties":{"id":{"type":"string"},"rego":{"type":"string"},"rego_state":{"type":"string","enum":["ACT","NSW","NT","QLD","SA","TAS","VIC","WA"]},"vin":{"type":"string"},"fleet_number":{"type":"string"},"external_id":{"type":"string"},"make":{"type":"string"},"model":{"type":"string"},"variant":{"type":"string"},"year":{"type":"number"},"body_type":{"type":"string","enum":["sedan","hatch","wagon","suv","ute","van","people_mover","bus","truck","other"]},"colour":{"type":"string"},"fuel_type":{"type":"string","enum":["petrol","diesel","hybrid","plug_in_hybrid","electric","lpg"]},"transmission":{"type":"string","enum":["automatic","manual"]},"seats":{"type":"number"},"odometer":{"type":"number"},"gvm":{"type":"number"},"towing_capacity":{"type":"number"},"special_use":{"type":"array","items":{"type":"string","enum":["wheelchair","bus","4wd","ute","other"]}},"required_licence_class":{"type":"string","enum":["C","LR","MR","HR","HC","MC"]},"required_qualifications":{"type":"array","items":{"type":"string"}},"home_location":{"type":"string","description":"ID"},"current_location":{"type":"string","description":"ID"},"key_location":{"type":"string"},"status":{"type":"string","enum":["available","in_use","out_of_service","retired"]},"prestart_template":{"type":"string","description":"ID"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Trailer":{"type":"object","properties":{"id":{"type":"string"},"rego":{"type":"string"},"rego_state":{"type":"string","enum":["ACT","NSW","NT","QLD","SA","TAS","VIC","WA"]},"vin":{"type":"string"},"type":{"type":"string","enum":["box","cage","plant","car","other"]},"size":{"type":"string"},"atm":{"type":"number"},"gvm":{"type":"number"},"braked":{"type":"boolean"},"coupling":{"type":"string","enum":["ball_50mm","pintle","treg","other"]},"home_location":{"type":"string","description":"ID"},"status":{"type":"string","enum":["available","in_use","out_of_service","retired"]},"prestart_template":{"type":"string","description":"ID"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Location":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","description":"ID"},"address":{"type":"string"},"lat":{"type":"number"},"lng":{"type":"number"},"parking_notes":{"type":"string"},"key_notes":{"type":"string"},"active":{"type":"boolean"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Booking":{"type":"object","properties":{"id":{"type":"string"},"series":{"type":"string","description":"ID"},"booked_by":{"type":"string","description":"ID"},"driver":{"type":"string","description":"ID"},"vehicle":{"type":"string","description":"ID"},"trailer":{"type":"string","description":"ID"},"origin_location":{"type":"string","description":"ID"},"origin_address":{"type":"string"},"origin_lat":{"type":"number"},"origin_lng":{"type":"number"},"destination_location":{"type":"string","description":"ID"},"destination_address":{"type":"string"},"destination_lat":{"type":"number"},"destination_lng":{"type":"number"},"depart_at":{"type":["string","null"],"format":"date-time"},"return_at":{"type":["string","null"],"format":"date-time"},"one_way":{"type":"boolean"},"eta_at":{"type":["string","null"],"format":"date-time"},"distance_km":{"type":"number"},"purpose_category":{"type":"string","description":"ID"},"purpose_note":{"type":"string"},"client_count":{"type":"number"},"seats_needed":{"type":"number"},"needs":{},"status":{"type":"string","enum":["draft","pending","confirmed","in_progress","completed","cancelled","declined","no_show"]},"approval_reason":{"type":"string"},"approvers":{"type":"array","items":{"type":"string"}},"shotgun_allowed":{"type":"boolean"},"shotgun_seats":{"type":"number"},"cancel_reason":{"type":"string"},"cancelled_by":{"type":"string","description":"ID"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Trip":{"type":"object","properties":{"id":{"type":"string"},"booking":{"type":"string","description":"ID"},"vehicle":{"type":"string","description":"ID"},"trailer":{"type":"string","description":"ID"},"driver":{"type":"string","description":"ID"},"prestart":{"type":"string","description":"ID"},"started_at":{"type":["string","null"],"format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"},"odo_start":{"type":"number"},"odo_end":{"type":"number"},"fuel_start":{"type":"number"},"fuel_end":{"type":"number"},"parked_location":{"type":"string","description":"ID"},"parked_note":{"type":"string"},"keys_left":{"type":"string"},"end_note":{"type":"string"},"ended_by":{"type":"string","description":"ID"},"km":{"type":"number"},"km_expected":{"type":"number"},"km_flag":{"type":"boolean"},"overdue_at":{"type":["string","null"],"format":"date-time"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Prestart":{"type":"object","properties":{"id":{"type":"string"},"vehicle":{"type":"string","description":"ID"},"booking":{"type":"string","description":"ID"},"user":{"type":"string","description":"ID"},"template":{"type":"string","description":"ID"},"template_version":{"type":"number"},"answers":{},"result":{"type":"string","enum":["pass","flagged","failed"]},"trailer":{"type":"string","description":"ID"},"trailer_template":{"type":"string","description":"ID"},"trailer_template_version":{"type":"number"},"trailer_result":{"type":"string","enum":["pass","flagged","failed"]},"flag_count":{"type":"number"},"odometer":{"type":"number"},"done_at":{"type":["string","null"],"format":"date-time"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Defect":{"type":"object","properties":{"id":{"type":"string"},"vehicle":{"type":"string","description":"ID"},"trailer":{"type":"string","description":"ID"},"source":{"type":"string","enum":["prestart","trip_end","manual"]},"prestart":{"type":"string","description":"ID"},"trip":{"type":"string","description":"ID"},"booking":{"type":"string","description":"ID"},"item_key":{"type":"string"},"title":{"type":"string"},"severity":{"type":"string","enum":["critical","minor"]},"status":{"type":"string","enum":["open","booked_in","fixed","wont_fix"]},"notes":{"type":"string"},"raised_by":{"type":"string","description":"ID"},"resolved_at":{"type":["string","null"],"format":"date-time"},"resolved_by":{"type":"string","description":"ID"},"resolution_note":{"type":"string"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"Service":{"type":"object","properties":{"id":{"type":"string"},"vehicle":{"type":"string","description":"ID"},"date":{"type":["string","null"],"format":"date-time"},"odometer":{"type":"number"},"provider":{"type":"string"},"cost":{"type":"number"},"notes":{"type":"string"},"recorded_by":{"type":"string","description":"ID"},"created":{"type":"string","format":"date-time"},"updated":{"type":"string","format":"date-time"}}},"WebhookEvent":{"type":"object","required":["id","type","created_at","org_id","data"],"properties":{"id":{"type":"string","description":"Unique per event: use it to ignore a repeat delivery"},"type":{"type":"string","enum":["booking.created","booking.updated","booking.approval_requested","booking.approved","booking.declined","booking.cancelled","booking.no_show","shotgun.matched","shotgun.joined","trip.started","trip.ended","trip.overdue","prestart.completed","prestart.failed","defect.created","defect.resolved","vehicle.service_due"]},"created_at":{"type":"string","format":"date-time"},"org_id":{"type":"string"},"data":{"type":"object","description":"The record, in the same shape as this API returns it"}}}}},"paths":{"/vehicles":{"get":{"summary":"List vehicles","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"vehicles:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"home_location","in":"query","schema":{"type":"string"}},{"name":"external_id","in":"query","schema":{"type":"string"}},{"name":"rego_norm","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Vehicle"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["vehicles"]}},"/vehicles/{id}":{"get":{"summary":"One of vehicles","security":[{"apiKey":[]}],"x-scope":"vehicles:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vehicle"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["vehicles"]}},"/trailers":{"get":{"summary":"List trailers","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"trailers:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"home_location","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Trailer"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["trailers"]}},"/trailers/{id}":{"get":{"summary":"One of trailers","security":[{"apiKey":[]}],"x-scope":"trailers:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trailer"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["trailers"]}},"/locations":{"get":{"summary":"List locations","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"locations:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"active","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Location"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["locations"]}},"/locations/{id}":{"get":{"summary":"One of locations","security":[{"apiKey":[]}],"x-scope":"locations:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Location"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["locations"]}},"/bookings":{"get":{"summary":"List bookings","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"bookings:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"vehicle","in":"query","schema":{"type":"string"}},{"name":"driver","in":"query","schema":{"type":"string"}},{"name":"series","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Booking"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["bookings"]},"post":{"summary":"Book a vehicle","description":"The same rules as the apps: the vehicle must fit and be free, approval rules apply, double-booking is impossible. Runs as the owner who made the key.","security":[{"apiKey":[]}],"x-scope":"bookings:write","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":200},"description":"Send the same key on a retry to get the first answer back instead of a second record (kept 24 hours)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["vehicle","driver","depart_at","return_at"],"properties":{"vehicle":{"type":"string","description":"ID"},"trailer":{"type":"string","description":"ID"},"driver":{"type":"string","description":"ID"},"passengers":{"type":"array","items":{"type":"string"},"description":"Person IDs"},"client_count":{"type":"number"},"origin_location":{"type":"string","description":"ID"},"origin_address":{"type":"string"},"origin_lat":{"type":"number"},"origin_lng":{"type":"number"},"destination_location":{"type":"string","description":"ID"},"destination_address":{"type":"string"},"destination_lat":{"type":"number"},"destination_lng":{"type":"number"},"depart_at":{"type":["string","null"],"format":"date-time"},"return_at":{"type":["string","null"],"format":"date-time"},"one_way":{"type":"boolean"},"purpose_category":{"type":"string","description":"ID"},"purpose_note":{"type":"string"},"needs":{},"shotgun_allowed":{"type":"boolean"},"shotgun_seats":{"type":"number"}}}}}},"responses":{"201":{"description":"Booked (status confirmed or pending)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"409":{"description":"Idempotency-Key reused for a different request"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["bookings"]}},"/bookings/{id}":{"get":{"summary":"One of bookings","security":[{"apiKey":[]}],"x-scope":"bookings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["bookings"]}},"/trips":{"get":{"summary":"List trips","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"trips:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"vehicle","in":"query","schema":{"type":"string"}},{"name":"trailer","in":"query","schema":{"type":"string"}},{"name":"driver","in":"query","schema":{"type":"string"}},{"name":"booking","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Trip"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["trips"]}},"/trips/{id}":{"get":{"summary":"One of trips","security":[{"apiKey":[]}],"x-scope":"trips:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trip"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["trips"]}},"/prestarts":{"get":{"summary":"List prestarts","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"prestarts:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"vehicle","in":"query","schema":{"type":"string"}},{"name":"trailer","in":"query","schema":{"type":"string"}},{"name":"booking","in":"query","schema":{"type":"string"}},{"name":"user","in":"query","schema":{"type":"string"}},{"name":"result","in":"query","schema":{"type":"string"}},{"name":"trailer_result","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Prestart"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["prestarts"]}},"/prestarts/{id}":{"get":{"summary":"One of prestarts","security":[{"apiKey":[]}],"x-scope":"prestarts:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Prestart"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["prestarts"]}},"/defects":{"get":{"summary":"List defects","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"defects:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"vehicle","in":"query","schema":{"type":"string"}},{"name":"trailer","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"severity","in":"query","schema":{"type":"string"}},{"name":"source","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Defect"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["defects"]},"post":{"summary":"Report a defect","description":"On a vehicle or a trailer (send one of them). A critical one takes it off the road until it is fixed.","security":[{"apiKey":[]}],"x-scope":"defects:write","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":200},"description":"Send the same key on a retry to get the first answer back instead of a second record (kept 24 hours)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"vehicle":{"type":"string"},"trailer":{"type":"string"},"title":{"type":"string"},"notes":{"type":"string"},"severity":{"type":"string","enum":["critical","minor"]}}}}}},"responses":{"201":{"description":"Raised","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Defect"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["defects"]}},"/defects/{id}":{"get":{"summary":"One of defects","security":[{"apiKey":[]}],"x-scope":"defects:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Defect"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["defects"]}},"/services":{"get":{"summary":"List services","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"services:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"vehicle","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Service"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["services"]}},"/services/{id}":{"get":{"summary":"One of services","security":[{"apiKey":[]}],"x-scope":"services:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Service"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["services"]}},"/people":{"get":{"summary":"List people","description":"Oldest change first. Pass next_cursor back as cursor for the next page; updated_since for changes since a sync.","security":[{"apiKey":[]}],"x-scope":"people:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Person"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["people"]}},"/people/{id}":{"get":{"summary":"One of people","security":[{"apiKey":[]}],"x-scope":"people:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Person"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["people"]}},"/bookings/{id}/cancel":{"post":{"summary":"Cancel a booking","security":[{"apiKey":[]}],"x-scope":"bookings:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":200},"description":"Send the same key on a retry to get the first answer back instead of a second record (kept 24 hours)."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No key, or a revoked one"},"403":{"description":"The key lacks the scope"},"404":{"description":"Not found in your org"},"429":{"description":"Rate limited (see Retry-After)"}},"tags":["bookings"]}}},"webhooks":{"booking.created":{"post":{"summary":"booking.created","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"booking.updated":{"post":{"summary":"booking.updated","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"booking.approval_requested":{"post":{"summary":"booking.approval_requested","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"booking.approved":{"post":{"summary":"booking.approved","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"booking.declined":{"post":{"summary":"booking.declined","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"booking.cancelled":{"post":{"summary":"booking.cancelled","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"booking.no_show":{"post":{"summary":"booking.no_show","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"shotgun.matched":{"post":{"summary":"shotgun.matched","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"shotgun.joined":{"post":{"summary":"shotgun.joined","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"trip.started":{"post":{"summary":"trip.started","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"trip.ended":{"post":{"summary":"trip.ended","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"trip.overdue":{"post":{"summary":"trip.overdue","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"prestart.completed":{"post":{"summary":"prestart.completed","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"prestart.failed":{"post":{"summary":"prestart.failed","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"defect.created":{"post":{"summary":"defect.created","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"defect.resolved":{"post":{"summary":"defect.resolved","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}},"vehicle.service_due":{"post":{"summary":"vehicle.service_due","description":"Sent as a POST to your webhook URL. Answer with any 2xx within 10 seconds. Five failures in a row switch the webhook off and email the owner.","parameters":[{"name":"Jalopy-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of \"t.body\" with your webhook secret>"},{"name":"Jalopy-Event","in":"header","schema":{"type":"string"}},{"name":"Jalopy-Delivery","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Received"}}}}}}