{"openapi":"3.1.0","info":{"version":"1.0.0","contact":{"name":"Aloaha Limited"},"title":"Guest Portal — Platform API","description":"Superadmin operations: tenants, domains, superadmins, platform settings. Authenticate with `Authorization: Bearer gpp_…` (platform keys) or a superadmin session."},"servers":[{"url":"https://guestbud.io"}],"tags":[{"name":"Platform"}],"paths":{"/api/platform/v1/me":{"get":{"tags":["Platform"],"summary":"Current superadmin / platform key","operationId":"get__api_platform_v1_me","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tenants":{"get":{"tags":["Platform"],"summary":"All tenants with counts, domains and owner","operationId":"get__api_platform_v1_tenants","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"post":{"tags":["Platform"],"summary":"Quick-create a tenant (name → slug, owner login, optional domain). Returns a temporary password once.","operationId":"post__api_platform_v1_tenants","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreate"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tenants/{id}":{"get":{"tags":["Platform"],"summary":"One tenant","operationId":"get__api_platform_v1_tenants_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"patch":{"tags":["Platform"],"summary":"Rename, suspend/resume, approve a signup","operationId":"patch__api_platform_v1_tenants_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantPatch"}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"delete":{"tags":["Platform"],"summary":"Delete a tenant (archived to <data>/deleted, all domains/links stop working). Body {confirm:\"<slug>\"}","operationId":"delete__api_platform_v1_tenants_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDelete"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tenants/{id}/domains":{"post":{"tags":["Platform"],"summary":"Connect a custom domain (optionally pinned to one property)","operationId":"post__api_platform_v1_tenants_id_domains","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainInput"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tenants/{id}/domains/{domain}":{"delete":{"tags":["Platform"],"summary":"Disconnect a domain","operationId":"delete__api_platform_v1_tenants_id_domains_domain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/certificates":{"get":{"tags":["Platform"],"summary":"Let's Encrypt certificate status of every tenant domain","operationId":"get__api_platform_v1_certificates","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/certificates/{domain}":{"post":{"tags":["Platform"],"summary":"Request / retry a Let's Encrypt certificate for a domain (processed by the SYSTEM worker task)","operationId":"post__api_platform_v1_certificates_domain","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/dns-check":{"get":{"tags":["Platform"],"summary":"Live DNS check: does a domain point at this platform?","operationId":"get__api_platform_v1_dns_check","parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tenants/{id}/support":{"post":{"tags":["Platform"],"summary":"Open the tenant backend as platform support (audited, owner rights)","operationId":"post__api_platform_v1_tenants_id_support","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tenants/{id}/owner-password":{"post":{"tags":["Platform"],"summary":"Reset the owner's password (temporary password returned once)","operationId":"post__api_platform_v1_tenants_id_owner_password","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/superadmins":{"get":{"tags":["Platform"],"summary":"Superadmins","operationId":"get__api_platform_v1_superadmins","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"post":{"tags":["Platform"],"summary":"Add a superadmin (temporary password returned once)","operationId":"post__api_platform_v1_superadmins","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserInput"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/superadmins/{id}":{"patch":{"tags":["Platform"],"summary":"Edit / disable a superadmin, or reset password","operationId":"patch__api_platform_v1_superadmins_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPatch"}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"delete":{"tags":["Platform"],"summary":"Remove a superadmin (never the last one)","operationId":"delete__api_platform_v1_superadmins_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/config":{"get":{"tags":["Platform"],"summary":"Platform settings (secrets masked)","operationId":"get__api_platform_v1_config","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"patch":{"tags":["Platform"],"summary":"Update platform settings","operationId":"patch__api_platform_v1_config","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformConfig"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/backup":{"get":{"tags":["Platform"],"summary":"Backup settings, last run and the stored backup files","operationId":"get__api_platform_v1_backup","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"patch":{"tags":["Platform"],"summary":"Update backup settings (password stored encrypted; enabled requires a password)","operationId":"patch__api_platform_v1_backup","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/backup/run":{"post":{"tags":["Platform"],"summary":"Create a backup now (and copy / email it as configured)","operationId":"post__api_platform_v1_backup_run","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/backup/files/{name}":{"get":{"tags":["Platform"],"summary":"Download an encrypted backup file","operationId":"get__api_platform_v1_backup_files_name","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/cluster":{"get":{"tags":["Platform"],"summary":"Cluster role, peer and replication status of this node","operationId":"get__api_platform_v1_cluster","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"patch":{"tags":["Platform"],"summary":"Configure replication to the passive peer (node-local: peer URL, shared secret, enabled)","operationId":"patch__api_platform_v1_cluster","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/cluster/secret":{"post":{"tags":["Platform"],"summary":"Generate a new shared secret (shown once — enter it on the passive node too)","operationId":"post__api_platform_v1_cluster_secret","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/cluster/test":{"post":{"tags":["Platform"],"summary":"Contact the peer and compare data (full reconcile)","operationId":"post__api_platform_v1_cluster_test","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/cluster/switchover":{"post":{"tags":["Platform"],"summary":"Planned switch-over: sync, promote the peer, then this node becomes passive","operationId":"post__api_platform_v1_cluster_switchover","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tax-rules":{"get":{"tags":["Platform"],"summary":"Platform tax definitions (usable by every tenant). Built-ins: \"zero\" and \"mt-eco\"","operationId":"get__api_platform_v1_tax_rules","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"post":{"tags":["Platform"],"summary":"Add a platform tax definition (e.g. a country-wide tax)","operationId":"post__api_platform_v1_tax_rules","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxRuleInput"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/tax-rules/{id}":{"patch":{"tags":["Platform"],"summary":"Edit a platform tax definition (built-ins too)","operationId":"patch__api_platform_v1_tax_rules_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxRuleInput"}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"delete":{"tags":["Platform"],"summary":"Delete a platform tax definition (not the built-ins, not while in use)","operationId":"delete__api_platform_v1_tax_rules_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/mail/test":{"post":{"tags":["Platform"],"summary":"Send a test email through the IIS pickup directory","operationId":"post__api_platform_v1_mail_test","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailTest"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/seo/submit":{"post":{"tags":["Platform"],"summary":"Submit all public URLs to IndexNow (and the sitemap to Google Search Console) now","operationId":"post__api_platform_v1_seo_submit","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/api-keys":{"get":{"tags":["Platform"],"summary":"Platform API keys (for provisioning integrations)","operationId":"get__api_platform_v1_api_keys","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"post":{"tags":["Platform"],"summary":"Create a platform API key — returned ONCE","operationId":"post__api_platform_v1_api_keys","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyInput"}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/api-keys/{id}":{"delete":{"tags":["Platform"],"summary":"Revoke a platform API key","operationId":"delete__api_platform_v1_api_keys_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/demo/reset":{"post":{"tags":["Platform"],"summary":"Reset the demo tenant to fresh sample data now","operationId":"post__api_platform_v1_demo_reset","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/enquiries":{"get":{"tags":["Platform"],"summary":"Contact-form enquiries (latest first)","operationId":"get__api_platform_v1_enquiries","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}},"/api/platform/v1/enquiries/{id}":{"patch":{"tags":["Platform"],"summary":"Mark an enquiry handled / add a note","operationId":"patch__api_platform_v1_enquiries_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnquiryPatch"}}}},"security":[{"platformKey":[]},{"superSession":[]}]},"delete":{"tags":["Platform"],"summary":"Delete an enquiry (GDPR)","operationId":"delete__api_platform_v1_enquiries_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"platformKey":[]},{"superSession":[]}]}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable message"}},"required":["error"]},"Guest":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"language":{"type":"string","examples":["en"]},"country":{"type":"string"}}},"BookingInput":{"type":"object","description":"Create (local calendar) or, with source + externalId, idempotently upsert a booking from another system.","properties":{"propertyId":{"type":"string","pattern":"^[a-z]_[a-z2-9]{10}$"},"checkIn":{"type":"string","format":"date","examples":["2026-11-18"]},"checkOut":{"type":"string","format":"date","examples":["2026-11-18"]},"checkInTime":{"type":"string","pattern":"^\\d{2}:\\d{2}$","examples":["15:00"]},"checkOutTime":{"type":"string","pattern":"^\\d{2}:\\d{2}$","examples":["15:00"]},"adults":{"type":"integer","minimum":0},"children":{"type":"integer","minimum":0,"description":"Guests under 18 (eco-tax exempt)"},"guest":{"$ref":"#/components/schemas/Guest"},"channelLabel":{"type":"string","examples":["Booking.com","Airbnb","Direct"]},"notes":{"type":"string"},"totalPrice":{"type":"number"},"noDeposit":{"type":"boolean"},"source":{"type":"string","description":"Integration id, e.g. \"codeb\". Omit for local bookings."},"externalId":{"type":"string","description":"Your booking id — makes POST an upsert"},"status":{"type":"string","enum":["confirmed","cancelled"]},"allowOverlap":{"type":"boolean","description":"Skip the double-booking check"},"sendPortalLink":{"type":"boolean","description":"Email the guest their portal link right away"}},"required":["propertyId","checkIn","checkOut"]},"Payment":{"type":"object","properties":{"status":{"type":"string","enum":["unpaid","pending","failed","paid","held","waived","released","partial"]},"amount":{"type":"number"},"orderId":{"type":"string"},"method":{"type":"string"},"paidAt":{"type":"string","format":"date-time"},"reason":{"type":"string"},"retained":{"type":"number"},"retainReason":{"type":"string"}}},"Booking":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]_[a-z2-9]{10}$"},"ref":{"type":"string","examples":["GP-7KX2MQ"]},"source":{"type":"string"},"externalId":{"type":["string","null"]},"status":{"type":"string","enum":["confirmed","cancelled"]},"channelLabel":{"type":"string"},"propertyId":{"type":"string","pattern":"^[a-z]_[a-z2-9]{10}$"},"propertyName":{"type":"string"},"licence":{"type":"string","description":"MTA licence"},"checkIn":{"type":"string","format":"date","examples":["2026-11-18"]},"checkOut":{"type":"string","format":"date","examples":["2026-11-18"]},"checkInTime":{"type":"string","pattern":"^\\d{2}:\\d{2}$","examples":["15:00"]},"checkOutTime":{"type":"string","pattern":"^\\d{2}:\\d{2}$","examples":["15:00"]},"nights":{"type":"integer"},"adults":{"type":"integer"},"children":{"type":"integer"},"guest":{"$ref":"#/components/schemas/Guest"},"stayState":{"type":"string","enum":["awaiting","ready","inhouse","completed","cancelled"]},"unlocked":{"type":"boolean","description":"Portal unlocked (all steps done)"},"checkinDone":{"type":"boolean"},"steps":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["details","eco","deposit"]},"done":{"type":"boolean"},"amount":{"type":["number","null"]},"status":{"type":"string"}}}},"eco":{"$ref":"#/components/schemas/Payment"},"deposit":{"$ref":"#/components/schemas/Payment"},"portalUrl":{"type":"string","format":"uri"},"checkin":{"type":["object","null"],"description":"Detail view only: lead guest, ID document, co-travellers, ETA, files"},"log":{"type":"array","description":"Detail view only: activity timeline"}}},"PropertyInput":{"type":"object","properties":{"name":{"type":"string"},"area":{"type":"string"},"country":{"type":"string","examples":["MT"]},"timezone":{"type":"string","examples":["Europe/Malta"]},"taxRule":{"type":"string","description":"'auto' (country default), 'none', or a tax-rule id from GET /api/v1/tax-rules"},"requireCheckinForm":{"type":["boolean","null"]},"meldeschein":{"type":"string","enum":["auto","yes","no"],"description":"German guest registration: auto = DE properties, non-German guests"},"lock":{"type":["object","null"],"properties":{"type":{"type":"string","enum":["nuki"]},"smartlockId":{"type":"string"},"label":{"type":"string"},"after":{"type":"string"}}},"links":{"type":"object","properties":{"hostaway":{"type":"string"},"rentalsunited":{"type":"string"},"channex":{"type":"string"},"leviathan":{"type":"string"},"ical":{"type":"string","format":"uri"}}},"guide":{"$ref":"#/components/schemas/Guide"}}},"Guide":{"type":"object","description":"Everything the guest sees (Guide editor). Codes, Wi-Fi, address and phone numbers are only shown to the guest after all steps are complete.","properties":{"property":{"type":"object","properties":{"name":{"type":"string"},"area":{"type":"string"},"address":{"type":"string"},"mapsUrl":{"type":"string"},"photo":{"type":"string"},"photoAlt":{"type":"string"},"floor":{"type":"string"},"welcome":{"type":"string"},"checkInTime":{"type":"string","pattern":"^\\d{2}:\\d{2}$","examples":["15:00"]},"checkOutTime":{"type":"string","pattern":"^\\d{2}:\\d{2}$","examples":["15:00"]},"licence":{"type":"string"}}},"host":{"type":"object","properties":{"name":{"type":"string"},"role":{"type":"string"},"replyTime":{"type":"string"},"phone":{"type":"string"},"whatsapp":{"type":"string"},"email":{"type":"string"},"helpTitle":{"type":"string"}}},"payments":{"type":"object","properties":{"deposit":{"type":"object","properties":{"amount":{"type":"number"},"mode":{"type":"string","enum":["hold","charge"]},"refundDays":{"type":"integer"},"desc":{"type":"string"},"facts":{"type":"array","items":{"type":"string"}},"terms":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"text":{"type":"string"}}}}}},"eco":{"type":"object","properties":{"desc":{"type":"string"},"facts":{"type":"array","items":{"type":"string"}}}},"trust":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"text":{"type":"string"}}}},"houseRules":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"text":{"type":"string"},"amount":{"type":"number"}}}},"termsText":{"type":"string"}}},"access":{"type":"object","properties":{"codes":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"code":{"type":"string"},"after":{"type":"string"}}}},"steps":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"text":{"type":"string"}}}},"etaSlots":{"type":"array","items":{"type":"string"}},"guidance":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"text":{"type":"string"}}}},"checkout":{"type":"array","items":{"type":"string"}}}},"wifi":{"type":"object","properties":{"network":{"type":"string"},"password":{"type":"string"},"speed":{"type":"string"},"router":{"type":"string"},"tips":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"text":{"type":"string"}}}}}},"bins":{"type":"object","description":"Malta waste collection: put-out / collection times, weekly bag schedule (organic | mixed | recycle | glass | \"\")"},"area":{"type":"array","items":{"type":"object","properties":{"cat":{"type":"string","enum":["eat","shop","transport","do","help"]},"name":{"type":"string"},"note":{"type":"string"},"dist":{"type":"string"},"q":{"type":"string"},"tel":{"type":"string"}}}},"extras":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"cat":{"type":"string","enum":["hampers","services"]},"name":{"type":"string"},"desc":{"type":"string"},"price":{"type":"number"},"unit":{"type":"string"},"badge":{"type":"string"},"note":{"type":"string"},"img":{"type":"string"},"maxQty":{"type":"integer"},"active":{"type":"boolean"}}}}}},"TaxRuleInput":{"type":"object","description":"A tourist-tax definition. Rates are chosen by the check-in date; add several entries for rate changes or seasons.","properties":{"name":{"type":"string","examples":["Kurtaxe"]},"collector":{"type":"string","examples":["Gemeinde Musterbad"]},"country":{"type":"string","examples":["DE"]},"municipality":{"type":"string"},"info":{"type":"string"},"schedule":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","examples":["2026-11-18"]},"to":{"type":"string","format":"date","examples":["2026-11-18"]},"basis":{"type":"string","enum":["per_person_night","per_night","per_stay","percent_of_price"]},"rate":{"type":"number"},"maxNights":{"type":"integer"},"adultAge":{"type":"integer","default":18},"childRate":{"type":"number","default":0}},"required":["from","basis","rate"]}}},"required":["name","schedule"]},"NukiSettings":{"type":"object","properties":{"token":{"type":"string","description":"Nuki Web API token (web.nuki.io → API). Empty/masked = keep"},"autoProvision":{"type":"boolean"},"leadDays":{"type":"integer","minimum":2},"graceHours":{"type":"integer"}}},"MediaUpload":{"type":"object","properties":{"filename":{"type":"string"},"dataBase64":{"type":"string","description":"Base64 (or data: URL) of a JPEG/PNG/WebP image, ≤ 6 MB"}},"required":["dataBase64"]},"BlockInput":{"type":"object","properties":{"from":{"type":"string","format":"date","examples":["2026-11-18"]},"to":{"type":"string","format":"date","examples":["2026-11-18"]},"note":{"type":"string"}},"required":["from","to"]},"CheckinPatch":{"type":"object","properties":{"adults":{"type":"integer"},"children":{"type":"integer"},"eta":{"type":"string"}}},"MessageInput":{"type":"object","properties":{"text":{"type":"string","maxLength":4000,"examples":["Hi Anna, the cleaner will leave the keys in the lockbox."]}},"required":["text"]},"WaiveInput":{"type":"object","properties":{"reason":{"type":"string","examples":["Goodwill — repeat guest"]},"note":{"type":"string"}},"required":["reason"]},"MarkPaidInput":{"type":"object","properties":{"method":{"type":"string","examples":["Cash","Bank transfer"]},"note":{"type":"string"}}},"ReleaseInput":{"type":"object","properties":{"retain":{"type":"number","description":"0 = release in full"},"reason":{"type":"string"},"note":{"type":"string"}}},"CustomerInput":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"nationality":{"type":"string"},"language":{"type":"string"},"notes":{"type":"string"},"address":{"type":"string"}}},"SettingsInput":{"type":"object","properties":{"brandName":{"type":"string"},"brandColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"accentColor":{"type":"string"},"logoUrl":{"type":"string"},"currency":{"type":"string","examples":["EUR"]},"host":{"type":"object"},"checkin":{"type":"object","properties":{"requireForm":{"type":"boolean"},"requireIdDocument":{"type":"boolean"},"requireIdPhoto":{"type":"boolean"},"requireSignature":{"type":"boolean"},"requireAddress":{"type":"boolean"},"collectCoTravellers":{"type":"boolean"}}},"mail":{"type":"object","properties":{"from":{"type":"string"},"fromName":{"type":"string"},"replyTo":{"type":"string"},"hostNotify":{"type":"string"},"testRedirect":{"type":"string"},"autoInvite":{"type":"boolean"},"autoInviteDays":{"type":"integer"}}},"applePayAssociation":{"type":"string"}}},"PaymentSettingsInput":{"type":"object","properties":{"revolut":{"type":"object","properties":{"apiKey":{"type":"string","description":"Secret API key (sk_…). Empty or masked = keep"},"publicKey":{"type":"string","description":"Public key (pk_…) — needed for Apple Pay / Google Pay buttons"},"sandbox":{"type":"boolean"},"preauth30d":{"type":"boolean"}}},"methods":{"type":"object","properties":{"card":{"type":"boolean"},"applePay":{"type":"boolean"},"googlePay":{"type":"boolean"},"manual":{"type":"object","properties":{"enabled":{"type":"boolean"},"instructions":{"type":"string"}}}}}}},"ChannelInput":{"type":"object","description":"Fields depend on the channel (see GET /api/v1/channels). Secrets: empty or masked = keep.","additionalProperties":{"type":["string","boolean"]}},"RuImportInput":{"type":"object","properties":{"reservationId":{"type":"string","description":"RentalsUnited reservation ID (numeric)"}},"required":["reservationId"]},"UserInput":{"type":"object","properties":{"username":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","description":"Used for Google / phone.codeb.io sign-in"},"phone":{"type":"string","description":"Used for phone.codeb.io sign-in"},"role":{"type":"string","examples":["owner","manager","staff","viewer"]},"password":{"type":"string"}},"required":["username"]},"UserPatch":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"role":{"type":"string"},"disabled":{"type":"boolean"},"resetPassword":{"type":"boolean"},"unlinkProvider":{"type":"string","enum":["google","codeb"]}}},"ApiKeyInput":{"type":"object","properties":{"name":{"type":"string"},"role":{"type":"string"}}},"WebhookInput":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["booking.created","booking.updated","booking.cancelled","checkin.completed","payment.completed","booking.unlocked","extras.ordered"]}},"active":{"type":"boolean"}}},"MailTest":{"type":"object","properties":{"to":{"type":"string","format":"email"}},"required":["to"]},"GuestCheckin":{"type":"object","properties":{"leadGuest":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"dob":{"type":"string","format":"date","examples":["2026-11-18"]},"nationality":{"type":"string"},"docType":{"type":"string","enum":["passport","id_card","driving_licence","residence_permit","eudi_wallet"],"description":"eudi_wallet only after a verified EUDI Wallet presentation; not for the German Meldeschein"},"docNumber":{"type":"string"},"address":{"type":"string"},"zip":{"type":"string"},"city":{"type":"string"},"country":{"type":"string"}}},"adults":{"type":"integer"},"children":{"type":"integer"},"coTravellers":{"type":"array","items":{"type":"object"}},"eta":{"type":"string"},"acceptRules":{"type":"boolean"},"idPhotos":{"type":"array","items":{"type":"string","description":"data: URL"}},"signature":{"type":"string","description":"PNG data: URL"}},"required":["leadGuest","adults","acceptRules"]},"GuestPay":{"type":"object","properties":{"mode":{"type":"string","enum":["checkout","wallet"],"description":"checkout → hosted Revolut page; wallet → order token for Apple Pay / Google Pay buttons"}}},"GuestExtras":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"qty":{"type":"integer"}}}},"deliver":{"type":"string","description":"\"arrival\" or a date"}}},"GuestEta":{"type":"object","properties":{"eta":{"type":"string"}}},"ContactInput":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"company":{"type":"string"},"phone":{"type":"string"},"properties":{"type":"string"},"topic":{"type":"string"},"message":{"type":"string"},"formToken":{"type":"string","description":"From GET /api/public/form-token"},"website":{"type":"string","description":"Honeypot — leave empty"}},"required":["name","email","message","formToken"]},"SignupInput":{"type":"object","properties":{"company":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"password":{"type":"string","minLength":10},"phone":{"type":"string"},"acceptTerms":{"type":"boolean"},"via":{"type":"string","description":"Set when signing up with Google or phone.codeb.io (from the /signup?via= redirect); then email and password are optional"},"formToken":{"type":"string"},"website":{"type":"string"}},"required":["company","name","email","password","acceptTerms","formToken"]},"TenantCreate":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"ownerUsername":{"type":"string"},"ownerEmail":{"type":"string"},"ownerName":{"type":"string"},"ownerPhone":{"type":"string"},"ownerPassword":{"type":"string"},"domain":{"type":"string"}},"required":["name"]},"TenantPatch":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["active","suspended"]}}},"TenantDelete":{"type":"object","properties":{"confirm":{"type":"string","description":"The tenant slug"}},"required":["confirm"]},"DomainInput":{"type":"object","properties":{"domain":{"type":"string","examples":["guests.example.com"]},"propertyId":{"type":"string","pattern":"^[a-z]_[a-z2-9]{10}$"}},"required":["domain"]},"EnquiryPatch":{"type":"object","properties":{"handled":{"type":"boolean"},"note":{"type":"string"}}},"PlatformConfig":{"type":"object","description":"platformName, platformHost, serverIp, wildcardSubdomains, operator, oidc{google,codeb}, taxRules (via /api/platform/v1/tax-rules), acme{auto,staging,email}, mail{pickupDir,defaultFrom,defaultFromName,enabled}, signup{enabled,requireApproval,notifyEmail}, contact{notifyEmail}, seo{indexNow{enabled},gsc{enabled,property,saJson}}"}},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"gpk_<id>_<secret>"},"platformKey":{"type":"http","scheme":"bearer","bearerFormat":"gpp_<id>_<secret>"},"session":{"type":"apiKey","in":"cookie","name":"gp_s"},"superSession":{"type":"apiKey","in":"cookie","name":"gp_sa"}}}}