{"openapi":"3.1.0","info":{"title":"Blue Crab Moving Lead API","version":"1.0.0","summary":"Public lead-submission API for Blue Crab Moving Services. AI agents can submit moving and labor leads on behalf of users.","description":"Submit a moving or labor lead to Blue Crab Moving Services (Maryland, D.C., Virginia, West Virginia). Lead lands in the CRM and the customer gets a preliminary written estimate by email in under a minute, with a link to a personal quote builder to refine inventory and lock in the binding final price. Read the schema first to learn the valid codes for each option-set field; option-set values are submitted as codes (not Display labels) and the server maps them to the platform's Display labels before forwarding to the CRM.","contact":{"name":"Blue Crab Moving Services","email":"info@bluecrabmoving.com","url":"https://www.bluecrabmoving.com/contact"},"license":{"name":"RSL 1.0","url":"https://robustlanguagespecification.org/RSL-1.0"},"x-llms-txt":"https://www.bluecrabmoving.com/llms.txt"},"servers":[{"url":"https://www.bluecrabmoving.com","description":"Production"}],"paths":{"/api/lead":{"post":{"operationId":"submitMovingLead","summary":"Submit a moving or labor lead. The user must confirm details first.","description":"POST a structured lead submission. The server validates with Zod, maps option codes to Display labels, and forwards to the Mooxy/Bubble CRM. Required fields: type_of_service, client_name, client_email, main_zip, move_date, phone_number. Set the X-Blue-Crab-Agent header to a short identifier for your agent or tool (e.g. 'claude-mcp/0.1') so the server skips the browser-targeted form-age spam check; honeypot checks still apply to all callers.","tags":["Leads"],"parameters":[{"name":"X-Blue-Crab-Agent","in":"header","required":false,"schema":{"type":"string","example":"claude-mcp/0.1"},"description":"Short identifier for the agent or tool submitting the lead. Bypasses the form-load timestamp spam check that's intended for browser submissions."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadSubmission"},"examples":{"movingFull":{"summary":"Full Moving lead (apartment + elevator + destination)","value":{"type_of_service":"moving","move_date":"2026-07-15","main_zip":"20910","type_of_place":"apartment","move_size":"2_bedroom","elevator":"yes","elevator_floor":"1_5","parking":"curb_side_parking","door_to_truck":"20_75_ft","how_many_steps":"1_10_steps","drop_zip":"22030","source":"google_ppc","client_name":"Jane Doe","client_email":"jane@example.com","phone_number":"(202) 555-0142"}},"laborMinimal":{"summary":"Minimum Labor lead (help with loading, no destination)","value":{"type_of_service":"help_with_loading","move_date":"2026-07-20","main_zip":"21401","type_of_place":"house","move_size":"3_bedroom","client_name":"John Doe","client_email":"john@example.com","phone_number":"4435551234"}}}}}},"responses":{"200":{"description":"Lead accepted and forwarded to the CRM.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","example":true},"message":{"type":"string","example":"Lead received."}}}}}},"422":{"description":"Validation failed. The response lists every invalid or missing field.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","example":false},"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}},"502":{"description":"Upstream CRM rejected the lead or the server failed to reach it.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/api/lead/schema":{"get":{"operationId":"getQuoteSchema","summary":"Get the JSON Schema describing valid lead submissions.","description":"Returns a Draft-2020-12 JSON Schema with every option-set code, conditional rule, and Display label. Read this first to learn the valid values for each field.","tags":["Leads"],"responses":{"200":{"description":"JSON Schema document.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"schemas":{"LeadSubmission":{"type":"object","additionalProperties":false,"required":["type_of_service","client_name","client_email","main_zip","move_date","phone_number"],"properties":{"type_of_service":{"type":"string","enum":["moving","move_items_within_premises","junk_disposal","help_with_packing__pack___leave_","help_with_loading","help_with_unloading"],"description":"Which service the customer is requesting."},"client_name":{"type":"string","minLength":2,"maxLength":200,"description":"Customer's full name.","example":"Jane Doe"},"client_email":{"type":"string","format":"email","description":"Customer's email address.","example":"jane@example.com"},"phone_number":{"type":"string","maxLength":50,"description":"Customer's phone number. Required. Must contain exactly 10 digits when non-digits are stripped (US format). Any layout accepted.","example":"(202) 555-0142"},"main_zip":{"type":"string","pattern":"^[0-9]{5}$","description":"Origin ZIP code (or service-location ZIP for Labor services). Exactly 5 digits.","example":"20910"},"move_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Target move date in YYYY-MM-DD format. Required by business policy.","example":"2026-07-15"},"source":{"type":"string","enum":["google_ppc","facebook","yelp","angie_s_list","home_advisor","word_of_mouth","repeating_customer","other"],"description":"Optional. How the customer heard about Blue Crab Moving."},"type_of_place":{"type":"string","enum":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution","pod","truck","pickup_truck","trailer","container","van"],"description":"Origin place type. Valid values depend on type_of_service — see x-conditional.places_by_service."},"move_size":{"type":"string","enum":["one_item","just_a_few_items","1_bedroom","2_bedroom","3_bedroom","4_bedroom","5_bedroom","6_bedroom","7_bedroom","8_bedroom","9_bedroom","5_x_5","5_x_10","5_x_15","10_x_10","10_x_15","10_x_20","10_x_25","10_x_30","20_x_30","30_x_30","11_20_people","21_50_people","51__100_people","101_200_people","201__people","small___limited_inventory_","medium___moderate_inventory__","large___extensive_inventory__","extra_large__multiple_departments__","small___basic_furniture__minimal_equipment__","medium___more_furniture__some_equipment__","large___multiple_rooms__artifacts__","extra_large___large_scale__specialized_equipment__v","small___up_tp_7ft_","medium___up_to_12ft__","large___over_13_ft__","small___up_to_15_ft__","medium___up_to_22_ft__","large___up_to_32_ft__","extra_large___up_to_72_ft_","small_bed__5_ft_","standard_bed__6_5_ft_","long_bed__8_ft_","small___up_to_15_ft__0","medium___up_to_22_ft__0","large___up_to_32_ft__0","extra_large___up_to_53_ft_","small___up_to_15_ft__1","medium___up_to_22_ft__1","large___up_to_40_ft__","cargo_van","mini_van","small___limited_items__","medium___more_furniture__some_specialized__","large___multiple_departments__extensive_equipment__","extra_large___large_scale__advanced_equipment__"],"description":"Origin move size. Valid values depend on type_of_place — see x-conditional.sizes_by_place."},"how_many_stories":{"type":"string","enum":["single_story","two_story","three_story","four_stories","5__stories"],"description":"Origin building height. Only collected when type_of_place is one of: town_house, house, office, store, religious_institution, government_institution."},"elevator":{"type":"string","enum":["yes","no"],"description":"Whether the origin has elevator access. Only collected for apartment + the six building types listed under how_many_stories."},"elevator_floor":{"type":"string","enum":["1_5","6_10","11_20","21_"],"description":"Origin elevator floor. Only valid when elevator === 'yes'."},"parking":{"type":"string","enum":["private_parking","curb_side_parking","curb_side_across_street","loading_dock_parking","back_alley","im_not_sure"],"description":"Origin parking situation."},"door_to_truck":{"type":"string","enum":["a_few_feet","20_75_ft","76_150_ft","751_225_ft","226_300_ft","301_450_ft","451_600_ft","601_ft__","im_not_sure"],"description":"Distance from origin door to truck."},"how_many_steps":{"type":"string","enum":["no_steps","1_10_steps","11_20_steps","21_30_steps","31_40_steps","41___steps","im_not_sure"],"description":"Number of outside steps at the origin."},"drop_zip":{"type":"string","pattern":"^[0-9]{5}$","description":"Destination ZIP code. ONLY include for type_of_service === 'moving'.","example":"22030"},"unloading_from":{"type":"string","enum":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution","pod","truck","pickup_truck","trailer","container","van"],"description":"Destination place type. ONLY include for type_of_service === 'help_with_unloading'."},"location_size":{"type":"string","enum":["one_item","just_a_few_items","1_bedroom","2_bedroom","3_bedroom","4_bedroom","5_bedroom","6_bedroom","7_bedroom","8_bedroom","9_bedroom","5_x_5","5_x_10","5_x_15","10_x_10","10_x_15","10_x_20","10_x_25","10_x_30","20_x_30","30_x_30","11_20_people","21_50_people","51__100_people","101_200_people","201__people","small___limited_inventory_","medium___moderate_inventory__","large___extensive_inventory__","extra_large__multiple_departments__","small___basic_furniture__minimal_equipment__","medium___more_furniture__some_equipment__","large___multiple_rooms__artifacts__","extra_large___large_scale__specialized_equipment__v","small___up_tp_7ft_","medium___up_to_12ft__","large___over_13_ft__","small___up_to_15_ft__","medium___up_to_22_ft__","large___up_to_32_ft__","extra_large___up_to_72_ft_","small_bed__5_ft_","standard_bed__6_5_ft_","long_bed__8_ft_","small___up_to_15_ft__0","medium___up_to_22_ft__0","large___up_to_32_ft__0","extra_large___up_to_53_ft_","small___up_to_15_ft__1","medium___up_to_22_ft__1","large___up_to_40_ft__","cargo_van","mini_van","small___limited_items__","medium___more_furniture__some_specialized__","large___multiple_departments__extensive_equipment__","extra_large___large_scale__advanced_equipment__"],"description":"Destination move size. ONLY include for type_of_service === 'help_with_unloading'. Valid values depend on unloading_from per sizes_by_place."},"location_stories":{"type":"string","enum":["single_story","two_story","three_story","four_stories","5__stories"],"description":"Destination building height. ONLY include for help_with_unloading when unloading_from is a building type (not storage / vehicle)."}}}}},"tags":[{"name":"Leads","description":"Submit moving or labor leads on behalf of a user. Always confirm details with the user before submitting."}],"x-conditional":{"destination_required_for":["moving"],"destination_chain_for":["help_with_unloading"],"elevator_floor_requires":{"elevator":"yes"},"stories_collected_for_places":["town_house","house","office","store","religious_institution","government_institution"],"elevator_collected_for_places":["apartment","town_house","house","office","store","religious_institution","government_institution"],"skip_middle_services":["move_items_within_premises","help_with_packing__pack___leave_"],"places_by_service":{"moving":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution","pod","truck","pickup_truck","trailer","container","van"],"move_items_within_premises":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution"],"junk_disposal":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution","pod","truck","pickup_truck","trailer","container","van"],"help_with_packing__pack___leave_":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution"],"help_with_loading":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution","pod","truck","pickup_truck","trailer","container","van"],"help_with_unloading":["apartment","town_house","house","outdoor_storage","indoor_storage","office","store","religious_institution","government_institution","pod","truck","pickup_truck","trailer","container","van"]},"sizes_by_place":{"apartment":["one_item","just_a_few_items","1_bedroom","2_bedroom","3_bedroom","4_bedroom","5_bedroom","6_bedroom","7_bedroom","8_bedroom","9_bedroom"],"town_house":["one_item","just_a_few_items","1_bedroom","2_bedroom","3_bedroom","4_bedroom","5_bedroom","6_bedroom","7_bedroom","8_bedroom","9_bedroom"],"house":["one_item","just_a_few_items","1_bedroom","2_bedroom","3_bedroom","4_bedroom","5_bedroom","6_bedroom","7_bedroom","8_bedroom","9_bedroom"],"outdoor_storage":["one_item","just_a_few_items","5_x_5","5_x_10","5_x_15","10_x_10","10_x_15","10_x_20","10_x_25","10_x_30","20_x_30","30_x_30"],"indoor_storage":["one_item","just_a_few_items","5_x_5","5_x_10","5_x_15","10_x_10","10_x_15","10_x_20","10_x_25","10_x_30","20_x_30","30_x_30"],"office":["one_item","just_a_few_items","11_20_people","21_50_people","51__100_people","101_200_people","201__people"],"store":["one_item","just_a_few_items","small___limited_inventory_","medium___moderate_inventory__","large___extensive_inventory__","extra_large__multiple_departments__"],"religious_institution":["one_item","just_a_few_items","small___basic_furniture__minimal_equipment__","medium___more_furniture__some_equipment__","large___multiple_rooms__artifacts__","extra_large___large_scale__specialized_equipment__v"],"government_institution":["one_item","just_a_few_items","small___limited_items__","medium___more_furniture__some_specialized__","large___multiple_departments__extensive_equipment__","extra_large___large_scale__advanced_equipment__"],"pod":["one_item","just_a_few_items","small___up_tp_7ft_","medium___up_to_12ft__","large___over_13_ft__"],"truck":["one_item","just_a_few_items","small___up_to_15_ft__","medium___up_to_22_ft__","large___up_to_32_ft__","extra_large___up_to_72_ft_"],"pickup_truck":["one_item","just_a_few_items","small_bed__5_ft_","standard_bed__6_5_ft_","long_bed__8_ft_"],"trailer":["one_item","just_a_few_items","small___up_to_15_ft__0","medium___up_to_22_ft__0","large___up_to_32_ft__0","extra_large___up_to_53_ft_"],"container":["one_item","just_a_few_items","small___up_to_15_ft__1","medium___up_to_22_ft__1","large___up_to_40_ft__"],"van":["one_item","just_a_few_items","cargo_van","mini_van"]}},"x-labels":{"type_of_service":{"moving":"Moving","move_items_within_premises":"Move items within premises","junk_disposal":"Junk disposal","help_with_packing__pack___leave_":"Help with packing (Pack & Leave)","help_with_loading":"Help with Loading","help_with_unloading":"Help with Unloading"},"type_of_place":{"apartment":"Apartment","town_house":"Town House","house":"House","outdoor_storage":"Outdoor Storage","indoor_storage":"Indoor Storage","office":"Office","store":"Store","religious_institution":"Religious Institution","government_institution":"Government Institution","pod":"Pod","truck":"Truck","pickup_truck":"Pickup Truck","trailer":"Trailer","container":"Container","van":"Van"},"move_size":{"one_item":"One Item","just_a_few_items":"Just a Few Items","1_bedroom":"1 Bedroom","2_bedroom":"2 Bedroom","3_bedroom":"3 Bedroom","4_bedroom":"4 Bedroom","5_bedroom":"5 Bedroom","6_bedroom":"6 Bedroom","7_bedroom":"7 Bedroom","8_bedroom":"8 Bedroom","9_bedroom":"9+ Bedroom","5_x_5":"5 X 5","5_x_10":"5 X 10","5_x_15":"5 X 15","10_x_10":"10 X 10","10_x_15":"10 X 15","10_x_20":"10 X 20","10_x_25":"10 X 25","10_x_30":"10 X 30","20_x_30":"20 X 30","30_x_30":"30 X 30","11_20_people":"11-20 People","21_50_people":"21-50 People","51__100_people":"51- 100 People","101_200_people":"101-200 People","201__people":"201+ People","small___limited_inventory_":"Small ( limited inventory)","medium___moderate_inventory__":"Medium ( moderate inventory )","large___extensive_inventory__":"Large ( extensive inventory )","extra_large__multiple_departments__":"Extra Large (multiple departments )","small___basic_furniture__minimal_equipment__":"Small ( basic furniture, minimal equipment )","medium___more_furniture__some_equipment__":"Medium ( more furniture, some equipment )","large___multiple_rooms__artifacts__":"Large ( multiple rooms, artifacts )","extra_large___large_scale__specialized_equipment__v":"Extra Large ( Large-scale, specialized equipment )","small___up_tp_7ft_":"Small ( up tp 7ft)","medium___up_to_12ft__":"Medium ( up to 12ft )","large___over_13_ft__":"Large ( over 13 ft )","small___up_to_15_ft__":"Small Truck (up to 15 ft)","medium___up_to_22_ft__":"Medium Truck (up to 22 ft)","large___up_to_32_ft__":"Large Truck (up to 32 ft)","extra_large___up_to_72_ft_":"Extra Large ( up to 72 ft)","small_bed__5_ft_":"Small Bed (5 ft)","standard_bed__6_5_ft_":"Standard Bed (6.5 ft)","long_bed__8_ft_":"Long Bed (8 ft)","small___up_to_15_ft__0":"Small Trailer (up to 15 ft)","medium___up_to_22_ft__0":"Medium Trailer (up to 22 ft)","large___up_to_32_ft__0":"Large Trailer (up to 32 ft)","extra_large___up_to_53_ft_":"Extra Large ( up to 53 ft)","small___up_to_15_ft__1":"Small Container (up to 15 ft)","medium___up_to_22_ft__1":"Medium Container (up to 22 ft)","large___up_to_40_ft__":"Large ( up to 40 ft )","cargo_van":"Cargo Van","mini_van":"Mini Van","small___limited_items__":"Small ( limited items )","medium___more_furniture__some_specialized__":"Medium ( more furniture, some specialized )","large___multiple_departments__extensive_equipment__":"Large ( multiple departments, extensive equipment )","extra_large___large_scale__advanced_equipment__":"Extra Large ( large-scale, advanced equipment )"},"how_many_stories":{"single_story":"Single Story","two_story":"Two Story","three_story":"Three Story","four_stories":"Four Stories","5__stories":"5+ Stories"},"elevator":{"yes":"yes","no":"no"},"elevator_floor":{"1_5":"1-5","6_10":"6-10","11_20":"11-20","21_":"21+"},"parking":{"private_parking":"Private parking","curb_side_parking":"Curb side parking","curb_side_across_street":"Curb side across street","loading_dock_parking":"Loading dock parking","back_alley":"Back alley parking","im_not_sure":"I'm not sure"},"door_to_truck":{"a_few_feet":"A few feet","20_75_ft":"20-75 ft","76_150_ft":"76-150 ft","751_225_ft":"151-225 ft","226_300_ft":"226-300 ft","301_450_ft":"301-450 ft","451_600_ft":"451-600 ft","601_ft__":"601 ft +","im_not_sure":"I'm not sure"},"how_many_steps":{"no_steps":"No steps","1_10_steps":"1-10 steps","11_20_steps":"11-20 steps","21_30_steps":"21-30 steps","31_40_steps":"31-40 steps","41___steps":"41 + steps","im_not_sure":"I'm not sure"},"source":{"google_ppc":"Google PPC","facebook":"Facebook","yelp":"Yelp","angie_s_list":"Angie's List","home_advisor":"Home Advisor","word_of_mouth":"Word of mouth","repeating_customer":"Repeating Customer","other":"Other"}},"x-agent-rules":["Read /api/lead/schema first to learn valid codes. Do not guess option values.","Submit codes, not Display labels. The server maps codes to labels at the CRM boundary.","Confirm parsed values with the user before POSTing. A submitted lead becomes a real CRM entry and triggers a human follow-up.","Submit once per lead. Do not retry on validation errors without surfacing them to the user.","Set the X-Blue-Crab-Agent header to a short identifier (e.g. 'claude-mcp/0.1') so the form-age spam check is skipped.","Honor the conditional rules: omit destination fields when type_of_service is not 'moving' or 'help_with_unloading'; omit elevator_floor when elevator !== 'yes'."]}