REST API for property management software (PMS) and partner integrations. Push listings, pull leads, exchange messages, and receive real-time webhook events.
All requests require an x-api-key header. Keys are scoped to a single operator account.
curl -H "x-api-key: bmc_your_api_key_here" \ https://bookmycoliving.com/api/v1/leads
https://bookmycoliving.com/api/v1
List endpoints return a { data, pagination } envelope. Single-resource endpoints return the resource directly.
{
"data": [ ... ],
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}Every authenticated response carries:
X-RateLimit-Limit, your hourly budget for this endpointX-RateLimit-Remaining, calls left in the current windowX-RateLimit-Reset, epoch seconds when the window resetsPass Idempotency-Key on writes. We cache the first response for 24h and replay it on retries, even after a 5xx or timeout you can safely retry without creating duplicates. Replayed responses include Idempotent-Replayed: true.
curl -X POST https://bookmycoliving.com/api/v1/properties \
-H "x-api-key: bmc_..." \
-H "Idempotency-Key: 8b1f...-uuid-..." \
-H "Content-Type: application/json" \
-d '{ ... }'Pass an externalId in the property body and we'll record it alongside our own id. On POST /properties, if the same externalId already exists for your operator account, we return the existing record (HTTP 200 + { reused: true }) instead of creating a duplicate. Filter list endpoints with ?externalId=.
/propertiesList all properties owned by the authenticated operator.
Query: page, limit (max 100)
/propertiesCreate a new property. Lands as PENDING_REVIEW for admin moderation.
curl -X POST https://bookmycoliving.com/api/v1/properties \
-H "x-api-key: bmc_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Sunny Coliving",
"description": "...",
"cityId": "<from /api/v1/cities>",
"address": "123 Main St",
"amenities": ["wifi", "gym"],
"contactEmail": "host@example.com",
"colivingTypeIds": ["<from /api/v1/coliving-types>"],
"roomOptions": [
{ "type": "PRIVATE", "priceMonthly": 80000 }
]
}'Note: priceMonthly is in USD cents (e.g. $800.00 β 80000).
/properties/:idGet a single property by ID.
/properties/:idReplace a property's details. APPROVED listings stay live but get flagged for re-review.
/properties/:idPermanently delete a property and all its data.
/properties/:id/submitSubmit a DRAFT or REJECTED property for admin review.
/properties/:id/unpublishMove an APPROVED property back to DRAFT (off the public site).
/properties/:id/photosAppend photos to an existing property.
{ "photos": [{ "url": "https://..." }, { "url": "https://..." }] }/leadsList all leads for properties owned by the authenticated operator.
Query: page, limit, propertyId, since (ISO 8601)
curl -H "x-api-key: bmc_..." \ "https://bookmycoliving.com/api/v1/leads?since=2026-04-01T00:00:00Z"
/leads/:idGet a single lead. Operator must own the linked property.
/messagesList all conversations the authenticated operator is part of.
Query: propertyId, dateFrom, dateTo
/messages/:threadIdGet all messages in a single conversation. threadId is the partner user ID.
/messages/:threadIdReply to a conversation.
{ "content": "Thanks for your interest!", "propertyId": "..." }Capped at 5,000 characters per message and 60 messages per hour per API key.
These endpoints return canonical IDs and slugs. Cache responses for at least 1 hour.
/citiesAll active cities. Use the returned `id` as `cityId` when creating a property.
/coliving-typesAll community types. Use returned `id` values in `colivingTypeIds`.
/amenitiesCanonical amenity slugs (e.g. `wifi`, `gym`, `coworking`). Use these in the `amenities` array.
Set a webhook URL in Dashboard Settings to receive real-time events. Events are POSTed as JSON.
lead.created, new tenant enquiry on one of your propertiesmessage.received, a tenant or admin sent you a messageproperty.created, property created (typically by your own integration)property.updated, property details changedproperty.approved, admin approved your listing, it's now liveproperty.rejected, admin rejected your listing (check adminNotes)property.deleted, property removedPOST <your-webhook-url>
Content-Type: application/json
X-BMC-Event: lead.created
X-BMC-Timestamp: 2026-04-25T10:00:00.000Z
X-BMC-Signature: <hmac-sha256(`${timestamp}.${body}`, your-webhook-secret)>
User-Agent: BookMyColiving-Webhook/1.0
{
"event": "lead.created",
"timestamp": "2026-04-25T10:00:00.000Z",
"data": {
"id": "lead_abc",
"propertyId": "prop_xyz",
"guestName": "Jane Smith",
"guestEmail": "jane@example.com",
...
}
}Each delivery is signed with HMAC-SHA256 over `${timestamp}.${rawBody}` using your webhook secret (separate from your API key, generate it in dashboard settings). Including the timestamp in the signed material defeats replay attacks. Verify on your end:
// Node.js example
const crypto = require("crypto");
function verifyWebhook(rawBody, headers, webhookSecret) {
const sig = headers["x-bmc-signature"];
const ts = headers["x-bmc-timestamp"];
// Reject events older than 5 minutes, protects against replay
if (Math.abs(Date.now() - Date.parse(ts)) > 5 * 60_000) return false;
const expected = crypto
.createHmac("sha256", webhookSecret)
.update(`${ts}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(sig),
);
}We deliver fire-and-forget, failed deliveries are not retried. Use POST /webhooks/test below to validate your receiver before going live.
/webhooks/testFires a synthetic event at your configured webhook URL. Body: { event?: 'lead.created' | ... }. Useful for verifying signature handling.
curl -X POST https://bookmycoliving.com/api/v1/webhooks/test \
-H "x-api-key: bmc_..." \
-H "Content-Type: application/json" \
-d '{ "event": "lead.created" }'Errors return a JSON body: { "error": "Human-readable message" }
| Status | Meaning |
|---|---|
400 | Bad request, body validation failed |
401 | Missing or invalid API key |
403 | API key doesn't own this resource |
404 | Resource not found |
409 | Conflict (e.g. duplicate slug) |
429 | Rate limit exceeded |
500 | Server error, safe to retry |
/cities, /coliving-types, /amenities), 5,000 per hourPOST /messages/:threadId), 60 per hour per API keyRead your remaining budget from the X-RateLimit-* response headers. Exceeded limits return 429. Cache reference data to avoid unnecessary calls.
The API is versioned via the URL path (/api/v1/). We commit to at least 6 months notice before deprecating any endpoint, and breaking changes only happen in new major versions.
Email us at mayank@everythingcoliving.com with your operator account email and a description of your integration. Or schedule a call.