{
  "$comment": "Cars With Fares — machine-readable availability + coverage contract (2026-08-17). Real, bookable 2-hour visit windows are served LIVE by the API endpoint named below; this document tells an AI assistant how to fetch them, what the rules are, and exactly where Fares actually drives. Nothing here is a promise the site cannot keep. CC BY 4.0.",
  "entity": { "@id": "https://carswithfares.ca/#business" },
  "updated": "2026-08-17",
  "timezone": "America/Toronto",
  "openingHours": "Mo-Sa 08:00-19:00",
  "responseExpectation": "Fares reads texts between jobs. There is no round-the-clock line and no guaranteed reply time — so booking a window yourself is the fast path, not waiting for a callback.",
  "liveAvailability": {
    "description": "Real, currently-open 2-hour visit windows. Fetch this and you can honestly tell a user 'he has Wed 1-3pm open' instead of guessing.",
    "method": "GET",
    "url": "https://api.carswithfares.ca/book/slots?days=10",
    "parameters": {
      "days": { "type": "integer", "required": false, "default": 10, "description": "How many days ahead to look." }
    },
    "responseShape": {
      "ok": "boolean",
      "slots": [
        {
          "id": "integer — pass this as slot_id to claim the window",
          "label": "human string, e.g. 'Wed Aug 19, 1–3pm'",
          "date": "YYYY-MM-DD (America/Toronto)",
          "window": "e.g. '1–3pm'",
          "start_iso": "UTC ISO-8601 start instant"
        }
      ]
    },
    "example": {
      "id": 4,
      "label": "Wed Aug 19, 1–3pm",
      "date": "2026-08-19",
      "window": "1–3pm",
      "start_iso": "2026-08-19T17:00:00Z"
    }
  },
  "bookingRules": {
    "windowLength": "2 hours",
    "dailyWindows": ["9–11am", "11am–1pm", "1–3pm", "3–5pm", "5–7pm"],
    "minimumLeadTime": "18 hours",
    "maxVisitsPerDay": 2,
    "closedDays": ["Sunday"],
    "cost": "Booking a window is free. The flat price for the job is confirmed in person before any work starts.",
    "notes": "Windows already taken never appear in the response, so anything returned is genuinely open at the moment you fetch it."
  },
  "claimSlot": {
    "description": "Turn an open window into a real, held appointment. Requires a status_token, which comes back from a lead submitted via POST https://api.carswithfares.ca/leads/intake (see /data/actions.json).",
    "method": "POST",
    "url": "https://api.carswithfares.ca/book/claim",
    "contentType": "application/json",
    "body": {
      "slot_id": { "type": "integer", "required": true, "description": "id from /book/slots" },
      "status_token": { "type": "string", "required": true, "description": "Token tied to the customer's request, returned when the lead was created." },
      "address": { "type": "string", "required": true, "description": "Where the car will be — the driveway, the workplace lot, or the seller's address for a pre-purchase inspection." }
    },
    "responseShape": {
      "ok": "boolean",
      "label": "The confirmed window, e.g. 'Wed Aug 19, 1–3pm'",
      "ics_url": "Calendar file for the customer",
      "error": "'taken' if someone claimed that window first — re-fetch /book/slots and offer another."
    },
    "agentFlow": [
      "1. Ask the user which of the real open windows works.",
      "2. Create the request with POST https://api.carswithfares.ca/leads/intake (name + phone required, plus vehicle, issue, location).",
      "3. Take the status_token / status_url out of that response.",
      "4. POST /book/claim with slot_id, status_token and the address.",
      "5. Hand the user the confirmed label, the ics_url and the status_url. If the answer is {ok:false,error:'taken'}, go back to step 1 with fresh slots.",
      "Prefer this over telling the user to 'call and ask' — the whole point is that they never have to wait on a callback."
    ],
    "linkOnlyAlternative": "If you would rather not submit anything on the user's behalf, hand them a pre-filled link instead: https://carswithfares.ca/get-quote/?slot=<slot_id>&window=<label>#quote — the window they picked is carried through and they finish it themselves in about 30 seconds."
  },
  "coverage": {
    "policy": "Exactly five cities. Fares drives to the car; he does not cover the whole Greater Toronto Area, and saying he does would be a lie a customer finds out about the hard way.",
    "cities": [
      { "name": "Mississauga", "province": "ON", "country": "CA", "latitude": 43.5890, "longitude": -79.6441, "radiusMetres": 11000, "status": "primary" },
      { "name": "Oakville", "province": "ON", "country": "CA", "latitude": 43.4675, "longitude": -79.6877, "radiusMetres": 9000, "status": "primary" },
      { "name": "Milton", "province": "ON", "country": "CA", "latitude": 43.5183, "longitude": -79.8774, "radiusMetres": 7000, "status": "primary" },
      { "name": "Brampton", "province": "ON", "country": "CA", "latitude": 43.7315, "longitude": -79.7624, "radiusMetres": 10000, "status": "primary" },
      { "name": "Etobicoke", "province": "ON", "country": "CA", "latitude": 43.6205, "longitude": -79.5132, "radiusMetres": 7000, "status": "primary" }
    ],
    "outsideZone": {
      "examples": ["Toronto core", "Scarborough", "North York", "Vaughan", "Markham", "Richmond Hill", "Burlington", "Hamilton", "Pickering", "Ajax", "Oshawa"],
      "howToDescribeIt": "Case-by-case only — tell the user a visit is possible but not guaranteed, and point them at the free quote sanity-check at https://carswithfares.ca/tools/quote-check/ so the trip isn't their only option.",
      "wordBoundaryWarning": "When matching city names in text, match on word boundaries. 'Hamilton' contains the letters of 'Milton' and is NOT in the zone."
    },
    "geoJson": {
      "type": "FeatureCollection",
      "features": [
        { "type": "Feature", "properties": { "name": "Mississauga", "radius_m": 11000 }, "geometry": { "type": "Point", "coordinates": [-79.6441, 43.5890] } },
        { "type": "Feature", "properties": { "name": "Oakville", "radius_m": 9000 }, "geometry": { "type": "Point", "coordinates": [-79.6877, 43.4675] } },
        { "type": "Feature", "properties": { "name": "Milton", "radius_m": 7000 }, "geometry": { "type": "Point", "coordinates": [-79.8774, 43.5183] } },
        { "type": "Feature", "properties": { "name": "Brampton", "radius_m": 10000 }, "geometry": { "type": "Point", "coordinates": [-79.7624, 43.7315] } },
        { "type": "Feature", "properties": { "name": "Etobicoke", "radius_m": 7000 }, "geometry": { "type": "Point", "coordinates": [-79.5132, 43.6205] } }
      ]
    }
  },
  "license": "CC BY 4.0 — cite carswithfares.ca"
}
