Overview

The Accommodation module is the core of Ananas GDS for hotels, resorts, and apartment complexes. An accommodation account can manage one or more Properties, and each property is a self-contained data unit that holds all the information a tour operator or travel agent needs to work with that property.

Each property contains:

  • A complete fact sheet split across 12+ structured categories covering everything from general information and location through to rooms, food & beverage, sports, entertainment, and policies.
  • A photo gallery with CDN-hosted images, category tagging, and a selectable feature image.
  • A stop sale calendar for managing availability, allotments, and room-level blockouts (handled by the Stop Sale module — see Stop Sale).
  • Partner connections via active contracts, controlling which tour operators receive data and which categories they can read.
  • A publishing workflow that governs when edited fact sheet data becomes visible to connected partners.

Accommodation accounts are the data-producing side of the platform. Everything they enter flows downstream to tour operators who consume it via authenticated API calls using partner tokens.

Property Model

A Property record represents a single accommodation unit — a hotel, resort, apartment block, or villa complex. It is the top-level anchor for all fact sheet data, photos, and partner connections.

user FK(User) The accommodation account owner. All properties are scoped to this user.
hotel_name CharField(200) Display name of the property shown across the platform and in published fact sheets.
country CharField(2) ISO 3166-1 alpha-2 country code (e.g. DE, TR, ES).
state CharField(3) State or region code within the country.
city CharField(100) City or locality name.
hotel_logo URLField CDN URL of the property logo image (hosted via ImageKit).
logo_id CharField ImageKit file ID for the logo — used for deletion and transformation operations.
hotel_image IntegerField Primary key of the gallery photo designated as the featured image for this property.
date_created DateTimeField Timestamp when the property record was first created. Set automatically on insert.
date_update DateTimeField Timestamp of the most recent update to the property record. Updated automatically on every save.

Property Access Rules

Access to property records is controlled at two levels:

  • Owner: the account manager can access all properties belonging to their account.
  • Sub-user: can only access properties explicitly granted via a SubUserPropertyAccess record. If no access rows exist for a sub-user, they see all properties of their manager as a fallback.

Property Endpoints

All property endpoints require session or token authentication. Sub-users are filtered to their permitted property set automatically.

GET /api/facts/properties/ 🔐 Auth required

Returns a list of all properties accessible to the authenticated user. Manager accounts see all their properties; sub-users see only granted properties.

GET /api/facts/property/{id}/ 🔐 Auth required

Returns the detail record for a single property by ID.

POST /api/facts/property/create/ 🔐 Auth required

Creates a new property. After creation, call /api/facts/init-facts-info/{info_id}/ to initialise all fact sheet category records for the new property.

PUT /api/facts/property/update/{id}/ 🔐 Auth required

Full update of a property record. Requires all fields to be present.

DELETE /api/facts/property/delete/{id}/ 🔐 Auth required

Permanently deletes a property and all associated fact sheet data, photos, and partner connections. This action cannot be undone.

GET /api/facts/properties/search/ 🔐 Auth required

Full-text search across property names and locations. Accepts a q query parameter.

Fact Sheet

A fact sheet is the complete, structured description of a property. It is divided into independent categories, each of which has its own endpoint. Categories are separated into two types depending on how they relate to the property: OneToOne records (one per property) and Array records (multiple rows, replaced on save).

All fact sheet data is scoped to a property via a hotel field. On GET requests this is passed as a query parameter (?hotel={property_id}); on POST requests the property ID is included in the request body.

Factory View Pattern

Fact sheet endpoints are generated by internal factory functions (_facts_view and _array_facts_view). Each handles combined GET and POST on a single URL, with the model and serializer injected at registration time. This is why all OneToOne endpoints share identical request/response conventions.

OneToOne Fact Categories

These categories hold a single record per property. A GET retrieves the existing record; a POST creates or overwrites it. All endpoints accept GET ?hotel={property_id} and a POST body that includes the property ID.

