Skip to content
Staywick

Data formats

What every file you can export from Staywick holds, column by column, and every field of the public API and its webhooks. The page is built from the code that writes the files, so it always describes the version running now.

Archive format staywick-export, version 1.

Four ways to take your data

  • From the dashboard: the Bookings, Guests, Registration, Payments, Invoices, Owners and Analytics screens each export what they show — as CSV on every plan, and as Excel (XLSX) or a printable page on Standard and above (the guest register in every format on every plan). This works also while the account is locked.
  • Export everything: the account owner downloads the whole organization as one ZIP file — every table, the owner statements, the analytics report, signed rental agreements, photos and the logo. Free on every plan, also while the account is locked, 3 times a day.
  • One by one as PDF: invoices, booking confirmations and signed rental agreements.
  • Through the public API, on Pro and above while the trial or subscription is active: units, bookings, availability and prices.

How the files are written

  • CSV files are UTF-8 with a byte order mark, so spreadsheets show accented letters correctly. Values are separated by commas, one record per line.
  • A value that holds a comma, a double quote or a line break is wrapped in double quotes, and a double quote inside it is doubled.
  • The first line of each CSV names its columns, in the order listed on this page.
  • A text value that begins with =, +, -, @, a tab or a carriage return is written with an apostrophe in front of it in the CSV, so a spreadsheet never runs it as a formula. The JSON file keeps the value unchanged.
  • An empty CSV cell, and null in JSON, means there is no value.
  • Yes/no values are written true or false.
  • JSON values and lists are JSON text inside a CSV cell, and real JSON in the .json file.
  • Each .json file is one array of records with the same field names as the CSV's columns. It is complete, and it is the file to use when moving to another system.
  • Dates are written YYYY-MM-DD, and times of day HH:MM or HH:MM:SS.
  • A date with a time is ISO 8601 in UTC, for example 2026-07-02T09:14:00+00:00, sometimes with fractions of a second.
  • Amounts are numbers with a dot as the decimal mark, in the property's currency (property.currency in manifest.json). The API writes amounts as text instead, such as "120.00".
  • Every id is a UUID that never changes: the same record has the same id in every export and in the API, and a column that points to another file holds that file's id.
  • Column and field names are in English and the same in every language. What was typed — unit names, notes, messages — is as it was typed. The headings of the owner statements and of the analytics report are in the language of whoever exported them.
  • Rows are read page by page while the account keeps working, between startedAt and finishedAt in manifest.json, so the archive is not a snapshot of one instant.
  • The archive is a standard ZIP without ZIP64, so it holds at most 4,294,967,294 bytes and 65,534 files. When an export would come near that — above 3,900,000,000 bytes or 65,000 files — the photos are left out, and everything else still fits.
  • The account owner can run the full export 3 times in any 24 hours. Each screen's own export always works.
  • Photos and the logo are the files as they are stored, which were made smaller when they were uploaded.

The full export (ZIP)

  • README.txt

    What the archive holds, in the language of whoever exported it, with the address of this page.

  • manifest.json

    What is in the archive, how many rows each file holds, what was left out and why. Its fields are listed below.

  • data/<part>.csvdata/<part>.json

    One table each, as CSV and as JSON. Every file and its columns are described below.

  • owner-statements/<owner>.csvowner-statements/<owner>.json

    Each owner's statements, month by month, as on the Owners screen.

  • reports/analytics-365-days.csvreports/analytics-365-days.json

    The analytics report for the last 365 days, when the plan includes analytics.

  • agreements/<confirmation_number>.pdf

    Each signed rental agreement as a PDF, named by its booking's number.

  • photos/property/cover-<file>photos/property/<NN>-<file>

    The listing's cover and its photos, numbered in their order.

  • photos/units/<unit>/<NN>-<file>

    Each unit's photos, numbered in their order.

  • photos/unused/<file>

    Files still in storage that no listing uses any more.

  • photos/index.csv

    Where each downloaded photo is used.

    • zip_path

      text

    • used_as

      value from a list

      one of: logo, cover, property, unit, unused

    • unit

      text

      may be empty

    • position

      whole number

      may be empty

    • source_url

      text

    • bytes

      whole number

      may be empty

    • status

      value from a list

      one of: ok, missing, not_included

  • photos/external-links.csv

    Pictures linked from other websites: listed, never downloaded.

    • used_as

      value from a list

      one of: logo, cover, property, unit, unused

    • unit

      text

      may be empty

    • position

      whole number

      may be empty

    • url

      text

  • branding/logo.<ext>

    The logo, if one was uploaded.

Fields of manifest.json

  • formatThe format's name: staywick-export.
  • versionThe format's version.
  • documentationThe address of this page.
  • propertyThe property's id, name, currency and time zone.
  • startedAtWhen the export started (UTC).
  • finishedAtWhen it finished (UTC).
  • consistencyHow the rows were read: page by page, between the two times.
  • partsFor each part written: its files and how many rows it holds.
  • skippedEach part that was left out, and why.
  • photosWhether the photos are included, how many files and bytes, which could not be downloaded, and how many are linked from elsewhere or unused.
  • agreementsHow many agreement PDFs were written, and which could not be.
  • notExportedThe internal tables that never leave.
  • zipLimitsThe ZIP limits described above.

Why a part is listed in skipped

  • missingTableThe database did not have that table yet.
  • missingColumnThe database did not have one of its columns yet.
  • notOnPlanThe plan does not include it.
  • failedThe server or the network refused it, after a second try.
  • notIncludedThe owner chose to leave it out (the photos).

Every file and its columns

Each table is written twice with the same columns: as data/<part>.csv and as data/<part>.json. The columns are listed in their order, each with its type and the database's own type beside it.

01Units, with their settings, photos, calendars, prices, pricing rules and offers

data/units.csvdata/units.json

