Breaking Malta Budget 2027: the eco tax for short lets is set to increase to €10 per adult per night (capped at €80 per person) from 1 January 2027. Read more
Guestbud

Developers

API reference

REST + JSON. One API for the owner dashboard and your integrations: create bookings from your PMS, read check-in data, release deposits, export the MTA return, receive signed webhooks. Start with the API quick-start.

Tenant API

Manage properties, the local calendar, bookings, guest check-in data, payments (eco-contribution, deposits, extras), the MTA eco return, channels, users, API keys and webhooks of ONE tenant. Authenticate with Authorization: Bearer gpk_… (create keys in the backend under Settings → API keys). Every key has a role; the same permissions apply as for users. Writes from a browser session additionally need the header X-GP: 1.

OpenAPI 3.1 JSON

API keys

GET/api/v1/api-keysList this tenant's API keys (never the secret)

Requires permission users.manage.

POST/api/v1/api-keysCreate an API key with a role — the full key is returned ONCE

Requires permission users.manage.

Body: ApiKeyInput

DELETE/api/v1/api-keys/{id}Revoke an API key immediately

Requires permission users.manage.

Parameters: id (path)

Account

GET/api/v1/meWho am I: tenant, user/key, role and permissions
GET/api/v1/auditAudit trail (latest first)

Requires permission users.manage.

Parameters: limit (query)

Bookings

GET/api/v1/bookingsList bookings (filters; format=csv for a spreadsheet export)

Requires permission bookings.view.

Parameters: from (query), to (query), dateField (query), propertyId (query), status (query), state (query), q (query), source (query), limit (query), format (query)

POST/api/v1/bookingsCreate a booking (local calendar) — or upsert by source+externalId for integrations

Requires permission bookings.edit.

Body: BookingInput

GET/api/v1/bookings/{id}Booking with check-in data, payments and activity log

Requires permission bookings.view.

Parameters: id (path)

PATCH/api/v1/bookings/{id}Edit a booking (dates, guests, guest contact, notes, noDeposit)

Requires permission bookings.edit.

Parameters: id (path)

Body: BookingInput

POST/api/v1/bookings/{id}/cancelCancel a booking (frees the calendar; portal shows "cancelled")

Requires permission bookings.edit.

Parameters: id (path)

POST/api/v1/bookings/{id}/reinstateUndo a cancellation (refused if the dates were booked meanwhile, unless allowOverlap)

Requires permission bookings.edit.

Parameters: id (path)

PATCH/api/v1/bookings/{id}/checkinStaff correction of check-in data (adults / under-18 / ETA)

Requires permission bookings.edit.

Parameters: id (path)

Body: CheckinPatch

POST/api/v1/bookings/{id}/portal-link/rotateIssue a new guest portal link (the old one stops working)

Requires permission bookings.edit.

Parameters: id (path)

POST/api/v1/bookings/{id}/send-linkEmail the guest their portal link

Requires permission bookings.edit.

Parameters: id (path)

POST/api/v1/bookings/{id}/remindSend a payment / check-in reminder email

Requires permission bookings.edit.

Parameters: id (path)

GET/api/v1/bookings/{id}/files/{file}Download an ID document photo / signature uploaded at check-in

Requires permission bookings.view.

Parameters: id (path), file (path)

GET/api/v1/bookings/{id}/meldescheinPrintable Meldeschein (German guest registration, bilingual) — HTML, ?lang=de|en

Requires permission bookings.view.

Parameters: id (path), lang (query)

Calendar

POST/api/v1/properties/{id}/feed-token/rotateRotate the private iCal export URL (old URL stops working)

Requires permission properties.edit.

Parameters: id (path)

GET/api/v1/calendarCalendar: bookings + owner blocks per property in a date window

Requires permission bookings.view.

Parameters: from (query), to (query), propertyId (query)

POST/api/v1/properties/{id}/blocksBlock dates on a property (owner stay, maintenance)

Requires permission bookings.edit.

Parameters: id (path)

Body: BlockInput

DELETE/api/v1/properties/{id}/blocks/{blockId}Remove a date block

Requires permission bookings.edit.

Parameters: id (path), blockId (path)

Channels

GET/api/v1/channelsAvailable channel connectors and this tenant's (masked) connection settings

Requires permission channels.manage.

PATCH/api/v1/channels/{id}Save a channel connection (empty / masked secret = keep the stored one)

Requires permission channels.manage.

Parameters: id (path)

Body: ChannelInput

POST/api/v1/channels/{id}/testTest a channel connection

Requires permission channels.manage.

Parameters: id (path)