Category Endpoint Description
Main Info GET/POST /api/facts/main-info/ Hotel name, star category, opening year, total units, total area, general description, and common property information.
Location GET/POST /api/facts/location/ GPS coordinates (lat/lon), full address, environment type, and distances to airport, city centre, beach, and key attractions.
Facility GET/POST /api/facts/facility/ Pool details (count, heated, outdoor/indoor), spa, fitness centre, beach access, general amenities checklist.
Food & Beverage GET/POST /api/facts/food/ Available board types (BB, HB, FB, AI), meal service times, total restaurant count, dietary options.
All Inclusive GET/POST /api/facts/all-inclusive/ AI package scope and inclusions, premium brand availability, soft/alcoholic beverages, snack times.
Sports & Wellness GET/POST /api/facts/sports-wellness/ Land sports facilities, water sports availability, tennis courts, spa treatment menu, wellness services.
Children GET/POST /api/facts/children/ Mini club details, dedicated kids pool, childcare services, accepted age ranges, child-specific programs.
Entertainment GET/POST /api/facts/entertainment/ Evening shows, animation team, live music schedule, daytime activity programming.
Additional GET/POST /api/facts/additional/ Car rental, transfer services, laundry facilities, business centre, conference rooms, parking.
Partner GET/POST /api/facts/partner/ Tour operator-specific supplementary information not covered by standard categories.

Array Fact Categories

Array categories hold multiple rows for a single property. Unlike OneToOne categories, a POST to an array endpoint deletes all existing rows for that property and recreates them from the submitted payload. This means you must always submit the complete desired set of records, not a diff.

Full Replacement on POST

Array endpoints do not support partial updates. Posting a list of two restaurants when three already exist will result in only two records after the save. Always submit the full list of records you want to persist.

Category Endpoint Description
Maintenance Periods GET/POST /api/facts/maintenance/ Annual closure windows and renovation periods. Each record has a start date, end date, and description.
Restaurants GET/POST /api/facts/facility/restaurants/ Individual restaurant detail: name, cuisine type, seating capacity, service hours, dress code, reservation policy.
Bars GET/POST /api/facts/facility/bars/ Bar details: name, type (pool bar, lobby bar, etc.), service hours, location on property.

Rooms

Room types use a different pattern from the two above. Rather than full-replacement on save, rooms support individual upsert (create-or-update) and single-row delete. This allows hotel staff to add, edit, or remove a single room type without affecting the rest.

GET /api/facts/rooms/?hotel={id} 🔐 Auth required

Returns all room type records for the specified property.

POST /api/facts/rooms/ 🔐 Auth required

Upserts a single room record. Include id: 0 in the payload to create a new room. Include an existing room's id to update it in-place.

DELETE /api/facts/rooms/delete/?id={room_id} 🔐 Auth required

Deletes a single room type record by its ID.

Room records include the following key fields:

  • name — room type name as displayed to partners
  • category — room class (standard, superior, suite, etc.)
  • count — total number of units of this type at the property
  • size_sqm — floor area in square metres
  • beds — bed configuration description
  • view — view type (sea view, garden view, pool view, etc.)
  • floor info — available floor levels
  • features — amenities checklist (balcony, air conditioning, safe, etc.)

Rooms and Stop Sale

The Room model is imported from info.models into the stop_sale app. Room records serve as the base unit for the stop sale calendar — each room type has its own set of availability events. Deleting a room type will also remove its associated stop sale events.

Each property has an independent photo gallery. Photos are stored via ImageKit CDN, which provides fast delivery, on-the-fly transformations, and permanent deletion via file ID. The gallery supports categorisation, metadata, and a single designated feature image shown as the property thumbnail across the platform.

GET /api/facts/property/{id}/gallery/ 🔐 Auth required

Returns all photo records for the specified property, including CDN URLs, metadata, and the featured flag.

POST /api/facts/property/{id}/gallery/create/ 🔐 Auth required

Uploads a new photo to ImageKit and creates a gallery record. The request must be a multipart/form-data submission. Returns the new photo record including the assigned CDN URL.