Each unit — apartment, room or house: its name, settings, check-in details, door code and Wi-Fi, and its photo addresses.Columns: 32
  • id

    id (UUID)uuid

  • number

    textcharacter varying(120)

    The unit's name, as the host wrote it.

  • room_type_id

    id (UUID)uuid

    may be empty · points to unit-types.id

  • sort_order

    whole numberinteger

    may be empty

  • status

    value from a listroom_status

    one of: available, occupied, dirty, inspected, maintenance, dnd, out_of_order

  • floor

    whole numberinteger

    may be empty

  • is_smoking

    true/falseboolean

  • description

    texttext

    may be empty

  • amenities

    JSONjsonb

    may be empty

  • photos

    JSONjsonb

    may be empty

    The unit's photo addresses, in order.

  • address

    texttext

    may be empty

  • city

    textcharacter varying(100)

    may be empty

  • country

    textcharacter varying(100)

    may be empty

  • lat

    decimal numbernumeric(10,7)

    may be empty

  • lng

    decimal numbernumeric(10,7)

    may be empty

  • max_occupancy

    whole numberinteger

    may be empty

  • base_price

    decimal numbernumeric(10,2)

    may be empty

    The price per night when no other price applies.

  • price_min

    decimal numbernumeric(10,2)

    may be empty

  • price_max

    decimal numbernumeric(10,2)

    may be empty

  • min_nights

    whole numberinteger

    may be empty

  • check_in_time

    textcharacter varying(5)

    may be empty

    HH:MM; empty means the property's time.

  • check_out_time

    textcharacter varying(5)

    may be empty

  • check_in_instructions

    texttext

    may be empty

  • access_code

    textcharacter varying(50)

    may be empty

    The door code. Keep the file safe.

  • wifi_name

    textcharacter varying(100)

    may be empty

  • wifi_password

    textcharacter varying(100)

    may be empty

  • online_checkin

    true/falseboolean

    may be empty

  • code_after_checkin

    true/falseboolean

    may be empty

  • default_cleaner_id

    id (UUID)uuid

    may be empty · points to team.id

  • notes

    texttext

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

Columns of this table that are not exported: 1 (credentials and private links).

data/unit-types.csvdata/unit-types.json

Unit types: settings and prices that units can share.Columns: 10
  • id

    id (UUID)uuid

  • name

    textcharacter varying(100)

  • description

    texttext

    may be empty

  • base_price

    decimal numbernumeric(10,2)

  • max_occupancy

    whole numberinteger

  • bed_type

    textcharacter varying(50)

  • size_sqft

    whole numberinteger

    may be empty

  • amenities

    JSONjsonb

    may be empty

  • images

    JSONjsonb

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

data/unit-calendar.csvdata/unit-calendar.json

Per-night prices and the nights the host closed, one row per unit and night.Columns: 8
  • id

    id (UUID)uuid

  • room_id

    id (UUID)uuid

    points to units.id

  • date

    datedate

  • price

    decimal numbernumeric(10,2)

    may be empty

    That night's own price; empty means the unit's price.

  • blocked

    true/falseboolean

  • note

    texttext

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/pricing-rules.csvdata/pricing-rules.json

Pricing rules and offers: seasons, days of the week, and discounts for longer, early or last-minute stays.Columns: 13
  • id

    id (UUID)uuid

  • kind

    texttext

    season, weekend, length_of_stay, early_bird or last_minute.

  • name

    textcharacter varying(80)

  • percent

    decimal numbernumeric(5,2)

    For season and weekend, the change in percent (negative lowers the price); for the others, the discount in percent.

  • date_from

    datedate

    may be empty

  • date_to

    datedate

    may be empty

  • weekdays

    list of: whole numbersmallint[]

    may be empty

    The days of the week it applies to: 1 = Monday … 7 = Sunday.

  • min_nights

    whole numberinteger

    may be empty

  • days_before

    whole numberinteger

    may be empty

  • unit_ids

    list of: id (UUID)uuid[]

    may be empty · points to units.id

    The units it applies to; empty means every unit.

  • active

    true/falseboolean

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/unit-compliance.csvdata/unit-compliance.json

A unit's own guest-register and tourist-tax settings, where they differ from the property's.Columns: 10
  • room_id

    id (UUID)uuid

    points to units.id

  • register

    textcharacter varying(20)

    may be empty

  • tourist_tax_rate

    decimal numbernumeric(10,2)

    may be empty

  • free_under_age

    whole numberinteger

    may be empty

  • half_under_age

    whole numberinteger

    may be empty

  • obligor_name

    textcharacter varying(200)

    may be empty

  • obligor_tax_id

    textcharacter varying(50)

    may be empty

  • facility_code

    textcharacter varying(50)

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/calendar-feeds.csvdata/calendar-feeds.json

Calendars imported from other channels (iCal links).Columns: 7
  • id

    id (UUID)uuid

  • room_id

    id (UUID)uuid

    points to units.id

  • source

    textcharacter varying(100)

  • channel_id

    textcharacter varying(40)

    may be empty

  • url

    texttext

  • last_synced_at

    date and time (UTC)timestamp with time zone

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

data/imported-calendar.csvdata/imported-calendar.json

The stays and blocks read from those calendars.Columns: 11
  • id

    id (UUID)uuid

  • room_id

    id (UUID)uuid

    points to units.id

  • feed_id

    id (UUID)uuid

    points to calendar-feeds.id

  • source

    textcharacter varying(100)

    may be empty

  • uid

    texttext

  • start_date

    datedate

  • end_date

    datedate

    The day the stay ends; that night is free.

  • summary

    texttext

    may be empty

  • channel_ref

    textcharacter varying(40)

    may be empty

  • phone_hint

    textcharacter varying(4)

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

data/channels.csvdata/channels.json

Channel connections and their state.Columns: 7
  • id

    id (UUID)uuid

  • channel_id

    textcharacter varying(40)

  • mode

    textcharacter varying(10)

  • status

    textcharacter varying(24)

  • last_error

    texttext

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

