Common workflows
Each sequence below is the shortest correct path. Endpoint details are in the API reference.
Check whether a property is free
curl -X POST 'https://core.mtro.app/bookings/public/check-availability' \
-H 'Authorization: Bearer mtro_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"propertyId":"<propertyId>","startDate":1790000000000,"endDate":1792592000000}'
Dates are millisecond timestamps. endDate is checkout and is exclusive: a stay
may start on the same calendar day another one ends.
Availability accounts for confirmed bookings, explicit date blocks, and synced external calendars such as Airbnb. Prospective bookings do not block.
Take in a new enquiry
-
Read the pipeline stages. Stage ids are per-organization, so never hardcode them.
curl 'https://core.mtro.app/pipeline-stages/get/entity/<entityId>' \
-H 'Authorization: Bearer mtro_your_api_key' -
Create the lead.
tenantNameis the only required field. Note the field names — they are notname/email/phone.curl -X POST 'https://core.mtro.app/webhooks/create-lead' \
-H 'Authorization: Bearer mtro_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"tenantName": "Jordan Ellis",
"emailAddress": "[email protected]",
"phoneNumber": "+14695550123",
"service": "Manual",
"destination": "Dallas, TX",
"numberOfTravelers": 4,
"stageId": "<stageId>"
}' -
Move it along the funnel as it progresses:
curl -X POST 'https://core.mtro.app/webhooks/update-stage' \
-H 'Authorization: Bearer mtro_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"leadId":"<leadId>","stageId":"<nextStageId>"}'
Scopes: leads.read to list stages and leads, leads.write to create and move.
Turn a lead into a booking
POST /bookings/create needs propertyId, startDate, and endDate. The
primary guest is identified by email, not by guest id: Core matches an
existing guest on that address or creates one from the name fields.
curl -X POST 'https://core.mtro.app/bookings/create' \
-H 'Authorization: Bearer mtro_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"propertyId": "<propertyId>",
"startDate": 1790000000000,
"endDate": 1792592000000,
"guestEmail": "[email protected]",
"guestName": "Jordan",
"guestSurname": "Ellis",
"rate": 120,
"status": "pending",
"leadId": "<leadId>"
}'
Pass leadId so the booking stays linked to the enquiry it came from.
Message a guest
-
Find the conversation —
POST /conversations/getlists them, andGET /conversations/get/entity/:entityIdreturns the thread for a booking when you passentityType=booking. -
Send:
curl -X POST 'https://core.mtro.app/conversations/send-message' \
-H 'Authorization: Bearer mtro_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"conversationId":"<conversationId>","message":"Your keys are in the lockbox."}'
This sends a real message over SMS, email, or in-app depending on the
conversation. There is no dry run. Test on https://dev.core.mtro.app.
Scopes: conversations.read and conversations.write.
Schedule maintenance
-
Read the vendors:
GET /vendors/get/all. -
Create the task:
curl -X POST 'https://core.mtro.app/tasks/create' \
-H 'Authorization: Bearer mtro_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"propertyId": "<propertyId>",
"vendorId": "<vendorId>",
"date": 1790000000000,
"notes": "Turnover clean between stays",
"status": "pending"
}'
Scopes: vendors.read and tasks.write.
Notice what changed
There are no outbound webhooks, so polling is the only option. A workable shape:
| Resource | Endpoint | Suggested interval |
|---|---|---|
| Conversations | POST /conversations/get | every 2–5 minutes |
| Leads | GET /webhooks/get/all | every 5 minutes |
| Bookings | GET /bookings/get/all | every 15 minutes |
| Properties, vendors | GET /properties/get/all, GET /vendors/get/all | hourly or on demand |
POST /conversations/get accepts page and limit in the body and reports
total, so poll the first page and only walk further when the count moves. The
others return the full set on every call, so cache what you read and compare
against it rather than re-reading in a loop.