PATCH /api/facts/property/gallery/{prop_id}/{photo_id}/update/ 🔐 Auth required

Updates metadata for an existing photo: title, description, and category tags. Does not replace the image file itself.

DELETE /api/facts/property/gallery/{prop_id}/{photo_id}/delete/ 🔐 Auth required

Deletes the photo record and removes the image from ImageKit using the stored file ID. This action is permanent and cannot be undone.

POST /api/facts/property/gallery/featured-image/ 🔐 Auth required

Sets a specific photo as the property's feature image. Updates Property.hotel_image to point to the selected photo ID. Only one photo can be featured at a time.

GET /api/facts/count-images/ 🔐 Auth required

Returns a count of photos per property for the authenticated account. Useful for dashboard display and quota checks.

Accommodation managers can export or email the photo gallery for a property.

GET /api/facts/download-photos/{property_id}/ 🔐 Auth required

Downloads all gallery photos for the property as a single ZIP archive. Photos are fetched from ImageKit and bundled server-side before streaming to the client.

POST /api/facts/send-photos/{mailing_list_id}/acc/{property_id}/ 🔐 Auth required

Sends the photo gallery to all recipients in a saved mailing list. Attach the mailing_list_id of the target list and the property_id of the property whose photos you want to distribute.

Partner Photo Access

Tour operators with an active partner token access photos through a separate public endpoint. No session authentication is required — the token itself is the credential.

GET /api/facts/partners-photos/{token}/ 🗝 Token required

Returns all published gallery photos for the property associated with the given partner token. The response includes CDN URLs suitable for direct display or download.

Photo Categories

Photos support category tags such as exterior, lobby, room, pool, restaurant, and spa. Partners can filter the returned gallery by category when building their catalogues.

Publishing & Approval Workflow

Fact sheet data entered by hotel staff is not immediately visible to partners. Before partner API calls return updated content, the fact sheet must go through a publish and approval workflow. This ensures data quality and prevents incomplete edits from being distributed to tour operators.

Publishing States

A fact sheet version moves through four states:

  1. Draft — the fact sheet has been edited by hotel staff but not yet submitted. Changes are stored and visible in the hotel dashboard but not distributed to partners.
  2. Pending — the hotel has submitted the fact sheet for review. A pending record is created and awaits approval by a platform manager or admin.
  3. Approved — a manager or admin has approved the submitted version. The fact sheet becomes the live published version and is immediately available to partners via the API.
  4. Declined — a manager or admin has declined the submission. The hotel receives feedback, revises the fact sheet, and resubmits.

Publishing Endpoints

POST /api/facts/property/{id}/publish/create/ 🔐 Auth required

Submits the current draft fact sheet for this property for review. Moves the state to Pending and creates a publish record. Requires the publishing_manager permission flag for sub-users.

GET /api/facts/property/{id}/publish/{info_type}/ 🔐 Auth required

Returns the currently approved (live) published facts for a specific category (info_type) of the given property. Use this to see exactly what partners receive.

GET /api/facts/last-publish-date/ 🔐 Auth required

Returns the date and time of the most recent approved publish for each property belonging to the authenticated account. Accepts an optional hotel query parameter to filter to a single property.

Admin Review Endpoints

These endpoints are restricted to platform staff with the relevant admin permission.

GET /api/facts/publish/pending/ 🛡 Admin required

Lists all pending publish requests across all accommodation accounts. Returns property name, submission timestamp, and submitting user.

GET /api/facts/publish/pending/{id}/preview/ 🛡 Admin required

Returns a full preview of the fact sheet changes included in a specific pending publish request, compared against the currently live version.

POST /api/facts/publish/pending/{id}/approve/ 🛡 Admin required

Approves a pending publish. The submitted fact sheet version immediately becomes live. Partners accessing the API after approval will receive the updated data.

POST /api/facts/publish/pending/{id}/decline/ 🛡 Admin required