Columns of this table that are not exported: 2 (credentials and private links).

02Bookings and booking requests, with their payment entries

data/bookings.csvdata/bookings.json

Every booking and booking request, with its dates, guest, price and channel. A booking confirmation is this record.Columns: 30
  • id

    id (UUID)uuid

  • confirmation_number

    textcharacter varying(20)

  • status

    value from a listreservation_status

    one of: tentative, confirmed, checked_in, checked_out, cancelled, no_show

  • guest_id

    id (UUID)uuid

    may be empty · points to guests.id

  • room_id

    id (UUID)uuid

    may be empty · points to units.id

  • room_type_id

    id (UUID)uuid

    may be empty · points to unit-types.id

  • check_in_date

    datedate

  • check_out_date

    datedate

    The day the guest leaves; that night is not part of the stay.

  • actual_check_in

    date and time (UTC)timestamp with time zone

    may be empty

  • actual_check_out

    date and time (UTC)timestamp with time zone

    may be empty

  • adults

    whole numberinteger

  • children

    whole numberinteger

  • rate_plan

    value from a listrate_plan_type

    one of: bar, package, corporate, government, promotional

  • rate_per_night

    decimal numbernumeric(10,2)

  • total_amount

    decimal numbernumeric(10,2)

    The stay's total, after any discount.

  • discount_amount

    decimal numbernumeric(10,2)

    may be empty

  • discount_detail

    JSONjsonb

    may be empty

    How the discount was worked out.

  • payment_due_at

    date and time (UTC)timestamp with time zone

    may be empty

  • payment_due_amount

    decimal numbernumeric(10,2)

    may be empty

  • billing

    JSONjsonb

    may be empty

    The invoice details the guest gave at online check-in: company, tax number, address.

  • channel

    value from a listchannel

    one of: direct, booking_com, expedia, airbnb, hotels_com, gds, phone, walk_in

  • channel_confirmation_id

    textcharacter varying(100)

    may be empty

  • group_id

    id (UUID)uuid

    may be empty

  • corporate_account_id

    id (UUID)uuid

    may be empty

  • special_requests

    texttext

    may be empty

  • early_check_in

    true/falseboolean

  • late_check_out

    true/falseboolean

  • locale

    texttext

    may be empty

    The language of the guest's e-mails.

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

Columns of this table that are not exported: 2 (credentials and private links).

data/payments-and-expenses.csvdata/payments-and-expenses.json

Payments received and expenses, as on the Payments screen.Columns: 11
  • id

    id (UUID)uuid

  • type

    value from a listledger_type

    one of: income, expense

  • category

    textcharacter varying(60)

  • description

    texttext

    may be empty

  • amount

    decimal numbernumeric(12,2)

    Always positive; type says whether it is income or an expense.

  • currency

    textcharacter varying(3)

  • method

    textcharacter varying(30)

    may be empty

  • entry_date

    datedate

  • reservation_id

    id (UUID)uuid

    may be empty · points to bookings.id

  • room_id

    id (UUID)uuid

    may be empty · points to units.id

  • created_at

    date and time (UTC)timestamp with time zone

03Guests and the guest register

data/guests.csvdata/guests.json

The guest book: each guest's contact details and what is known about them.Columns: 22
  • id

    id (UUID)uuid

  • first_name

    textcharacter varying(100)

  • last_name

    textcharacter varying(100)

  • email

    textcharacter varying(255)

    may be empty

  • phone

    textcharacter varying(50)

    may be empty

  • nationality

    textcharacter varying(100)

    may be empty

  • passport_number

    textcharacter varying(50)

    may be empty

  • date_of_birth

    datedate

    may be empty

  • address

    JSONjsonb

    may be empty

  • notes

    texttext

    may be empty

  • tags

    list of: texttext[]

    may be empty

  • preferences

    JSONjsonb

    may be empty

  • dietary_restrictions

    list of: texttext[]

    may be empty

  • loyalty_tier

    value from a listloyalty_tier

    may be empty

    one of: bronze, silver, gold, platinum, invite_only

  • loyalty_points

    whole numberinteger

  • lifetime_value

    decimal numbernumeric(12,2)

  • total_stays

    whole numberinteger

  • marketing_consent

    true/falseboolean

  • gdpr_consent

    true/falseboolean

  • gdpr_consent_date

    date and time (UTC)timestamp with time zone

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/guest-register.csvdata/guest-register.json

Everyone registered for a stay, with their identity document details.Columns: 15
  • id

    id (UUID)uuid

  • reservation_id

    id (UUID)uuid

    points to bookings.id

  • is_lead

    true/falseboolean

    true for the guest who made the booking.

  • first_name

    textcharacter varying(100)

  • last_name

    textcharacter varying(100)

  • date_of_birth

    datedate

    may be empty

  • nationality

    textcharacter varying(100)

    may be empty

  • document_type

    textcharacter varying(20)

  • document_number

    textcharacter varying(50)

    may be empty

  • gender

    textcharacter varying(10)

    may be empty

  • self_registered_at

    date and time (UTC)timestamp with time zone

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

  • age_at_arrival

    whole numbersmallint

    may be empty

    Age on the day of arrival, kept when the date of birth is removed.

  • details_removed_at

    date and time (UTC)timestamp with time zone

    may be empty

    When the identity details were removed, after the period set for the register.

data/registrations.csvdata/registrations.json

Each stay's registration with the authorities, and its tourist tax.Columns: 8
  • reservation_id

    id (UUID)uuid

    points to bookings.id

  • status

    textcharacter varying(20)

    pending, exported or filed.

  • tourist_tax_amount

    decimal numbernumeric(10,2)

    may be empty

  • exported_at

    date and time (UTC)timestamp with time zone

    may be empty

  • filed_at

    date and time (UTC)timestamp with time zone

    may be empty

  • reference

    textcharacter varying(100)

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/compliance-settings.csvdata/compliance-settings.json

