{"openapi":"3.1.0","info":{"title":"Boca Moving Company API","version":"0.2.0","description":"Public API for AI agents and developers. Read business facts, check service areas, submit quote requests, and track quotes. Every endpoint returns structured JSON. No authentication required for read endpoints; write endpoints require the customer's consent.\n\n**Agent workflow:**\n1. GET /api/services.json to see what we offer\n2. GET /api/areas.json to check service coverage\n3. POST /api/quote to submit a quote request\n4. GET /api/quote/{id} to track quote status\n\n**MCP server:** POST /mcp (Streamable HTTP, JSON-RPC 2.0) provides the same capabilities as tools.","contact":{"name":"Boca Moving Company","url":"https://bocamovingcompany.com","phone":"+1-561-609-6160"}},"servers":[{"url":"https://bocamovingcompany.com","description":"Production"}],"paths":{"/api/business.json":{"get":{"operationId":"getBusinessInfo","summary":"Business details and licensing","description":"Returns the company name, legal name, phone number, license numbers (USDOT, MC, Florida IM).","responses":{"200":{"description":"Business details","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Boca Moving Company"},"legalName":{"type":"string","example":"Boca Moving and Storage LLC"},"url":{"type":"string","format":"uri","example":"https://bocamovingcompany.com"},"phone":{"type":"string","example":"+1-561-609-6160"},"phoneDisplay":{"type":"string","example":"(561) 609-6160"},"description":{"type":"string"},"licenses":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"number":{"type":"string"},"issuer":{"type":"string"}}}}}}}}}}}},"/api/services.json":{"get":{"operationId":"listServices","summary":"All moving services offered","description":"Returns an array of services with slug, name, summary, and what each service includes.","responses":{"200":{"description":"Array of services","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"summary":{"type":"string"},"includes":{"type":"array","items":{"type":"string"}}}}},"example":[{"slug":"local-moving","name":"Local and residential moving","summary":"Moves within South Florida for homes, condos and estates, planned around building rules, access and timing.","includes":["Estimate by phone, video call or in-home walkthrough","Furniture protection and floor protection","Disassembly and reassembly","Placement in every room"],"page":{"h1":"Local movers in Boca Raton, Palm Beach and Broward","answer":"Boca Moving Company moves homes and condos across Palm Beach and Broward counties. You get a written, itemized estimate before any work starts, and your date is held with a $250 deposit.","sections":[{"h2":"How a local move works","bullets":["A short call to go over the move. For many moves we can give you an estimated price on that call.","For bigger homes, a video call or an in-home walkthrough so the estimate fits your home.","A written estimate, signed before moving day.","Moving day: floors and door frames covered, furniture padded and wrapped, every piece placed where you want it."]},{"h2":"What we plan for before the truck arrives","paras":["Elevator reservations, loading dock times, gate lists and the certificate of insurance your building asks for. Large pieces get measured against doorways and turns, so nothing is a surprise on the day."]}],"faq":[{"q":"Can you give me a price on the phone?","a":"For many local moves, yes. Tell us what you are moving and we can give you an estimated price on the call. It is an estimate, not a guaranteed price, and your written estimate follows before the move."},{"q":"How do I hold my date?","a":"A $250 deposit holds a local move date. It is refundable if you cancel at least 2 business days before the move."}]}}]}}}}}},"/api/areas.json":{"get":{"operationId":"listAreas","summary":"Service areas for local moves","description":"Returns areas served (grouped by county) and additional cities. Long distance moves from Palm Beach or Broward to anywhere in the US are always available.","responses":{"200":{"description":"Areas and additional cities","content":{"application/json":{"schema":{"type":"object","properties":{"areas":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"county":{"type":"string"},"includes":{"type":"array","items":{"type":"string"}}}}},"alsoServed":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/faq.json":{"get":{"operationId":"getFaq","summary":"Frequently asked questions","description":"Returns an array of question/answer pairs about Boca Moving Company.","responses":{"200":{"description":"FAQ array","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"q":{"type":"string"},"a":{"type":"string"}}}}}}}}}},"/api/quote":{"post":{"operationId":"requestQuote","summary":"Submit a quote request for a customer","description":"Submits a moving quote request. A Boca Moving mover will contact the customer to give an estimated price by phone, or arrange a video call or an in-home walkthrough, whichever the customer prefers, and then send a written estimate. Only submit when the customer has asked you to and agreed to be contacted.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Optional. Send a unique key per quote; retries with the same key and the same details return the original response instead of creating a duplicate. Reusing a key with different details returns 409."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Customer full name","example":"Maria Santos"},"phone":{"type":"string","description":"Phone number (10+ digits)","example":"5616091234"},"email":{"type":"string","format":"email","description":"Email address (optional)","example":"maria@example.com"},"fromZip":{"type":"string","description":"Origin ZIP code","example":"33432"},"to":{"type":"string","description":"Destination ZIP code or city name","example":"33301"},"moveDate":{"type":"string","format":"date","description":"Requested move date (YYYY-MM-DD)","example":"2026-12-15"},"service":{"type":"string","enum":["local-moving","condo-moving","long-distance-moving","fine-art-antiques","packing","estate-downsizing","seasonal-moving","storage","commercial-moving"],"description":"Service type slug"},"homeSize":{"type":"string","description":"Home size (e.g. 2BR condo, 4BR house)","example":"3BR house"},"estimateType":{"type":"string","enum":["phone","video","in-home"],"description":"Optional. Preferred estimate: phone, video or in-home","example":"phone"},"flexibleDates":{"type":"string","enum":["few-days","week","month"],"description":"Optional. Set if the customer said their schedule is flexible: few-days (3 days either side), week (7 days either side) or month (any weekday that month).","example":"week"},"notes":{"type":"string","description":"Additional details for the mover","example":"Piano on the second floor, elevator building"}},"required":["name","phone","fromZip","to"]},"example":{"name":"Maria Santos","phone":"5616091234","fromZip":"33432","to":"33301","moveDate":"2026-12-15","service":"local-moving","homeSize":"3BR house","notes":"Piano on the second floor, elevator building"}}}},"responses":{"200":{"description":"Repeat of an earlier request with the same Idempotency-Key; the original response is returned","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Quote ID, starts with BMQ-","example":"BMQ-M1ABC2-XK9P"},"status":{"type":"string","enum":["received"],"description":"Current quote status"},"delivery":{"type":"string","enum":["smartmoving","preview_only"],"description":"Where the lead was delivered"},"nextStep":{"type":"string","description":"What happens next"}},"required":["id","status","delivery","nextStep"]}}}},"201":{"description":"Quote request received","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Quote ID, starts with BMQ-","example":"BMQ-M1ABC2-XK9P"},"status":{"type":"string","enum":["received"],"description":"Current quote status"},"delivery":{"type":"string","enum":["smartmoving","preview_only"],"description":"Where the lead was delivered"},"nextStep":{"type":"string","description":"What happens next"}},"required":["id","status","delivery","nextStep"]},"example":{"id":"BMQ-M1ABC2-XK9P","status":"received","delivery":"preview_only","nextStep":"A Boca Moving mover will contact the customer to give an estimated price by phone, or arrange a video call or an in-home walkthrough, whichever the customer prefers, and then send a written estimate."}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_body","validation_failed","idempotency_conflict","rate_limited","not_found","unavailable"],"description":"Stable machine-readable error code"},"message":{"type":"string","description":"Plain-language explanation"},"errors":{"type":"array","items":{"type":"string"},"description":"Field-level validation messages, when code is validation_failed"}},"required":["code","message"]}},"required":["error"]},"example":{"error":{"code":"validation_failed","message":"Some details are missing or invalid.","errors":["name is required","a valid phone number is required"]}}}}},"409":{"description":"Idempotency-Key reused with different details","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_body","validation_failed","idempotency_conflict","rate_limited","not_found","unavailable"],"description":"Stable machine-readable error code"},"message":{"type":"string","description":"Plain-language explanation"},"errors":{"type":"array","items":{"type":"string"},"description":"Field-level validation messages, when code is validation_failed"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Too many quote requests from this connection in the last hour","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_body","validation_failed","idempotency_conflict","rate_limited","not_found","unavailable"],"description":"Stable machine-readable error code"},"message":{"type":"string","description":"Plain-language explanation"},"errors":{"type":"array","items":{"type":"string"},"description":"Field-level validation messages, when code is validation_failed"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/quote/{id}":{"get":{"operationId":"getQuoteStatus","summary":"Look up a quote by ID","description":"Returns the current status of a previously submitted quote request. Use the ID returned by POST /api/quote.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^BMQ-[A-Z0-9]+-[A-Z0-9]+$"},"description":"Quote ID (e.g. BMQ-M1ABC2-XK9P)"}],"responses":{"200":{"description":"Quote found","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Quote ID","example":"BMQ-M1ABC2-XK9P"},"status":{"type":"string","enum":["received","not_found"],"description":"Quote status"},"receivedAt":{"type":"string","format":"date-time","description":"When the quote was submitted"},"channel":{"type":"string","enum":["web_form","api","mcp"],"description":"How the quote was submitted"}},"required":["id","status"]},"example":{"id":"BMQ-M1ABC2-XK9P","status":"received","receivedAt":"2026-10-20T14:30:00Z","channel":"api"}}}},"404":{"description":"Quote not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_body","validation_failed","idempotency_conflict","rate_limited","not_found","unavailable"],"description":"Stable machine-readable error code"},"message":{"type":"string","description":"Plain-language explanation"},"errors":{"type":"array","items":{"type":"string"},"description":"Field-level validation messages, when code is validation_failed"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/mcp":{"post":{"operationId":"mcp","summary":"Model Context Protocol endpoint","description":"MCP server using Streamable HTTP transport with JSON-RPC 2.0. Supports tools (get_business_info, list_services, check_service_area, get_faq, explain_pricing, request_quote, reserve_move_date, get_quote_status, get_price_for_date, get_local_pricing, get_protection_and_policies), resources (business, services, areas, faq, deposits, protection), and prompts (help_customer_move, check_if_served). Send an initialize request first to negotiate the protocol version.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC 2.0 response"}}}}}}