Tour Operators
How tour operators access partner hotel data, configure property mappings, and apply override facts for their own catalogue.
Overview
Tour operators (TOs) consume hotel data from their accommodation partners. The TO module provides:
- A view of all properties from connected partners
- Hotel and room mapping — mapping Ananas property and room names to the TO's internal codes
- Override facts — modifying specific fact fields for the TO's catalogue without changing the source data from the hotel
- API access for automated data consumption
Before any data is accessible, an accepted contract (
status=A
) must exist between the TO and the accommodation provider. See the
Partners & Contracts
module for contract setup.
Accessing Partner Data
TOs access partner data through two mechanisms:
| Method | How it works | Best for |
|---|---|---|
| Dashboard | Visual review of partner properties via the Ananas GDS web app | Manual review, one-off checks |
| API | Programmatic access via API tokens issued by the accommodation provider | Automated catalogue ingestion, integrations |
For API access, the accommodation provider issues an API token to the TO. The token is passed as a URL path segment — not as an Authorization header.
Token-based access
The token endpoints (
/api/v1/facts/{token}/
,
/api/v1/photos/{token}/
,
/api/v1/stop-sale/{token}/
) require no Authorization header. The token in the URL path identifies both the partner relationship and the scope of data returned.
Hotel Mapping (HotelMapping)
A
HotelMapping
record lets a TO assign their own internal codes to a partner hotel. This is essential for automated ingestion where the TO's back-office system uses its own identifiers.
HotelMapping
├── user → FK(User) — the TO user
├── hotel → FK(Property) — the partner's property
├── override_code → CharField(20) — TO's internal hotel code
├── local_id → CharField(50) — TO's local identifier
├── external_id → CharField(50) — external system ID (GDS, OTA, PMS)
├── supplying_name → CharField(50) — name used in the TO's system
├── event_free → CharField(20) — code for Free Sale events
├── event_open → CharField(20) — code for Open Sale events
├── event_stop → CharField(20) — code for Stop Sale events
├── event_request → CharField(20) — code for On Request events
└── event_block → CharField(20) — code for Blocked events
The
event_*
fields translate Ananas event codes (0–4) into the TO's own stop sale codes for their internal systems. For example, if the TO's PMS uses
CLS
to represent a closed room, set
event_stop = "CLS"
.
| Ananas Code | Ananas Name | HotelMapping field |
|---|---|---|
0 |
Free Sale | event_free |
1 |
Open Sale | event_open |
2 |
Stop Sale | event_stop |
3 |
On Request | event_request |
4 |
Blocked | event_block |
Room Mapping (RoomMapping)
Each room within a partner hotel can also carry a TO-specific mapping.
RoomMapping
extends
HotelMapping
with room-level overrides:
RoomMapping
├── room → FK(Room, nullable)
├── user → FK(User) — the TO user
├── hotel → FK(HotelMapping)
├── override_code → CharField(20) — TO's room code
├── name → CharField(500) — override display name
├── original_name → BooleanField — use the property's original room name?
├── event_free / event_open / event_stop / event_request / event_block
│ → CharField(20) — room-level event codes
├── linked → BooleanField — is this mapping active?
├── link_date → DateTimeField
└── unlink_date → DateTimeField
The
get_event_code(event_code)
instance method on
RoomMapping
translates an Ananas integer event code to the TO's own string code. If no room-level code is set, the method falls back to the parent
HotelMapping
value.
Linked vs. unlinked rooms
A
RoomMapping
with
linked=False
is inactive — it will not appear in API exports for that TO. Use
link_date
and
unlink_date
to audit when a room was connected or disconnected.
Override Facts (FactsOverride)
Tour operators can override specific fact fields for their own catalogue without modifying the source data from the hotel. Overrides are stored per TO user and property combination. When the TO fetches fact data via the API, override fields are merged on top of the hotel's base fact data.
FactsOverride
├── user → FK(User) — the TO
├── property → FK(Property) — the hotel
├── add_operator_logo → BooleanField — show TO logo on this property's facts?
├── enable_stopsale_api → BooleanField — expose stop sale via API?
├── set_stopsale_closed_request → BooleanField — treat stop sales as on-request?
├── location_environment → TextField — custom location description
├── around_hotel → TextField — custom "around the hotel" text
├── beach_characteristics → TextField
├── beach_information → TextField
├── distance_to_beach → DecimalField
├── distance_to_beach_unit → CharField
├── distance_to_airport → DecimalField
├── airport_distance_type → CharField
├── outdoor_characteristics → TextField
└── outdoor_equipment → TextField
Only fields explicitly set in a
FactsOverride
record replace the hotel's values. Fields left blank fall through to the source data. This means a hotel's fact sheet remains canonical — the TO overlay is applied at query time.
TO-Specific API Endpoints
TOs also use the standard partner contract endpoints documented in the Partners module. The following endpoints are additionally available:
Override facts management:
/api/partners/override-facts/
🔐 Auth required
List all override facts records for the authenticated TO.
/api/partners/override-facts/create/
🔐 Auth required
Create or update an override record for a property.
/api/partners/override-facts/get/{prop_id}/
🔐 Auth required
Get the override record for a specific property.
/api/partners/partners-properties/
🔐 Auth required
List all properties visible from the TO's partner connections.
/api/partners/check-facts/{prop_id}/
🔐 Auth required
Check fact access status for a given property under the current contract.
Data consumption (token-based, no auth header required):
/api/v1/facts/{token}/
Retrieve the full fact sheet for the property associated with this token. Override facts are merged into the response.
/api/v1/photos/{token}/
Retrieve the photo gallery for the property associated with this token.
/api/v1/stop-sale/{token}/
Retrieve the stop sale calendar for the property associated with this token. Room event codes are translated using
RoomMapping.get_event_code()
where a mapping exists.
TO Sub-User Access
TO sub-users use a different set of permission flags from accommodation sub-users. The flags relevant to TO operations are:
| Flag | Description |
|---|---|
edit_products |
Manage Partner Products & Content — unlocks editing across mapping, room mapping, on-request, fact overrides, and partner photos. Viewing partner fact sheets, rooms, and media is available without it; edit access is further scoped to the sub-user's assigned countries. |
accounting |
View invoices issued to this TO |
Different permission model
TO sub-users are governed by the same
UserPermission
model as accommodation sub-users, but the meaningful flags differ. Accommodation-side flags such as
stop_sales
,
facts
, and
photos
apply to the property manager's side;
edit_products
and
accounting
apply to the TO side.
Property Visibility
The properties a TO can see depend on their active contract connections. Only properties belonging to partners with
status=A
(Accepted) contracts are returned by any TO-facing endpoint.
For TO sub-users with
SubUserRegionAccess
records, visibility is further filtered by country or region. A sub-user without any
SubUserRegionAccess
records sees all properties from accepted partners; one with records sees only the intersection of their region grants and accepted-contract properties.