The property's guest-register and tourist-tax settings.Columns: 10
  • register

    textcharacter varying(20)

  • tourist_tax_rate

    decimal numbernumeric(10,2)

  • free_under_age

    whole numberinteger

  • half_under_age

    whole numberinteger

  • obligor_name

    textcharacter varying(200)

    may be empty

  • obligor_tax_id

    textcharacter varying(50)

    may be empty

  • facility_code

    textcharacter varying(50)

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

  • register_retention_months

    whole numbersmallint

    may be empty

04Invoices and booking confirmations

data/invoices.csvdata/invoices.json

Invoices and credit notes, with their lines and totals.Columns: 26
  • id

    id (UUID)uuid

  • number

    texttext

    may be empty

  • kind

    texttext

    invoice or credit_note.

  • status

    texttext

    draft, issued, sent, paid or cancelled.

  • year

    whole numberinteger

    may be empty

  • seq

    whole numberinteger

    may be empty

  • reservation_id

    id (UUID)uuid

    may be empty · points to bookings.id

  • credit_of

    id (UUID)uuid

    may be empty · points to invoices.id

    For a credit note, the invoice it cancels.

  • issued_at

    datedate

    may be empty

  • due_at

    datedate

    may be empty

  • currency

    textcharacter varying(3)

  • locale

    texttext

    may be empty

  • recipient

    JSONjsonb

    Who the invoice is made out to.

  • items

    JSONjsonb

    The invoice's lines.

  • net_total

    decimal numbernumeric(12,2)

  • tax_total

    decimal numbernumeric(12,2)

  • total

    decimal numbernumeric(12,2)

  • payment_method

    texttext

  • terms

    texttext

  • note

    texttext

  • auto

    true/falseboolean

  • sent_at

    date and time (UTC)timestamp with time zone

    may be empty

  • paid_at

    date and time (UTC)timestamp with time zone

    may be empty

  • cancelled_at

    date and time (UTC)timestamp with time zone

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/invoice-settings.csvdata/invoice-settings.json

What every invoice says about the issuer: legal name, address, tax number, bank account and numbering.Columns: 11
  • legal_name

    texttext

  • address

    texttext

  • tax_id

    texttext

  • iban

    texttext

  • number_prefix

    texttext

  • due_days

    whole numberinteger

  • second_currency

    textcharacter varying(3)

    may be empty

  • note

    texttext

  • terms

    texttext

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/invoice-counters.csvdata/invoice-counters.json

The last invoice number used in each year.Columns: 2
  • year

    whole numberinteger

  • last_seq

    whole numberinteger

05Messages, inbox conversations and saved replies

data/inbox.csvdata/inbox.json

Inbox messages to and from guests.Columns: 8
  • id

    id (UUID)uuid

  • reservation_id

    id (UUID)uuid

    may be empty · points to bookings.id

  • guest_id

    id (UUID)uuid

    may be empty · points to guests.id

  • direction

    textcharacter varying(10)

    inbound from the guest, outbound to the guest.

  • channel

    textcharacter varying(20)

  • status

    textcharacter varying(20)

  • body

    texttext

  • created_at

    date and time (UTC)timestamp with time zone

data/guest-mail.csvdata/guest-mail.json

The automatic e-mails to guests: their text, and when they were sent.Columns: 13
  • id

    id (UUID)uuid

  • reservation_id

    id (UUID)uuid

    may be empty · points to bookings.id

  • guest_id

    id (UUID)uuid

    may be empty · points to guests.id

  • kind

    value from a listmessage_kind

    one of: booking_confirmation, pre_arrival, post_stay, cancellation, booking_request, checkin_reminder

  • channel

    textcharacter varying(20)

  • to_email

    textcharacter varying(255)

    may be empty

  • subject

    texttext

    may be empty

  • body

    texttext

    may be empty

  • status

    value from a listmessage_status

    one of: ready, sent, failed, skipped

  • error

    texttext

    may be empty

  • scheduled_for

    datedate

    may be empty

  • sent_at

    date and time (UTC)timestamp with time zone

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

data/saved-replies.csvdata/saved-replies.json

Saved replies.Columns: 6
  • id

    id (UUID)uuid

  • title

    textcharacter varying(80)

  • body

    texttext

  • sort_order

    whole numberinteger

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/message-templates.csvdata/message-templates.json

The templates of the automatic messages, and when each is sent.Columns: 8
  • id

    id (UUID)uuid

  • kind

    value from a listmessage_kind

    one of: booking_confirmation, pre_arrival, post_stay, cancellation, booking_request, checkin_reminder

  • enabled

    true/falseboolean

  • lead_days

    whole numberinteger

  • subject

    texttext

  • body

    texttext

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

06Reviews

data/reviews.csvdata/reviews.json

The reviews guests left after their stay.Columns: 7
  • id

    id (UUID)uuid

  • reservation_id

    id (UUID)uuid

    points to bookings.id

  • guest_id

    id (UUID)uuid

    may be empty · points to guests.id

  • rating

    whole numbersmallint

  • comment

    texttext

    may be empty

  • locale

    textcharacter varying(8)

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

07Cleaning tasks

data/cleaning-tasks.csvdata/cleaning-tasks.json

Cleaning tasks, with their checklist and who does them.Columns: 14
  • id

    id (UUID)uuid

  • room_id

    id (UUID)uuid

    points to units.id

  • reservation_id

    id (UUID)uuid

    may be empty · points to bookings.id

  • type

    value from a listhousekeeping_type

    one of: standard, deep, turndown, inspect, restock

  • status

    value from a listhousekeeping_status

    one of: pending, in_progress, inspected, confirmed

  • priority

    value from a listtask_priority

    one of: low, normal, high, urgent

  • scheduled_date

    datedate

    may be empty

  • assigned_to

    id (UUID)uuid

    may be empty · points to team.id

  • assign_mode

    textcharacter varying(10)

    may be empty

  • notes

    texttext

    may be empty

  • checklist

    JSONjsonb

    may be empty

  • completed_at

    date and time (UTC)timestamp with time zone

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

