Multi-channel hotel distribution platform. Manage properties, sync availability, and control pricing across booking channels from a single API.
Create, update, and manage hotel properties with subscription tracking and admin settings.
Distribute rates and availability across multiple booking channels from a single source of truth.
Separate Consumer and Admin keys, plus per-hotel credentials on every PMS endpoint. A leaked PMS key alone cannot reach any hotel without its user/parola.
Search and manage reservations across all channels with filtering by date, status, and guest details.
Connect to property management systems with room, rate, and child category mapping and reporting.
Debug logs, slow query tracking, channel update history, and PMS request inspection in one place.
Proxy guest reviews and post property replies via Booking.com’s review API with automatic JWT refresh.
Fetch property score summaries and category breakdowns from Booking.com’s property-scores API.
Copy the snippet below and paste it into your AI agent's system prompt or tool configuration.
# CMStart API — AI Integration Guide
## Base URL
https://cmstartapi01.azurewebsites.net
## Authentication
Two API keys, scoped by tier. Each tier-tagged endpoint requires its matching key in the `X-Api-Key` header.
X-Api-Key: <consumer-or-admin-key>
**Consumer key** unlocks `POST /api/hotels/add`, `GET /api/channels`, the `/api/hotelchannels/*` routes, and every `/api/pms/*` route. Every `/api/pms/*` request must additionally carry per-hotel credentials:
X-Hotel-Id: 110
X-Hotel-User: hotel_username
X-Hotel-Password: hotel_plaintext_password
The triple is validated server-side against the hotel’s stored credentials. If the route URL includes a `{hotelId}` segment it must equal `X-Hotel-Id`.
**Admin key** unlocks everything else under `/api/*` — hotels list/get/edit/extend, settings, logs, reservations, bookingreviews, bookingscores.
Open paths (no key required): `/health`, `/version`.
Wrong tier, missing key, or invalid hotel credentials → `401 Unauthorized`.
## Endpoints
### Hotels
GET /api/hotels/ # [Admin] List hotels (?showExpired=true)
GET /api/hotels/{hotelId} # [Admin] Get hotel details
POST /api/hotels/add # [Consumer] Create a hotel (no hotel-creds required)
PUT /api/hotels/{hotelId} # [Admin] Update a hotel
PATCH /api/hotels/{hotelId}/extend # [Admin] Extend subscription
### Channels — [Consumer]
GET /api/channels/ # List all channels
### Hotel Channels — [Consumer]
GET /api/hotelchannels/ # List hotel-channel connections
GET /api/hotelchannels/{id} # Get connection details
POST /api/hotelchannels/add # Create a connection
PUT /api/hotelchannels/{id} # Update a connection
PATCH /api/hotelchannels/{id}/toggle # Toggle autorizat | sincronizat_camere | ignora_pms_preturi
Read responses include per-binding currency fields: `monedaCanal`, `cursSchimb`,
`rotunjire`, `ignoraPmsPreturi`. `ignora_pms_preturi` freezes outbound prices when set.
### Settings — [Admin]
GET /api/settings/{camp} # Get a setting by key
### Logs — [Admin]
GET /api/logs/debug # List debug logs
DELETE /api/logs/debug # Clear debug logs
GET /api/logs/slow-queries # List slow queries
DELETE /api/logs/slow-queries # Clear slow queries
GET /api/logs/actions # List action logs
GET /api/logs/channel-updates # List channel update logs
GET /api/logs/pms-requests # List PMS request logs
GET /api/logs/pms-requests/room-mappings # Get room mappings
GET /api/logs/pms-requests/{logId} # Get PMS request detail
### Reservations — [Admin]
GET /api/reservations/ # Search reservations
### PMS — all routes are [Consumer] and require hotel-creds headers
GET /api/pms/reports # PMS reports
GET /api/pms/connections # List PMS connections
POST /api/pms/connections/setup # Set up a new connection
POST /api/pms/connections/{id}/authorize # Authorize a connection
GET /api/pms/connections/{id}/channel-rooms # Live channel rooms + rate plans (mapped/unmapped), no writes
GET /api/pms/connections/{id}/rooms # List room mappings
POST /api/pms/connections/{id}/rooms # Save room mappings
GET /api/pms/connections/{id}/rates # List rate mappings
POST /api/pms/connections/{id}/rates # Save rate mappings
GET /api/pms/connections/{id}/childcategories # List child categories
POST /api/pms/connections/{id}/childcategories # Save child categories
POST /api/pms/init # Seed PMS catalog (rooms, rate plans, child categories) for a hotel
POST /api/pms/prices # Push daily prices (+ valoriCopii/valoriPS optional)
GET /api/pms/prices?hotelId=&from=&to=&canalId= # Read prices: hotel-level, or per-channel post-conversion when canalId set
POST /api/pms/restrictions # Push per-channel restrictions (closed, min/max stay, etc.)
GET /api/pms/restrictions?hotelId=&canalId=&from=&to= # Pending (un-pushed) restrictions
POST /api/pms/availability # Push availability counts (global or per-channel)
GET /api/pms/availability?hotelId=&canalId=&from=&to= # Read current availability
`POST /api/pms/init` is the JSON port of legacy `pms/ms/init.php`. Body shape:
{
"hotelId": 110,
"vanzarePerCamera": false,
"rooms": [
{ "pmsId": "DBL", "name": "Dubla", "maxCamere": 5, "maxOcupare": 2,
"rates": [ { "pmsId": "BB", "name": "Bed and breakfast" } ] }
],
"categoriiCopii": []
}
Wraps every write in one MySQL transaction. Upserts `camere`, `camere_variante_pret`, and
`categorii_copii` keyed on `(hotel_id, pms_id)`. Cascade-deletes channel mappings for
removed cameras. Cameras / rate plans referenced by `rezervari` are renamed to
`[DELETED] {original} #{id}` instead of hard-deleted, so reservation history is preserved.
### PMS Tariff Optimizer — [Consumer], hotel-creds required, route `{hotelId}` must equal `X-Hotel-Id`
GET /api/pms/optimizator/{hotelId} # Read tariff-optimizer config (defaults if unset)
PUT /api/pms/optimizator/{hotelId} # Save tipOcupare, rotunjire, reguli[]
POST /api/pms/optimizator/{hotelId}/toggle # Flip activ
POST /api/pms/optimizator/{hotelId}/reset # Restore default rules
Config persists in `hoteluri.setari_admin.optimizator_tarif` (JSON sub-key).
Rule validation: `min >= 0`, `max > min`, `max <= 100`, `-50 <= extra <= 200`.
### Booking Reviews — [Admin]
GET /api/bookingreviews/ # List reviews (?propertyId=&hotelId=&canalId=&page=&pageSize=)
GET /api/bookingreviews/{reviewId} # Get single review by ID (?propertyId=&hotelId=&canalId=)
POST /api/bookingreviews/{reviewId}/reply # Post property reply (?propertyId=&hotelId=&canalId=)
GET /api/bookingreviews/score # Review-only score for property (?propertyId=&hotelId=&canalId=)
Pass-through to `supply-xml.booking.com/review-api`. Reviews must not be republished publicly per Booking's terms.
### Booking Property Scores — [Admin]
GET /api/bookingscores/ # Summary for multiple properties (paginated, ?hotelId=&canalId=&page=&pageSize=)
GET /api/bookingscores/{propertyId} # Per-property score breakdown (?hotelId=&canalId=)
Pass-through to `supply-xml.booking.com/property-scores`.
Both review and score endpoints resolve the Booking `propertyId` from `hotel_id_canal` automatically when
`?hotelId=&canalId=` are supplied. The JWT is injected from `setari.booking_token`; a 401 triggers one
automatic token refresh before bubbling up as `502 Bad Gateway`.
### Booking Promotions — [Consumer]
GET /api/pms/connections/{id}/promotions # Live list (auto-aggregated)
GET /api/pms/connections/{id}/promotion-types # Capabilities (per-channel discount ranges, campaign windows)
GET /api/pms/connections/{id}/promotions/{promoId} # Single promotion
POST /api/pms/connections/{id}/promotions # Create (no id) / update (id in body)
POST /api/pms/connections/{id}/promotions/{promoId}/activate # Reactivate
DELETE /api/pms/connections/{id}/promotions/{promoId} # Deactivate (soft)
Thin 1:1 Booking Supply-XML adapter. Ownership + Booking-only (`canal_id=6`) enforced server-side; the
Booking `propertyId` is resolved from `hotel_id_canal` (never a client param). Responses mirror Booking's
shape (camelCase), no normalization. Booking content faults surface as `{ faults:[{code,message}] }` (422);
gate failures return `{ error, code }`.
### Health & Version (no auth required)
GET /health
# { "status": "healthy", "database": "connected" }
GET /version
# { "version": "0.5.0", "sha": "abc1234", "branch": "master", "buildTime": "2026-05-25T..." }
## Important Notes
- Always call `/health` first to confirm connectivity before multi-step workflows.
- The `expira` field in responses is a **Unix timestamp** (seconds).
When creating or extending, send a date string like `"2027-01-01"`.
- HTTP status codes: 200 success, 201 created, 401 unauthorized, 404 not found, 500 server error.
/version reports the build’s commit and branch on every host./scalar, /openapi) is no longer served publicly.POST /api/pms/prices now reach the correct 4booking rate plans.warnings reasons on 4booking extras: extras_no_ob_plan and extras_non_numeric_id.GET /api/pms/connections/{id}/channel-rooms: the channel’s rooms and rate plans, read live, for room mapping.POST /api/pms/connections/{id}/rooms accepts the rate plans of each room (concepte).POST /api/pms/restrictions no longer fails on some channel mappings.GET and PUT /api/pms/connections/{id} to read and edit a channel connection.POST /api/pms/init removes child categories the PMS no longer sends and reports them in removedCategoriiCopiiIds.hnextConfig on POST /api/hotels/add and PUT /api/hotels/{id} to set a hotel’s HNext credentials.