Declines a pending publish. An optional reason can be included in the request body. The property's fact sheet returns to Draft state and the hotel is notified.

Partner Access to Published Facts

GET /api/facts/published-partners/{token}/ 🗝 Token required

Returns the full approved fact sheet for the property associated with the given partner token. Only approved data is returned — draft or pending versions are never exposed through this endpoint. This is the primary endpoint tour operators use to pull structured property data.

Data Not Yet Published

If a property has never been through the publishing workflow, or if all submissions have been declined, the partner API will return an empty data set or a specific not_published status. Tour operators should handle this case gracefully in their integration.

Export & Distribution

Accommodation providers can export and distribute fact sheet data outside the platform for partners who are not yet using the Ananas GDS API directly. Two distribution methods are available: PDF download and email delivery to a mailing list.

GET /api/facts/download-facts/{property_id}/ 🔐 Auth required

Generates and downloads a PDF fact sheet for the property. The PDF is built from the currently approved (published) fact sheet data. Layout and branding follow the platform's PDF template engine. Requires the publishing_manager permission flag for sub-users.

POST /api/facts/send-facts/{mailing_list_id}/sheet/{property_id}/ 🔐 Auth required

Emails a PDF fact sheet to all recipients saved in the specified mailing list. The mailing_list_id must belong to the authenticated account. Delivery is handled asynchronously via Celery. Requires the publishing_manager permission flag for sub-users.

Mailing Lists

Mailing lists are managed separately within the Accommodation dashboard. A list holds a named set of email addresses. One list can be used across multiple send operations for both fact sheets and photo galleries.

Initialise Fact Sheet

When a new property is created, its associated fact sheet category records do not exist yet. Before any category data can be saved, all fact records must be initialised for the property. This is done by calling the init endpoint immediately after the property creation step.

POST /api/facts/init-facts-info/{info_id}/ 🔐 Auth required

Creates empty placeholder records for all OneToOne fact categories linked to the property identified by info_id. This endpoint is idempotent — calling it on a property that already has initialised records will not overwrite existing data.

GET /api/facts/main-info/json/{info_id}/ 🔐 Auth required

Returns the complete fact sheet for the given property as a single JSON object, with all categories merged under their respective keys. Useful for generating exports, previews, and diagnostic checks of the full property data payload.

New Property Workflow

The recommended sequence for creating a new property is: (1) POST to /api/facts/property/create/ — receive the new property ID and its associated info_id. (2) POST to /api/facts/init-facts-info/{info_id}/ — initialise all fact category records. (3) Navigate to the fact sheet editor and begin filling in category data.

Sub-User Access

Accommodation accounts can create sub-user accounts for team members such as Revenue Managers, Front Office staff, and PR contacts. Sub-users share the manager's account data but are restricted by granular permission flags and optional property-level access grants.

Required Permission Flags

Each action category in the Accommodation module is gated by a separate flag on the UserPermission record. If a sub-user lacks the required flag, the relevant endpoints return 403 Not permitted.

Flag Grants Access To
properties Create, edit, and delete property records.
facts Read and write all fact sheet category data for permitted properties.
photos Upload, update metadata, delete photos, and set the feature image.
publishing_manager Submit fact sheets for publishing, download PDF fact sheets, email fact sheets and photos to mailing lists.
stop_sales View and edit the stop sale calendar. See the Stop Sale module for full details.

Property-Level Restriction

In addition to permission flags, sub-users can be restricted to a specific subset of properties via SubUserPropertyAccess records. Each record links a sub-user to a single property, effectively scoping all fact sheet, photo, and stop sale operations to that property only.

If a sub-user has no SubUserPropertyAccess rows, they fall back to seeing all properties belonging to their manager. This means property-level restriction is optional — an account manager can choose to grant a sub-user access to all properties by simply not creating any property access rows for that sub-user.

Sub-User Administration

Sub-user accounts and their permission flags are managed from the Settings > Team section of the accommodation dashboard. Property access grants are configured per sub-user from the Properties section. See Sub-Users for the full administration guide.