08Property owners and owner statements

data/owners.csvdata/owners.json

Property owners, with their contact and bank details and their commission.Columns: 10
  • id

    id (UUID)uuid

  • name

    textcharacter varying(200)

  • email

    textcharacter varying(255)

    may be empty

  • phone

    textcharacter varying(50)

    may be empty

  • iban

    textcharacter varying(50)

    may be empty

  • commission_pct

    decimal numbernumeric(5,2)

  • notes

    texttext

    may be empty

  • is_active

    true/falseboolean

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

data/owner-units.csvdata/owner-units.json

Which owner owns which unit.Columns: 3
  • room_id

    id (UUID)uuid

    points to units.id

  • owner_id

    id (UUID)uuid

    points to owners.id

  • created_at

    date and time (UTC)timestamp with time zone

owner-statements/<owner>.csvowner-statements/<owner>.json

Each owner's statements, month by month: revenue, commission, expenses and payout, with the bookings and expenses behind them.Fields: 23
owner-statements/<owner>.json
  • owner

    text

  • months

    list of: object

months[]
  • month

    text

    YYYY-MM. A stay counts in the month it checks out.

  • revenue

    decimal number

  • commissionPct

    decimal number

  • commission

    decimal number

  • expenses

    decimal number

  • payout

    decimal number

    Revenue minus commission and expenses; it may be negative.

  • nights

    whole number

  • bookings

    list of: object

  • expenseLines

    list of: object

bookings[]
  • confirmation

    text

  • unit

    text

  • guest

    text

  • checkIn

    date

  • checkOut

    date

  • nights

    whole number

  • revenue

    decimal number

expenseLines[]
  • date

    date

  • category

    text

  • description

    text

    may be empty

  • unit

    text

  • amount

    decimal number

09Team members' profiles

data/team.csvdata/team.json

Team members' profiles.Columns: 10
  • id

    id (UUID)uuid

  • first_name

    textcharacter varying(100)

  • last_name

    textcharacter varying(100)

  • email

    textcharacter varying(255)

  • phone

    textcharacter varying(50)

    may be empty

  • role

    value from a liststaff_role

    one of: front_desk, housekeeping, maintenance, manager, admin, revenue

  • department

    textcharacter varying(100)

    may be empty

  • is_active

    true/falseboolean

  • hire_date

    datedate

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

Columns of this table that are not exported: 3 (our own records of the account and unused fields).

10Signed rental agreements

data/agreements.csvdata/agreements.json

Each signed rental agreement: the text the guest signed, its SHA-256 fingerprint, and when and from where it was signed.Columns: 9
  • reservation_id

    id (UUID)uuid

    points to bookings.id

  • signer_name

    textcharacter varying(200)

  • signed_at

    date and time (UTC)timestamp with time zone

  • locale

    textcharacter varying(10)

  • body

    JSONjsonb

    The agreement exactly as the guest signed it.

  • body_sha256

    textcharacter(64)

    SHA-256 of the signed text, to show it has not changed.

  • ip

    textcharacter varying(64)

    may be empty

  • user_agent

    textcharacter varying(400)

    may be empty

  • created_at

    date and time (UTC)timestamp with time zone

11Your organization's settings, booking page and branding

data/property.csvdata/property.json

The organization's settings: booking-page content, payment and check-in options, messaging and branding. One row.Columns: 56
  • id

    id (UUID)uuid

  • name

    textcharacter varying(255)

  • address

    texttext

  • city

    textcharacter varying(100)

  • country

    textcharacter varying(100)

  • phone

    textcharacter varying(50)

    may be empty

  • email

    textcharacter varying(255)

    may be empty

  • website

    textcharacter varying(255)

    may be empty

  • timezone

    textcharacter varying(50)

  • currency

    textcharacter varying(3)

  • date_format

    texttext

    may be empty

  • host_locale

    texttext

    may be empty

  • check_in_time

    textcharacter varying(5)

  • check_out_time

    textcharacter varying(5)

  • tax_rate

    decimal numbernumeric(5,2)

  • description

    texttext

    may be empty

  • amenities

    JSONjsonb

  • cover_image_url

    texttext

    may be empty

  • photos

    JSONjsonb

    The listing's photo addresses, in order.

  • logo_url

    texttext

    may be empty

  • accent_color

    textcharacter varying(9)

    may be empty

  • theme

    texttext

    may be empty

  • public_slug

    textcharacter varying(60)

    may be empty

  • direct_booking_enabled

    true/falseboolean

  • house_rules

    texttext

  • cancellation_terms

    texttext

  • payment_methods

    texttext

  • payment_policy

    texttext

  • payment_mode

    texttext

  • payment_deposit_pct

    whole numberinteger

  • payment_hold_minutes

    whole numberinteger

  • payment_instructions

    texttext

    may be empty

  • payment_bank_holder

    texttext

    may be empty

  • payment_bank_account

    texttext

    may be empty

  • payment_bank_name

    texttext

    may be empty

  • payment_bank_swift

    texttext

    may be empty

  • online_checkin

    true/falseboolean

  • mrz_scan

    true/falseboolean

  • code_after_checkin

    true/falseboolean

  • rental_agreement

    true/falseboolean

  • agreement_terms

    texttext

  • auto_reply_enabled

    true/falseboolean

  • auto_reply_from

    time of daytime without time zone

  • auto_reply_to

    time of daytime without time zone

  • auto_reply_body

    texttext

    may be empty

  • whatsapp_number

    textcharacter varying(40)

    may be empty

  • messenger_page

    textcharacter varying(160)

    may be empty

  • viber_number

    textcharacter varying(40)

    may be empty

  • instagram_handle

    textcharacter varying(160)

    may be empty

  • telegram_handle

    textcharacter varying(160)

    may be empty

  • morning_brief

    true/falseboolean

  • created_at

    date and time (UTC)timestamp with time zone

  • updated_at

    date and time (UTC)timestamp with time zone

  • request_expiry_on

    true/falseboolean

  • request_expiry_hours

    whole numberinteger

  • request_expiry_since

    date and time (UTC)timestamp with time zone

    may be empty