GET/api/v1/channels/{id}/listingsListings available in the connected channel (to link properties)

Requires permission channels.manage.

Parameters: id (path)

POST/api/v1/channels/syncImport reservations now (all channels, or ?channel=…)

Requires permission channels.manage.

Parameters: channel (query)

Customers

GET/api/v1/customersGuest directory (search with q)

Requires permission bookings.view.

Parameters: q (query)

GET/api/v1/customers/{id}Customer with stay history

Requires permission bookings.view.

Parameters: id (path)

PATCH/api/v1/customers/{id}Edit a customer record

Requires permission bookings.edit.

Parameters: id (path)

Body: CustomerInput

DELETE/api/v1/customers/{id}Erase a customer record (GDPR) — bookings keep only what the law requires

Requires permission bookings.edit.

Parameters: id (path)

Messages

GET/api/v1/bookings/{id}/messagesThe guest conversation from the booking channel (live), plus messages sent from here

Requires permission bookings.view.

Parameters: id (path)

POST/api/v1/bookings/{id}/messagesSend a message to the guest through the booking channel (Airbnb / Booking.com … via Hostaway or Channex). Body {text}

Requires permission bookings.edit.

Parameters: id (path)

Body: MessageInput

POST/api/v1/bookings/{id}/send-link-channelSend the portal link (or a reminder, ?kind=reminder) through the booking channel chat

Requires permission bookings.edit.

Parameters: id (path)

Payments

POST/api/v1/bookings/{id}/payments/{leg}/waiveWaive the eco-contribution or deposit (reason required; waived eco stays due to the MTA)

Requires permission payments.manage.

Parameters: id (path), leg (path)

Body: WaiveInput

POST/api/v1/bookings/{id}/payments/{leg}/unwaiveUndo a waiver — the guest is asked to pay again

Requires permission payments.manage.

Parameters: id (path), leg (path)

POST/api/v1/bookings/{id}/payments/{leg}/mark-paidRecord a payment collected outside the portal (cash / bank transfer)

Requires permission payments.manage.

Parameters: id (path), leg (path)

Body: MarkPaidInput

POST/api/v1/bookings/{id}/deposit/releaseRelease the deposit in full, or retain part (amount + reason)

Requires permission payments.manage.

Parameters: id (path)

Body: ReleaseInput

GET/api/v1/payment-reasonsWaive reasons offered in the backend

Requires permission bookings.view.

Payments setup

PATCH/api/v1/settings/paymentsConfigure this tenant's payment methods (Revolut keys, Apple/Google Pay, manual collection)

Requires permission settings.manage.

Body: PaymentSettingsInput

POST/api/v1/settings/payments/testCheck the Revolut secret key (lists webhooks)

Requires permission settings.manage.

POST/api/v1/settings/payments/webhookRegister (or re-register) the Revolut webhook for this tenant

Requires permission settings.manage.

POST/api/v1/settings/payments/apple-pay-domainsRegister this tenant's portal domains with Revolut for Apple Pay

Requires permission settings.manage.

Properties

GET/api/v1/propertiesList properties (no codes / Wi-Fi in the list)

Requires permission properties.view.

POST/api/v1/propertiesCreate a property (local, or linked to a channel)

Requires permission properties.edit.

Body: PropertyInput

GET/api/v1/properties/{id}Property with its full guest guide (incl. codes & Wi-Fi)

Requires permission properties.view.

Parameters: id (path)

PATCH/api/v1/properties/{id}Update property settings and/or the guest guide (send the whole guide object)

Requires permission properties.edit.

Parameters: id (path)

Body: PropertyInput

DELETE/api/v1/properties/{id}Delete a property (refused while it has upcoming bookings)

Requires permission properties.edit.

Parameters: id (path)

GET/api/v1/waste-presetsRubbish & recycling presets (per country) for the guest guide

Requires permission properties.view.

POST/api/v1/properties/{id}/mediaUpload a photo (JPEG/PNG/WebP, base64, ≤ 6 MB) → returns its URL for the guide

Requires permission properties.edit.

Parameters: id (path)

Body: MediaUpload

Reports

GET/api/v1/reports/eco-returnQuarterly MTA eco-contribution return (JSON, or format=xlsx|csv|working-csv)

Requires permission reports.view.

Parameters: quarter (query), propertyId (query), includeUnpaid (query), format (query)

GET/api/v1/reports/tourist-taxTourist tax collected per definition in a date range (check-in based); format=csv

Requires permission reports.view.

Parameters: from (query), to (query), ruleId (query), format (query)

Settings

GET/api/v1/settingsTenant settings (secrets masked)

Requires permission settings.manage.

