{"openapi":"3.1.0","info":{"title":"Muvon Reseller API","version":"1.0.0","description":"Sell Muvon private transfers in the Riviera Maya: quote, book, collect through a Muvon payment link (2-hour hold) and receive signed webhooks. Money is integer US cents; dates are ISO 8601 with offset. Test keys (mvn_test_) and live keys (mvn_live_) set the mode. Docs: /developers (Spanish) and /en/developers (English).","contact":{"name":"Muvon","email":"support@muvon.mx"}},"servers":[{"url":"https://api.muvon.mx/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"general","description":"Key check and this document."},{"name":"catalogue","description":"Vehicle types, places and extras."},{"name":"quotes","description":"Server-priced quotes."},{"name":"bookings","description":"Bookings, retrieval and cancellation."},{"name":"events","description":"Events, the same ones sent by webhook."},{"name":"sandbox","description":"Test-mode helpers."}],"paths":{"/ping":{"get":{"operationId":"ping","summary":"Check your key","description":"Confirms the key works and which mode you're in. Changes nothing.","tags":["general"],"responses":{"200":{"description":"Your account and mode.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ping"},"example":{"object":"ping","livemode":false,"partner":{"id":"p_4c1d9a","code":"VIAJESSOL","name":"Viajes Sol"}}}}},"401":{"description":"Error codes: missing_api_key, invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error codes: rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/vehicle-types":{"get":{"operationId":"vehicleTypes","summary":"Vehicle types","description":"Vehicle types you can quote, with capacity and minimum notice.","tags":["catalogue"],"responses":{"200":{"description":"Full list (not paginated).","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VehicleType"}}}},"example":{"data":[{"id":"vt_sedan","object":"vehicle_type","name_es":"Sedán / SUV / Tesla","name_en":"Sedan / SUV / Tesla","min_passengers":1,"max_passengers":3,"max_bags":3,"min_notice_hours":30},{"id":"vt_van","object":"vehicle_type","name_es":"Van","name_en":"Van","min_passengers":1,"max_passengers":12,"max_bags":12,"min_notice_hours":30},{"id":"vt_sprinter","object":"vehicle_type","name_es":"Sprinter","name_en":"Sprinter","min_passengers":11,"max_passengers":19,"max_bags":19,"min_notice_hours":48}]}}}},"401":{"description":"Error codes: invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error codes: rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/places":{"get":{"operationId":"places","summary":"Places","description":"Airports, hotels and other known points. Using their `id` gives the most precise price.","tags":["catalogue"],"responses":{"200":{"description":"Full list (not paginated). Cache it for a few hours.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Place"}}}},"example":{"data":[{"id":"pl_cun","object":"place","name":"Cancun Airport (CUN)","kind":"airport","iata_code":"CUN","address":null,"lat":21.0365,"lng":-86.8771},{"id":"pl_hotel52","object":"place","name":"Hotel 52 Playa del Carmen","kind":"hotel","iata_code":null,"address":"Calle 52 Norte, Playa del Carmen","lat":20.6421,"lng":-87.0638}]}}}},"401":{"description":"Error codes: invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error codes: rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/extras":{"get":{"operationId":"extras","summary":"Extras","description":"Extras you can add to a transfer: baby seats, pets and more.","tags":["catalogue"],"responses":{"200":{"description":"Full list (not paginated).","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Extra"}}}},"example":{"data":[{"code":"BABY_SEAT","object":"extra","name_es":"Silla para bebé","name_en":"Baby seat","price_cents":1000,"currency":"USD","per_unit":true},{"code":"BOOSTER_SEAT","object":"extra","name_es":"Asiento elevador","name_en":"Booster seat","price_cents":1000,"currency":"USD","per_unit":true}]}}}},"401":{"description":"Error codes: invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error codes: rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/quotes":{"post":{"operationId":"quotesCreate","summary":"Create a quote","description":"Works out the public price and your commission for every vehicle type that fits. The quote locks the price: booking doesn't recalculate it.","tags":["quotes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"},"example":{"service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun"},"dropoff":{"place_id":"pl_hotel52"},"passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1}]}}}},"responses":{"201":{"description":"The quote.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"},"example":{"id":"qt_8f3a1c9e2b7d4f60","object":"quote","livemode":false,"expires_at":"2026-11-14T18:40:00-05:00","currency":"USD","request":{"service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1}]},"options":[{"vehicle_type_id":"vt_sedan","name":"Sedan / SUV / Tesla","max_passengers":3,"max_bags":3,"price_cents":9500,"commission_cents":950,"km":54.2},{"vehicle_type_id":"vt_van","name":"Van","max_passengers":12,"max_bags":12,"price_cents":13000,"commission_cents":1300,"km":54.2}]}}}},"400":{"description":"Error codes: parameter_missing, parameter_invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error codes: notice_too_short, same_origin_destination, route_too_long, route_not_priceable, passengers_out_of_range, too_many_bags, hours_out_of_range, extra_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Error codes: pricing_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings":{"post":{"operationId":"bookingsCreate","summary":"Create a booking","description":"Books one option of a quote. It starts as `new` and `unpaid`, with a `payment_url` for your customer and a 2-hour hold.","tags":["bookings"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique value per booking attempt. Retries with the same key and body return the stored response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingRequest"},"example":{"quote_id":"qt_8f3a1c9e2b7d4f60","vehicle_type_id":"vt_sedan","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"flight_number":"AA1234","notes":"Viajamos con una carriola","external_ref":"ORDER-5521","return_url":"https://www.example.com/orders/5521"}}}},"responses":{"201":{"description":"The booking. The same `Idempotency-Key` and body returns the same response.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"},"example":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"unpaid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":"2026-11-14T20:10:00-05:00","external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:10:00-05:00"}}}},"400":{"description":"Error codes: idempotency_key_required, parameter_missing, parameter_invalid, quote_invalid, idempotency_key_invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error codes: resource_missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error codes: idempotency_conflict, quote_expired, quote_used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error codes: option_unavailable, notice_too_short.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"bookingsList","summary":"List bookings","description":"Your bookings in the key's mode, newest first.","tags":["bookings"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. 20 by default.","schema":{"type":"integer"}},{"name":"starting_after","in":"query","required":false,"description":"Id of the last item of the previous page.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Only that status.","schema":{"type":"string","enum":["new","assigned","confirmed","on_the_way","arrived","on_board","dropped_off","completed","no_show","cancelled"]}},{"name":"from","in":"query","required":false,"description":"Pickups from this date.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Pickups up to this date.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"One page. See Pagination.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"type":"object","required":["data","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Booking"}},"has_more":{"type":"boolean","description":"Whether there are more items after this page."}}},"example":{"data":[{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"unpaid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":"2026-11-14T20:10:00-05:00","external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:10:00-05:00"}],"has_more":false}}}},"400":{"description":"Error codes: parameter_invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error codes: invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error codes: rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings/{ref}":{"get":{"operationId":"bookingsGet","summary":"Retrieve a booking","description":"A booking's current state, by `id` or `code`.","tags":["bookings"],"parameters":[{"name":"ref","in":"path","required":true,"description":"Booking `id` or `code`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The booking.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"},"example":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"unpaid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":"2026-11-14T20:10:00-05:00","external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:10:00-05:00"}}}},"401":{"description":"Error codes: invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error codes: resource_missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings/{ref}/cancel":{"post":{"operationId":"bookingsCancel","summary":"Cancel a booking","description":"Cancels up to 24 h before pickup, while the status is `new`, `assigned` or `confirmed`. The API never refunds: if it was paid, the Muvon team handles the refund.","tags":["bookings"],"parameters":[{"name":"ref","in":"path","required":true,"description":"Booking `id` or `code`.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRequest"},"example":{"reason":"Customer changed plans"}}}},"responses":{"200":{"description":"The cancelled booking. If it was paid it carries `refund: \"manual\"`.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelledBooking"},"example":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"cancelled","payment_status":"unpaid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":null,"external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":"Customer changed plans","created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-15T09:02:13-05:00","refund":"manual"}}}},"404":{"description":"Error codes: resource_missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error codes: cancel_window_closed, booking_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/events":{"get":{"operationId":"eventsList","summary":"List events","description":"The same events webhooks send, newest first. Use it to catch up on anything your server missed.","tags":["events"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. 20 by default.","schema":{"type":"integer"}},{"name":"starting_after","in":"query","required":false,"description":"Id of the last item of the previous page.","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"description":"Only that type.","schema":{"type":"string","enum":["booking.created","booking.paid","booking.assigned","booking.confirmed","booking.on_the_way","booking.arrived","booking.on_board","booking.dropped_off","booking.completed","booking.no_show","booking.cancelled","ping"]}}],"responses":{"200":{"description":"One page.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"type":"object","required":["data","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean","description":"Whether there are more items after this page."}}},"example":{"data":[{"id":"evt_0a9b8c7d6e5f4a3b","object":"event","type":"booking.paid","created":"2026-11-14T18:22:41-05:00","livemode":false,"data":{"object":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"paid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":null,"external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:22:41-05:00"}}}],"has_more":false}}}},"400":{"description":"Error codes: parameter_invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error codes: invalid_api_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/test/bookings/{ref}/pay":{"post":{"operationId":"testPay","summary":"Simulate payment","description":"Test only: marks a booking paid without Stripe and sends `booking.paid`. Test keys only.","tags":["sandbox"],"parameters":[{"name":"ref","in":"path","required":true,"description":"Booking `id` or `code`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The paid booking.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"},"example":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"paid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":null,"external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:22:41-05:00"}}}},"403":{"description":"Error codes: test_mode_only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error codes: resource_missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error codes: booking_not_payable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/test/bookings/{ref}/status":{"post":{"operationId":"testStatus","summary":"Simulate a status","description":"Test only: moves the booking to the next ride status and sends its event. Test keys only.","tags":["sandbox"],"parameters":[{"name":"ref","in":"path","required":true,"description":"Booking `id` or `code`.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestStatusRequest"},"example":{"status":"assigned"}}}},"responses":{"200":{"description":"The booking with its new status.","headers":{"Muvon-Request-Id":{"schema":{"type":"string"}},"Muvon-Mode":{"schema":{"type":"string","enum":["test","live"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"},"example":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"assigned","payment_status":"paid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":null,"external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:22:41-05:00"}}}},"403":{"description":"Error codes: test_mode_only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error codes: resource_missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error codes: invalid_status_transition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/openapi.json":{"get":{"operationId":"openapi","summary":"OpenAPI document","description":"This reference as OpenAPI 3.1, public and keyless. Use it to generate clients or import it into Postman.","tags":["general"],"security":[],"responses":{"200":{"description":"The document.","content":{"application/json":{"schema":{"type":"object"},"example":{"openapi":"3.1.0","info":{"title":"Muvon Reseller API","version":"1.0.0"}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key: mvn_test_… or mvn_live_…"}},"schemas":{"QuoteRequest":{"type":"object","properties":{"service_type":{"description":"Optional: Muvon works it out from the places (airport or not). Send `hourly` (or just `hours`) for a car by the hour, with no `dropoff`.","type":"string","enum":["airport_pickup","airport_dropoff","point_to_point","hourly"]},"pickup_at":{"description":"Pickup date and time in ISO 8601 with offset (Cancun is `-05:00`). At least 30 h from now, or more if the vehicle asks for it.","type":"string","format":"date-time"},"pickup":{"description":"Where the pickup is: `place_id`, or `address` + `lat` + `lng`.","properties":{"place_id":{"description":"Id of a place from `GET /places` (airport, hotel). The most precise option.","type":"string"},"address":{"description":"Address, when there's no `place_id`. Goes with `lat` and `lng`.","type":"string"},"lat":{"description":"Latitude of the address.","type":"number"},"lng":{"description":"Longitude of the address.","type":"number"}},"type":"object"},"dropoff":{"description":"Destination, same shape as `pickup`. Required except for `hourly`.","properties":{"place_id":{"description":"Id of a place from `GET /places` (airport, hotel). The most precise option.","type":"string"},"address":{"description":"Address, when there's no `place_id`. Goes with `lat` and `lng`.","type":"string"},"lat":{"description":"Latitude of the address.","type":"number"},"lng":{"description":"Longitude of the address.","type":"number"}},"type":"object"},"hours":{"description":"Only for `hourly`: 1 to 12.","type":"integer"},"passengers":{"description":"How many people travel.","properties":{"adults":{"description":"Adults, at least 1.","type":"integer"},"children":{"description":"Children. They count toward the vehicle's capacity.","type":"integer"}},"required":["adults"],"type":"object"},"bags":{"description":"Bags. Can't exceed the vehicle's maximum.","type":"integer"},"language":{"description":"Language of the vehicle and extra names in the response. `en` by default.","type":"string","enum":["es","en"]},"vehicle_type_id":{"description":"Optional: quote only that vehicle type. Without it you get every type that fits.","type":"string"},"extras":{"description":"Extras from `GET /extras`.","items":{"type":"object","properties":{"code":{"description":"Extra code.","type":"string"},"quantity":{"description":"Quantity, 1 by default.","type":"integer"}},"required":["code"]},"type":"array"}},"required":["pickup_at","pickup","passengers"]},"Quote":{"type":"object","properties":{"id":{"description":"Quote id (`qt_…`). You send it when booking.","type":"string"},"object":{"description":"Always `quote`.","type":"string","enum":["quote"]},"livemode":{"description":"`true` with a live key, `false` with a test key.","type":"boolean"},"expires_at":{"description":"Until when this quote can be booked.","type":"string","format":"date-time"},"currency":{"description":"Always `USD` in v1.","type":"string","enum":["USD"]},"request":{"description":"What you asked for, normalized (place names, date with offset).","properties":{},"type":"object"},"options":{"description":"One option per vehicle type that fits; always at least one. When none fits, the quote answers a 422 error (`passengers_out_of_range`, `too_many_bags`, `notice_too_short` or `route_not_priceable`).","items":{"type":"object","properties":{"vehicle_type_id":{"description":"Vehicle type. You send it when booking.","type":"string"},"name":{"description":"Vehicle type name.","type":"string"},"max_passengers":{"description":"Passenger capacity.","type":"integer"},"max_bags":{"description":"Bag capacity.","type":"integer"},"price_cents":{"description":"Total public price in US cents, extras included. What your customer pays.","type":"integer"},"commission_cents":{"description":"Your commission in cents, per your agreement with Muvon.","type":"integer"},"km":{"description":"Trip distance in km (`null` for `hourly`).","type":["number","null"]}},"required":["vehicle_type_id","name","max_passengers","max_bags","price_cents","commission_cents"]},"type":"array"}},"required":["id","object","livemode","expires_at","currency","request","options"],"description":"A server-priced quote. Book one of its options before expires_at.","example":{"id":"qt_8f3a1c9e2b7d4f60","object":"quote","livemode":false,"expires_at":"2026-11-14T18:40:00-05:00","currency":"USD","request":{"service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1}]},"options":[{"vehicle_type_id":"vt_sedan","name":"Sedan / SUV / Tesla","max_passengers":3,"max_bags":3,"price_cents":9500,"commission_cents":950,"km":54.2},{"vehicle_type_id":"vt_van","name":"Van","max_passengers":12,"max_bags":12,"price_cents":13000,"commission_cents":1300,"km":54.2}]}},"BookingRequest":{"type":"object","properties":{"quote_id":{"description":"Unexpired quote from `POST /quotes`. Each quote books once.","type":"string"},"vehicle_type_id":{"description":"One of the quote's `options`.","type":"string"},"passenger":{"description":"Who travels. Muvon contacts this email and phone about the ride.","properties":{"first_name":{"description":"First name.","type":"string"},"last_name":{"description":"Last name.","type":"string"},"email":{"description":"Email.","type":"string","format":"email"},"phone":{"description":"Phone with country code, like `+15551234567`.","type":"string"},"language":{"description":"Passenger's language, also used on the payment page. `en` by default.","type":"string","enum":["es","en"]}},"required":["first_name","last_name","email","phone"],"type":"object"},"flight_number":{"description":"Flight. Always ask for it on airport arrivals: the pilot follows delays with it.","type":"string"},"room":{"description":"Room or villa, if any.","type":"string"},"notes":{"description":"Notes for the Muvon team.","type":"string"},"external_ref":{"description":"Your own reference (order, cart). Comes back on the booking and in webhooks.","type":"string"},"return_url":{"description":"Optional, `https`. Where your customer goes after paying.","type":"string","format":"uri"}},"required":["quote_id","vehicle_type_id","passenger"]},"Booking":{"type":"object","properties":{"id":{"description":"Booking id.","type":"string"},"object":{"description":"Always `booking`.","type":"string","enum":["booking"]},"kind":{"description":"Product. Always `transfer` in v1; Muvon rentals will come with their own value.","type":"string","enum":["transfer"]},"code":{"description":"Code the customer sees: `MVN-000123` in live, `TEST-000001` in test. Works as `ref` in paths.","type":"string"},"livemode":{"description":"`false` for test bookings.","type":"boolean"},"status":{"description":"Ride status. See Booking lifecycle.","type":"string","enum":["new","assigned","confirmed","on_the_way","arrived","on_board","dropped_off","completed","no_show","cancelled"]},"payment_status":{"description":"`unpaid` or `paid`. `refunded` once the team records a refund.","type":"string"},"payment_url":{"description":"Payment link for your customer. See Payment link.","type":["string","null"],"format":"uri"},"hold_expires_at":{"description":"Cancelled automatically if not paid by then. If your customer opens the payment near the end, it can stretch by up to 35 minutes so they can finish paying. `null` once paid or cancelled.","type":["string","null"],"format":"date-time"},"external_ref":{"description":"Your reference.","type":["string","null"]},"service_type":{"description":"Service type.","type":"string","enum":["airport_pickup","airport_dropoff","point_to_point","hourly"]},"pickup_at":{"description":"Pickup, with Cancun's offset.","type":"string","format":"date-time"},"pickup":{"description":"Origin.","properties":{"place_id":{"description":"Place id, or `null` when it was an address.","type":["string","null"]},"name":{"description":"Name the pilot sees.","type":"string"},"address":{"description":"Address, when given.","type":["string","null"]}},"type":"object"},"dropoff":{"description":"Destination (for `hourly` without one, the same as `pickup`).","properties":{"place_id":{"description":"Place id, or `null` when it was an address.","type":["string","null"]},"name":{"description":"Name the pilot sees.","type":"string"},"address":{"description":"Address, when given.","type":["string","null"]}},"type":["object","null"]},"hours":{"description":"Hours, only for `hourly`.","type":["integer","null"]},"vehicle_type_id":{"description":"Booked vehicle type.","type":"string"},"passengers":{"description":"Passengers.","properties":{"adults":{"description":"Adults.","type":"integer"},"children":{"description":"Children.","type":"integer"}},"required":["adults","children"],"type":"object"},"bags":{"description":"Bags.","type":"integer"},"extras":{"description":"Booked extras.","items":{"type":"object","properties":{"code":{"description":"Code.","type":"string"},"quantity":{"description":"Quantity.","type":"integer"},"price_cents":{"description":"Unit price in cents (the line costs price × quantity).","type":"integer"}},"required":["code","quantity","price_cents"]},"type":"array"},"flight_number":{"description":"Flight.","type":["string","null"]},"room":{"description":"Room.","type":["string","null"]},"notes":{"description":"Your notes.","type":["string","null"]},"passenger":{"description":"Who travels.","properties":{"first_name":{"description":"First name.","type":"string"},"last_name":{"description":"Last name.","type":"string"},"email":{"description":"Email.","type":"string","format":"email"},"phone":{"description":"Phone.","type":["string","null"]},"language":{"description":"Language.","type":"string","enum":["es","en"]}},"required":["first_name","last_name","email","language"],"type":"object"},"price_cents":{"description":"Total public price in cents.","type":"integer"},"currency":{"description":"`USD`.","type":"string","enum":["USD"]},"commission_cents":{"description":"Your commission in cents.","type":"integer"},"tracking_url":{"description":"Ride page for the passenger: status, pilot on the way, contact.","type":["string","null"],"format":"uri"},"cancel_reason":{"description":"Why it was cancelled. `payment_timeout` when the hold ran out unpaid.","type":["string","null"]},"created_at":{"description":"Created.","type":"string","format":"date-time"},"updated_at":{"description":"Last change.","type":"string","format":"date-time"}},"required":["id","object","kind","code","livemode","status","payment_status","service_type","pickup_at","vehicle_type_id","passengers","bags","extras","passenger","price_cents","currency","commission_cents","created_at","updated_at"],"description":"A booking. kind is transfer in v1.","example":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"unpaid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":"2026-11-14T20:10:00-05:00","external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:10:00-05:00"}},"CancelRequest":{"type":"object","properties":{"reason":{"type":"string","description":"Reason, saved in cancel_reason."}}},"CancelledBooking":{"allOf":[{"$ref":"#/components/schemas/Booking"},{"type":"object","properties":{"refund":{"type":["string","null"],"enum":["manual",null],"description":"manual when the booking was paid: the Muvon team refunds it. The API never refunds."}}}]},"TestStatusRequest":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["assigned","confirmed","on_the_way","arrived","on_board","dropped_off","completed","no_show","cancelled"]}}},"Event":{"type":"object","properties":{"id":{"description":"Event id (`evt_…`). Use it to avoid processing the same one twice.","type":"string"},"object":{"description":"Always `event`.","type":"string","enum":["event"]},"type":{"description":"What happened. See Webhooks.","type":"string","enum":["booking.created","booking.paid","booking.assigned","booking.confirmed","booking.on_the_way","booking.arrived","booking.on_board","booking.dropped_off","booking.completed","booking.no_show","booking.cancelled","ping"]},"created":{"description":"When it happened.","type":"string","format":"date-time"},"livemode":{"description":"Booking mode.","type":"boolean"},"data":{"description":"Event content.","properties":{"object":{"description":"The full booking as it was after the change. On `ping` it is `{ \"object\": \"ping\", \"message\": \"…\" }`.","properties":{},"type":"object"}},"type":"object"}},"required":["id","object","type","created","livemode","data"],"description":"Sent by webhook (signed with Muvon-Signature) and listed by GET /events.","example":{"id":"evt_0a9b8c7d6e5f4a3b","object":"event","type":"booking.paid","created":"2026-11-14T18:22:41-05:00","livemode":false,"data":{"object":{"id":"bk_5d2e8a41c07f4b9e","object":"booking","kind":"transfer","code":"TEST-000001","livemode":false,"status":"new","payment_status":"paid","payment_url":"https://api.muvon.mx/pay/r/3c9f0b7e6a5d4c2b1a09f8e7d6c5b4a3","hold_expires_at":null,"external_ref":"ORDER-5521","service_type":"airport_pickup","pickup_at":"2026-12-20T14:30:00-05:00","pickup":{"place_id":"pl_cun","name":"Cancun Airport (CUN)","address":null},"dropoff":{"place_id":"pl_hotel52","name":"Hotel 52 Playa del Carmen","address":null},"hours":null,"vehicle_type_id":"vt_sedan","passengers":{"adults":2,"children":1},"bags":3,"extras":[{"code":"BOOSTER_SEAT","quantity":1,"price_cents":1000}],"flight_number":"AA1234","room":null,"notes":"Viajamos con una carriola","passenger":{"first_name":"Ana","last_name":"García","email":"ana@example.com","phone":"+5215512345678","language":"es"},"price_cents":9500,"currency":"USD","commission_cents":950,"tracking_url":"https://api.muvon.mx/track?t=a1b2c3d4e5f6","cancel_reason":null,"created_at":"2026-11-14T18:10:00-05:00","updated_at":"2026-11-14T18:22:41-05:00"}}}},"VehicleType":{"type":"object","properties":{"id":{"description":"Vehicle type id.","type":"string"},"object":{"description":"Always `vehicle_type`.","type":"string","enum":["vehicle_type"]},"name_es":{"description":"Spanish name.","type":"string"},"name_en":{"description":"English name.","type":"string"},"min_passengers":{"description":"Offered from this many passengers.","type":"integer"},"max_passengers":{"description":"Passenger capacity.","type":"integer"},"max_bags":{"description":"Bag capacity.","type":"integer"},"min_notice_hours":{"description":"Minimum notice in hours (never under 30).","type":"integer"}},"required":["id","object","name_es","name_en","min_passengers","max_passengers","max_bags","min_notice_hours"]},"Place":{"type":"object","properties":{"id":{"description":"Place id. Goes in `pickup.place_id` and `dropoff.place_id`.","type":"string"},"object":{"description":"Always `place`.","type":"string","enum":["place"]},"name":{"description":"Name.","type":"string"},"kind":{"description":"Place kind.","type":"string","enum":["airport","port","hotel","residence","other"]},"iata_code":{"description":"IATA code for airports.","type":["string","null"]},"address":{"description":"Address.","type":["string","null"]},"lat":{"description":"Latitude.","type":["number","null"]},"lng":{"description":"Longitude.","type":["number","null"]}},"required":["id","object","name","kind"]},"Extra":{"type":"object","properties":{"code":{"description":"Code. Goes in `extras[].code`.","type":"string"},"object":{"description":"Always `extra`.","type":"string","enum":["extra"]},"name_es":{"description":"Spanish name.","type":"string"},"name_en":{"description":"English name.","type":"string"},"price_cents":{"description":"Price per unit in cents.","type":"integer"},"currency":{"description":"`USD`.","type":"string","enum":["USD"]},"per_unit":{"description":"Whether it's charged per quantity.","type":"boolean"}},"required":["code","object","name_es","name_en","price_cents","currency"]},"Ping":{"type":"object","required":["object","livemode","partner"],"properties":{"object":{"type":"string","enum":["ping"]},"livemode":{"type":"boolean"},"partner":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}}}},"Error":{"type":"object","properties":{"error":{"description":"The error.","properties":{"type":{"description":"Error family.","type":"string","enum":["invalid_request_error","authentication_error","permission_error","rate_limit_error","idempotency_error","api_error"]},"code":{"description":"Exact code. Code against this value.","type":"string"},"message":{"description":"Explanation for developers. Don't show it to your customer as is.","type":"string"},"param":{"description":"Field that caused the error, if any.","type":["string","null"]},"request_id":{"description":"Request id (`req_…`). Share it with support.","type":"string"}},"required":["type","code","message","request_id"],"type":"object"}},"required":["error"],"description":"Error envelope. Codes: parameter_missing, parameter_invalid, invalid_json, body_missing, idempotency_key_invalid, place_not_found, vehicle_type_not_found, quote_invalid, idempotency_key_required, missing_api_key, invalid_api_key, test_mode_only, resource_missing, quote_expired, quote_used, cancel_window_closed, booking_not_payable, booking_not_cancellable, invalid_status_transition, idempotency_conflict, notice_too_short, same_origin_destination, route_too_long, route_not_priceable, passengers_out_of_range, too_many_bags, hours_out_of_range, extra_unavailable, option_unavailable, body_too_large, rate_limited, internal_error, not_configured, pricing_unavailable.","example":{"error":{"type":"invalid_request_error","code":"notice_too_short","message":"pickup_at must be at least 30 hours from now","param":"pickup_at","request_id":"req_7e1f0c2a9b8d4e3f"}}}}},"webhooks":{"event":{"post":{"summary":"Booking event","description":"POSTed to your webhook URL for the key's mode. Header Muvon-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, t + '.' + rawBody)>. Answer 2xx within 10 s; failures are retried after 1m, 5m, 30m, 2h, 6h, 12h and 24h.","parameters":[{"name":"Muvon-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}}}}