Columns of this table that are not exported: 23 (credentials and private links, billing and plan records, and our own records of the account).

data/api-keys.csvdata/api-keys.json

API keys, by name and prefix. The keys themselves are never stored.Columns: 7
  • id

    id (UUID)uuid

  • name

    textcharacter varying(80)

  • prefix

    textcharacter varying(20)

    The key's first characters, to tell keys apart; the key itself is never stored.

  • scopes

    list of: texttext[]

  • created_at

    date and time (UTC)timestamp with time zone

  • last_used_at

    date and time (UTC)timestamp with time zone

    may be empty

  • revoked_at

    date and time (UTC)timestamp with time zone

    may be empty

Columns of this table that are not exported: 2 (credentials and private links and our own records of the account).

data/webhooks.csvdata/webhooks.json

Webhook endpoints and the events each one receives.Columns: 8
  • id

    id (UUID)uuid

  • url

    texttext

  • events

    list of: texttext[]

  • active

    true/falseboolean

  • last_delivery_at

    date and time (UTC)timestamp with time zone

    may be empty

  • last_status

    whole numberinteger

    may be empty

  • failures

    whole numberinteger

  • created_at

    date and time (UTC)timestamp with time zone

Columns of this table that are not exported: 1 (credentials and private links).

12Analytics reports

reports/analytics-365-days.csvreports/analytics-365-days.json

The analytics report for the last 365 days: a summary, then months, channels and units.Fields: 4
reports/analytics-365-days.json
  • title

    text

  • columns

    list of: text

  • rows

    list of: list

    One list of cells per row.

  • more

    list of: object

    may be empty

    The further sections — months, channels and units — each with its own title, columns and rows.

Exports from each screen

Each screen's Export button gives its list as it is shown, with headings in the language of whoever exports it. These files are for reading and for an accountant; to move to another system, use the full export.

  • Bookings: The bookings in the list: number, guest and contact, unit, dates and nights, status, channel, guests, amount and the day it was booked.
  • Guests: The guest book: name, contact, nationality, loyalty, stays, total spent and the day each guest was added.
  • Registration: One month's guest register: each person's stay, identity document and tourist tax, and who files it.
  • Payments: The month's payments and expenses, the guests' payments, and the month's totals.
  • Invoices: Issued invoices: number, dates, recipient, stay, net amount, tax, total, currency and status.
  • Owners: One owner's statement for one month: the bookings, the expenses and the summary.
  • Analytics: The analytics report for the chosen period: a summary, then months, channels and units.

What is never exported

Never exported: our security logs, rate-limit records and internal operational records, and credentials — keys, signing secrets, private links and the booking-delete code.

Public API

The API lets a channel manager, a website or other software read and change one property's units, bookings, availability and prices. It is part of Pro and above and answers only while the trial or subscription is active: the plan is checked on every request.

Create a key in Settings → API and webhooks. It begins with sw_live_ and is shown once: only its SHA-256 is stored, so a lost key cannot be recovered — revoke it and create another. Send it with every request as Authorization: Bearer <key>.

https://staywick.com/api/v1
Authorization: Bearer sw_live_…

Every key can read. A key with the write scope can also create and cancel bookings and set prices and closed nights.

Each key may make 120 requests a minute; above that the answer is 429.

Requests and answers are JSON. Dates are YYYY-MM-DD, times ISO 8601 in UTC, and amounts are text with two decimals, such as "120.00", so no total is rounded. Everything is limited to the key's property: an id from another property answers 404. Answers are never cached.

Errors

Every failure has the same body. The message, in English, says what was wrong.

  • 401 unauthorizedNo key, an unknown key or a revoked one.
  • 403 forbiddenThe key does not have the scope, or the plan does not include the API.
  • 404 not_foundNo such booking or unit in this property.
  • 409 conflictThe nights are taken or closed, or the contact details belong to another guest.
  • 422 invalid_requestThe query or the body is not valid; the message says why.
  • 429 rate_limitedToo many requests in a minute.
  • 500 server_errorSomething failed on our side.
{
  "error": {
    "code": "forbidden",
    "message": "This key does not have the `write` scope."
  }
}

Objects

booking
  • id

    id (UUID)

  • confirmationNumber

    text

    may be empty

  • unitId

    id (UUID)

    may be empty

  • unitName

    text

    may be empty

  • arrival

    date

    may be empty

  • departure

    date

    may be empty

    The day the guest leaves; that night is not part of the stay.

  • nights

    whole number

    may be empty

  • status

    value from a list

    may be empty

    one of: tentative, confirmed, checked_in, checked_out, cancelled, no_show

  • guestName

    text

    may be empty

    null for a stay with no guest, such as a block or an import.

  • guestEmail

    text

    may be empty

  • guestPhone

    text

    may be empty

  • adults

    whole number

    may be empty

  • children

    whole number

    may be empty

  • total

    decimal number

    may be empty

    The stay's total, as text with two decimals.

  • currency

    text

    may be empty

  • channel

    value from a list

    may be empty

    one of: direct, booking_com, expedia, airbnb, hotels_com, gds, phone, walk_in

  • createdAt

    date and time (UTC)

    may be empty

  • updatedAt

    date and time (UTC)

    may be empty

unit
  • id

    id (UUID)

  • name

    text

    The unit's name, as the host wrote it.

  • maxGuests

    whole number

    may be empty

  • minNights

    whole number

    may be empty

  • basePrice

    decimal number

    may be empty

    The unit type's price when the unit has none of its own.

  • currency

    text

    may be empty