PATCH/api/v1/settingsUpdate branding, host defaults, check-in form options, email sender

Requires permission settings.manage.

Body: SettingsInput

POST/api/v1/settings/mail/testSend a test email to an address

Requires permission settings.manage.

Body: MailTest

GET/api/v1/settings/mail/logLast 300 emails handed to the mail server

Requires permission settings.manage.

Smart locks

POST/api/v1/bookings/{id}/lock/{action}Create / renew (provision) or remove (revoke) the Nuki door code of a booking now

Requires permission payments.manage.

Parameters: id (path), action (path)

GET/api/v1/settings/nukiNuki settings of this tenant (token masked)

Requires permission settings.manage.

PATCH/api/v1/settings/nukiSave this tenant's Nuki Web API token and code rules

Requires permission settings.manage.

Body: NukiSettings

GET/api/v1/settings/nuki/smartlocksSmart locks on this tenant's Nuki account (to assign to properties)

Requires permission settings.manage.

Tourist taxes

GET/api/v1/tax-rulesTax definitions available to this tenant (platform-wide + own)

Requires permission properties.view.

POST/api/v1/tax-rulesCreate a tenant tax definition (e.g. a municipality's Kurtaxe)

Requires permission settings.manage.

Body: TaxRuleInput

PATCH/api/v1/tax-rules/{id}Edit a tenant tax definition

Requires permission settings.manage.

Parameters: id (path)

Body: TaxRuleInput

DELETE/api/v1/tax-rules/{id}Delete a tenant tax definition (refused while a property uses it)

Requires permission settings.manage.

Parameters: id (path)

Users

GET/api/v1/rolesRoles and the permissions each grants
GET/api/v1/usersList users of this tenant

Requires permission users.manage.

POST/api/v1/usersAdd a user (password optional — a temporary one is generated). Sign-in: password, Google (email) or phone.codeb.io (email / phone)

Requires permission users.manage.

Body: UserInput

PATCH/api/v1/users/{id}Change role, contact, disable, or reset password

Requires permission users.manage.

Parameters: id (path)

Body: UserPatch

DELETE/api/v1/users/{id}Remove a user (never the last owner)

Requires permission users.manage.

Parameters: id (path)

Webhooks

GET/api/v1/webhooksOutbound webhooks (events pushed to your systems)

Requires permission settings.manage.

POST/api/v1/webhooksAdd a webhook — the signing secret is returned ONCE

Requires permission settings.manage.

Body: WebhookInput

PATCH/api/v1/webhooks/{id}Change URL / events / active

Requires permission settings.manage.

Parameters: id (path)

Body: WebhookInput

DELETE/api/v1/webhooks/{id}Delete a webhook

Requires permission settings.manage.

Parameters: id (path)

POST/api/v1/webhooks/{id}/testSend a test event (event: "ping")

Requires permission settings.manage.

Parameters: id (path)

GET/api/v1/webhooks/logLast 200 webhook deliveries

Requires permission settings.manage.

Platform API

Superadmin operations: tenants, domains, superadmins, platform settings. Authenticate with Authorization: Bearer gpp_… (platform keys) or a superadmin session.

OpenAPI 3.1 JSON

Platform

GET/api/platform/v1/meCurrent superadmin / platform key
GET/api/platform/v1/tenantsAll tenants with counts, domains and owner
POST/api/platform/v1/tenantsQuick-create a tenant (name → slug, owner login, optional domain). Returns a temporary password once.
GET/api/platform/v1/tenants/{id}One tenant

Parameters: id (path)

PATCH/api/platform/v1/tenants/{id}Rename, suspend/resume, approve a signup

Parameters: id (path)

Body: TenantPatch

DELETE/api/platform/v1/tenants/{id}Delete a tenant (archived to <data>/deleted, all domains/links stop working). Body {confirm:"<slug>"}

Parameters: id (path)

Body: TenantDelete

POST/api/platform/v1/tenants/{id}/domainsConnect a custom domain (optionally pinned to one property)

Parameters: id (path)

Body: DomainInput

DELETE/api/platform/v1/tenants/{id}/domains/{domain}Disconnect a domain

Parameters: id (path), domain (path)

GET/api/platform/v1/certificatesLet's Encrypt certificate status of every tenant domain
POST/api/platform/v1/certificates/{domain}Request / retry a Let's Encrypt certificate for a domain (processed by the SYSTEM worker task)

Parameters: domain (path)

GET/api/platform/v1/dns-checkLive DNS check: does a domain point at this platform?

Parameters: domain (query)

POST/api/platform/v1/tenants/{id}/supportOpen the tenant backend as platform support (audited, owner rights)

Parameters: id (path)

POST/api/platform/v1/tenants/{id}/owner-passwordReset the owner's password (temporary password returned once)

Parameters: id (path)

GET/api/platform/v1/superadminsSuperadmins
POST/api/platform/v1/superadminsAdd a superadmin (temporary password returned once)

Body: UserInput

PATCH/api/platform/v1/superadmins/{id}Edit / disable a superadmin, or reset password

Parameters: id (path)

Body: UserPatch

DELETE/api/platform/v1/superadmins/{id}Remove a superadmin (never the last one)

Parameters: id (path)

GET/api/platform/v1/configPlatform settings (secrets masked)
PATCH/api/platform/v1/configUpdate platform settings
GET/api/platform/v1/tax-rulesPlatform tax definitions (usable by every tenant). Built-ins: "zero" and "mt-eco"
POST/api/platform/v1/tax-rulesAdd a platform tax definition (e.g. a country-wide tax)
PATCH/api/platform/v1/tax-rules/{id}Edit a platform tax definition (built-ins too)

Parameters: id (path)

Body: TaxRuleInput

DELETE/api/platform/v1/tax-rules/{id}Delete a platform tax definition (not the built-ins, not while in use)

Parameters: id (path)

POST/api/platform/v1/mail/testSend a test email through the IIS pickup directory

Body: MailTest

POST/api/platform/v1/seo/submitSubmit all public URLs to IndexNow (and the sitemap to Google Search Console) now
GET/api/platform/v1/api-keysPlatform API keys (for provisioning integrations)
POST/api/platform/v1/api-keysCreate a platform API key — returned ONCE
DELETE/api/platform/v1/api-keys/{id}Revoke a platform API key

Parameters: id (path)

POST/api/platform/v1/demo/resetReset the demo tenant to fresh sample data now
GET/api/platform/v1/enquiriesContact-form enquiries (latest first)
PATCH/api/platform/v1/enquiries/{id}Mark an enquiry handled / add a note

Parameters: id (path)

Body: EnquiryPatch

DELETE/api/platform/v1/enquiries/{id}Delete an enquiry (GDPR)

Parameters: id (path)

Guest & public API

Endpoints used by the guest portal (authenticated by the booking token in the URL) and public forms.

OpenAPI 3.1 JSON

Guest portal

GET/g/{token}/eudiStart check-in with the EU Digital Identity Wallet (redirect to phone.codeb.io)

Parameters: token (path)

GET/api/guest/{token}Guest portal data for a booking token (locked until all steps are done)

Parameters: token (path)

POST/api/guest/{token}/checkinSubmit online check-in

Parameters: token (path)

Body: GuestCheckin

POST/api/guest/{token}/pay/{leg}Start a payment: returns a checkout URL (card) or an order token (Apple/Google Pay)

Parameters: token (path), leg (path)

Body: GuestPay

POST/api/guest/{token}/extrasOrder extras (prices are taken from the property catalogue, never from the client)

Parameters: token (path)

Body: GuestExtras

POST/api/guest/{token}/etaShare the estimated arrival time

Parameters: token (path)

Body: GuestEta

Public

GET/api/public/form-tokenAnti-spam form token for contact / signup forms
POST/api/public/contactContact form → stored and emailed to the operator
GET/api/public/slug-availableIs a tenant short name available?

Parameters: slug (query)

POST/api/public/signupSelf-service signup: creates a tenant awaiting email confirmation
POST/api/public/find-bookingFind a booking (ref + last name or email) on a tenant domain → portal URL
GET/ical/{feed}Private iCal availability feed of a property

Parameters: feed (path)

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"
    }
  }
}
BookingInputCreate (local calendar) or, with source + externalId, idempotently upsert a booking from another system.
{
  "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"
    }
  }
}
GuideEverything the guest sees (Guide editor). Codes, Wi-Fi, address and phone numbers are only shown to the guest after all steps are complete.
{
  "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"
          }
        }
      }
    }
  }
}
TaxRuleInputA tourist-tax definition. Rates are chosen by the check-in date; add several entries for rate changes or seasons.
{
  "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"
            }
          }
        }
      }
    }
  }
}
ChannelInputFields depend on the channel (see GET /api/v1/channels). Secrets: empty or masked = keep.
{
  "type": "object",
  "description": "Fields depend on the channel (see GET /api/v1/channels). Secrets: empty or masked = keep.",
  "additionalProperties": {
    "type": [
      "string",
      "boolean"
    ]
  }
}
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"
    },
    "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"
    }
  }
}
PlatformConfigplatformName, 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}}
{
  "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}}"
}