night
  • date

    date

  • available

    true/false

  • reason

    value from a list

    may be empty

    one of: booked, blocked

    booked or blocked; null when the night is free.

rate
  • unitId

    id (UUID)

  • date

    date

  • price

    decimal number

    may be empty

    In GET /api/v1/rates, what the night costs, with the pricing rules applied. In rates.updated, the price before the rules (see Webhooks).

  • blocked

    true/false

    true when the host closed the night.

Endpoints

GET /api/v1/units

Key scope: read

Every unit of the property. basePrice falls back to the unit type's price, as on the booking page.

Answer · 200

{
  "units": [
    {
      "id": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
      "name": "Apartment 3",
      "maxGuests": 4,
      "minNights": 2,
      "basePrice": "80.00",
      "currency": "EUR"
    }
  ]
}

GET /api/v1/bookings

Key scope: read

Stays that overlap from–to, latest arrival first. status takes a comma-separated list; limit is at most 500 (default 100); offset pages on.

Query parameters

  • from

    date

  • to

    date

  • status

    list of: value from a list

    one of: tentative, confirmed, checked_in, checked_out, cancelled, no_show

    Comma-separated.

  • limit

    whole number

    default: 100

  • offset

    whole number

    default: 0

Answer · 200

{
  "bookings": [
    {
      "id": "b3a91c08-6d24-4e57-a0b1-c2d3e4f5a6b7",
      "confirmationNumber": "AP-7KQ2ZX",
      "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
      "unitName": "Apartment 3",
      "arrival": "2026-08-01",
      "departure": "2026-08-05",
      "nights": 4,
      "status": "confirmed",
      "guestName": "Jana Marić",
      "guestEmail": "jana@example.com",
      "guestPhone": "+38765123456",
      "adults": 2,
      "children": 1,
      "total": "420.00",
      "currency": "EUR",
      "channel": "booking_com",
      "createdAt": "2026-07-02T09:14:00Z",
      "updatedAt": "2026-07-02T09:14:00Z"
    }
  ],
  "limit": 100,
  "offset": 0
}

GET /api/v1/bookings/{id}

Key scope: read

One stay, or 404.

Answer · 200

{
  "booking": {
    "id": "b3a91c08-6d24-4e57-a0b1-c2d3e4f5a6b7",
    "confirmationNumber": "AP-7KQ2ZX",
    "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
    "unitName": "Apartment 3",
    "arrival": "2026-08-01",
    "departure": "2026-08-05",
    "nights": 4,
    "status": "confirmed",
    "guestName": "Jana Marić",
    "guestEmail": "jana@example.com",
    "guestPhone": "+38765123456",
    "adults": 2,
    "children": 1,
    "total": "420.00",
    "currency": "EUR",
    "channel": "booking_com",
    "createdAt": "2026-07-02T09:14:00Z",
    "updatedAt": "2026-07-02T09:14:00Z"
  }
}

POST /api/v1/bookings

Key scope: write

Creates a stay and answers 201 with it. Staywick works out the price, as on the booking page; it cannot be sent. Without guest the stay is a block that holds the nights. Nights already taken or closed answer 409, and so does an e-mail address or phone number that belongs to another guest. A stay is at most 180 nights and starts at most 730 days ahead; past stays may be imported.

Body

  • unitId

    id (UUID)

    required

  • arrival

    date

    required

  • departure

    date

    required

  • adults

    whole number

    default: 1

  • children

    whole number

    default: 0

  • status

    value from a list

    default: confirmed

    one of: tentative, confirmed

  • channel

    value from a list

    default: direct

    one of: direct, booking_com, expedia, airbnb, hotels_com, gds, phone, walk_in

  • note

    text

    at most 2,000 characters

    Stored as the booking's special requests.

  • locale

    value from a list

    one of: en, hr, bs, sr, me, tr, de, it, es, el, pl, hu

    The language of the guest's e-mails. Left out, the phone number's country code decides.

  • guest

    object

    may be empty

    Leave it out for a block without a guest.

  • guest.firstName

    text

    required

  • guest.lastName

    text

  • guest.email

    text

  • guest.phone

    text

Request

{
  "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
  "arrival": "2026-08-01",
  "departure": "2026-08-05",
  "adults": 2,
  "children": 1,
  "status": "confirmed",
  "channel": "booking_com",
  "guest": {
    "firstName": "Jana",
    "lastName": "Marić",
    "email": "jana@example.com",
    "phone": "+38765123456"
  },
  "note": "Late arrival, about 23:00",
  "locale": "de"
}

Answer · 201

{
  "booking": {
    "id": "b3a91c08-6d24-4e57-a0b1-c2d3e4f5a6b7",
    "confirmationNumber": "AP-7KQ2ZX",
    "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
    "unitName": "Apartment 3",
    "arrival": "2026-08-01",
    "departure": "2026-08-05",
    "nights": 4,
    "status": "confirmed",
    "guestName": "Jana Marić",
    "guestEmail": "jana@example.com",
    "guestPhone": "+38765123456",
    "adults": 2,
    "children": 1,
    "total": "420.00",
    "currency": "EUR",
    "channel": "booking_com",
    "createdAt": "2026-07-02T09:14:00Z",
    "updatedAt": "2026-07-02T09:14:00Z"
  }
}

DELETE /api/v1/bookings/{id}

Key scope: write

Cancels the stay and frees its nights; nothing is deleted. A second call answers 200 with cancelled: false.

Answer · 200

{
  "booking": {
    "id": "b3a91c08-6d24-4e57-a0b1-c2d3e4f5a6b7",
    "confirmationNumber": "AP-7KQ2ZX",
    "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
    "unitName": "Apartment 3",
    "arrival": "2026-08-01",
    "departure": "2026-08-05",
    "nights": 4,
    "status": "cancelled",
    "guestName": "Jana Marić",
    "guestEmail": "jana@example.com",
    "guestPhone": "+38765123456",
    "adults": 2,
    "children": 1,
    "total": "420.00",
    "currency": "EUR",
    "channel": "booking_com",
    "createdAt": "2026-07-02T09:14:00Z",
    "updatedAt": "2026-07-02T09:14:00Z"
  },
  "cancelled": true
}

GET /api/v1/availability

Key scope: read

Which nights are free, for one unit or all: from (default today) to (default 90 days later), at most 400 nights. booked covers the host's own stays and stays imported from other channels; blocked is a night the host closed.

Query parameters

  • unit

    id (UUID)

  • from

    date

  • to

    date

Answer · 200

{
  "from": "2026-08-01",
  "to": "2026-08-04",
  "units": [
    {
      "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
      "unitName": "Apartment 3",
      "nights": [
        {
          "date": "2026-08-01",
          "available": false,
          "reason": "booked"
        },
        {
          "date": "2026-08-02",
          "available": false,
          "reason": "blocked"
        },
        {
          "date": "2026-08-03",
          "available": true,
          "reason": null
        }
      ]
    }
  ]
}

GET /api/v1/rates

Key scope: read

What each night costs, with the host's pricing rules applied, for one unit or all; at most 400 nights, with the same defaults as availability.

Query parameters

  • unit

    id (UUID)

  • from

    date

  • to

    date

Answer · 200

{
  "from": "2026-08-01",
  "to": "2026-08-03",
  "units": [
    {
      "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
      "unitName": "Apartment 3",
      "minNights": 2,
      "currency": "EUR",
      "rates": [
        {
          "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
          "date": "2026-08-01",
          "price": "120.00",
          "blocked": false
        },
        {
          "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
          "date": "2026-08-02",
          "price": "80.00",
          "blocked": true
        }
      ]
    }
  ]
}

PUT /api/v1/rates

Key scope: write

Sets one unit's prices and closed nights, at most 400 nights a request. Each row replaces the night: a row without price clears that night's price, and a row without blocked opens it.

Body

  • unitId

    id (UUID)

    required

  • rates

    list of: object

    required

  • rates[].date

    date

    required

  • rates[].price

    decimal number

    may be empty

    Left out, the night costs the unit's price again.

  • rates[].blocked

    true/false

    Left out, the night is open.

Request

{
  "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
  "rates": [
    {
      "date": "2026-08-01",
      "price": "140.00"
    },
    {
      "date": "2026-08-02",
      "price": "140.00",
      "blocked": false
    },
    {
      "date": "2026-08-03",
      "blocked": true
    }
  ]
}

Answer · 200

{
  "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
  "written": 3
}

Webhooks

Add an endpoint in Settings → API and webhooks, choose its events and copy the signing secret, which is shown once. A database trigger records each event when the change is saved, whichever screen, import or API call made it: every change to a booking, and every change to a night's own price or to whether it is closed. Other price changes send no event; see rates.updated below.

Events

  • reservation.created — New bookings
  • reservation.updated — Changed bookings
  • reservation.cancelled — Cancelled bookings
  • rates.updated — Prices and closed nights
  • ping — Sent only by the Test button.

Every delivery is a POST with the body below: data is the booking exactly as GET /api/v1/bookings/{id} returns it, or, for rates.updated, one rate.

{
  "event": "reservation.created",
  "data": {
    "id": "b3a91c08-6d24-4e57-a0b1-c2d3e4f5a6b7",
    "confirmationNumber": "AP-7KQ2ZX",
    "unitId": "6c1f2a9e-3b4d-4e5f-8a6b-7c8d9e0f1a2b",
    "unitName": "Apartment 3",
    "arrival": "2026-08-01",
    "departure": "2026-08-05",
    "nights": 4,
    "status": "confirmed",
    "guestName": "Jana Marić",
    "guestEmail": "jana@example.com",
    "guestPhone": "+38765123456",
    "adults": 2,
    "children": 1,
    "total": "420.00",
    "currency": "EUR",
    "channel": "booking_com",
    "createdAt": "2026-07-02T09:14:00Z",
    "updatedAt": "2026-07-02T09:14:00Z"
  }
}

rates.updated is sent when a night's own entry on the calendar changes: a price is set or cleared for it, or it is closed or opened. Its price is that night's own price, which is final, or else the unit's price before the pricing rules: no season or weekend rule is in it, while GET /api/v1/rates applies them. A change to a pricing rule or to a unit's price sends no rates.updated, so software that passes prices on should take them from GET /api/v1/rates and read them again regularly.

Headers

  • X-Staywick-EventThe event's name.
  • X-Staywick-TimestampWhen it was sent, in Unix seconds.
  • X-Staywick-SignatureHMAC-SHA256 of the timestamp and the body, with the signing secret:sha256=<hmac-sha256(secret, "<timestamp>.<body>")>
  • X-Staywick-DeliveryThe delivery's id, the same on every retry.

Events are sent moments after the change, and a scheduled run every few minutes sends anything still waiting. Answer with any 2xx within 10 seconds. Anything else is tried again, after these intervals: 1 minute, 5 minutes, 30 minutes, 2 hours, and 12 hours. Then it is given up, and Settings shows the endpoint's failures.

Every retry carries the same X-Staywick-Delivery, so handle each delivery once.

To check a delivery, compute the signature over the timestamp, a dot and the body exactly as received, and refuse old timestamps. In Node:

import crypto from "node:crypto";

export function verify(req, rawBody, secret) {
  const ts = req.headers["x-staywick-timestamp"];
  const sent = req.headers["x-staywick-signature"] ?? "";
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;

  const mine = `sha256=${crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`, "utf8")
    .digest("hex")}`;

  const a = Buffer.from(mine);
  const b = Buffer.from(String(sent));
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}