Download OpenAPI specification:
Solera is Data Mojito's travel data API. It returns flight and hotel pricing and availability — cash fares and loyalty award fares alike — extracted live from airline, hotel and meta-search providers.
Two ways to get the same data:
| Service | Use it when | |
|---|---|---|
| Realtime | TravelSearchService |
Someone is waiting. Results stream back per source as each one finishes. |
| Scheduled / batch | TravelJobService |
Nobody is waiting. Submit, poll, collect. |
Both cover flights and hotels, and both return the identical result payload — so you model the data once and choose the delivery mode per use case.
Every result, from every source, in both delivery modes, is shaped by one canonical model. A field means the same thing regardless of which provider produced it, so comparing two airlines is a matter of comparing two structs, not writing a mapping layer per provider.
Each source's payload is an envelope of three parts:
| Block | What it holds |
|---|---|
capture |
How the result was produced — collector, version, timestamp, device, point of sale |
resolved_query |
What was actually searched for, after any provider-side normalization |
offers |
What was found — the priced itineraries or rates |
capture and resolved_query are not decoration. The same route scanned
under a different point_of_sale or device is legitimately a different
price, and resolved_query records what the provider really searched for,
which is not always what you asked for. Reconcile against them before
comparing results across sources.
One thing to get right before you write a parser: Solera names fields in
snake_case, and the JSON on the wire uses camelCase.
Protobuf's canonical JSON mapping lower-camel-cases field names, so the
field display_price arrives as displayPrice, award_points as
awardPoints, and source_ids is sent as sourceIds. The schemas below
are labelled with both: the property name is the JSON name you will
actually see, and the title above it is the field's name in the model.
Requests accept either spelling; responses always use camelCase.
Cash and award pricing sit side by side on every flight and hotel result, rather than in separate response shapes:
price_mode — CASH, AWARD or MIXED. Read this first; it
determines which of the price fields is meaningful.display_price / currency — the cash price as displayed.award_points / loyalty_program — the award price. Points from
different programmes are not comparable, so never read award_points
without its programme.award_surcharge — cash still payable on an award booking (taxes,
surcharges, resort fees). Carries its own currency. An award fare is
rarely points-only, so ignoring this understates the real cost.Solera is a Connect RPC API. Every operation is
a POST to /{proto.package}.{Service}/{Method} — paths are never
parameterized, and there are no GET/PUT/DELETE variants. It is not
a REST API and does not pretend to be one.
The same endpoints speak three protocols, selected by Content-Type:
| Protocol | Content-Type | Notes |
|---|---|---|
| Connect, unary | application/json |
Plain JSON over HTTP/1.1 — usable straight from curl |
| Connect, streaming | application/connect+json |
JSON messages in Connect's length-prefixed envelope |
| gRPC / gRPC-Web | application/grpc* |
Binary protobuf; requires HTTP/2 |
The gRPC content types are listed on each operation for completeness, but
this document does not describe their binary framing — use the .proto,
or the server's gRPC reflection, for that.
SearchFlights and SearchHotels are server-streaming: one response
is emitted per requested source_id as that provider finishes, in
completion order rather than request order. The stream closes once every
requested source has produced a result.
OpenAPI has no vocabulary for this. The response schema shown below is the schema of a single message in the stream, not of the whole HTTP response body — the real body is a sequence of those messages inside Connect's envelope frames. Read the schema as "what each chunk looks like", and the operation description as the authority on how many chunks arrive.
If your infrastructure will not hold a connection open for the length of
a scan — seconds, not milliseconds — use TravelJobService instead.
Same data, no long-lived connection.
Two layers, and confusing them is the most common integration mistake.
RPC errors use the Connect error shape (code, message, details)
with an HTTP status derived from the code — see the connect.error
schema, present as the default response on every operation. These mean
the call itself failed.
Source-level failures are not RPC errors. A provider that times out,
is unreachable, or returns nothing still yields a normal 200 response
carrying that source's status and error. A multi-source search where
every source failed is still a successful call. The per-source status
field is the authoritative outcome — check it on every result before
reading data.
Note that NO_AVAILABILITY is a success: the search ran cleanly and
the route or property genuinely has nothing on sale. Do not retry it as
though it were a failure.
Request constraints are declared in the .proto with
protovalidate and enforced server-side
before any handler runs. The constraints rendered on each schema
(minItems, minimum, required, …) are generated from those same
declarations, so they are the rules the server actually applies — not
documentation-only hints. A violation returns invalid_argument naming
the field that failed.
Negative source_id values address the mock collector, which
synthesizes results deterministically without touching the live fleet:
0 is a generic mock, and -1 through -30 each mock the
correspondingly numbered real source. Use them to exercise every success
and failure path during integration — including the ones that are hard to
provoke on purpose, like SOURCE_BLOCKED and THROTTLER_TIMEOUT.
Asynchronous travel search: submit a job, poll for completion, fetch the results.
Same collectors, same payloads and same source semantics as
TravelSearchService — the only difference is delivery. Nothing is held
open: you submit, you get a job_id back immediately, and you come back
for the results whenever you like.
Use this for scheduled and batch work: overnight refreshes, rate monitoring across many routes, anything running where no user is waiting, and anything behind infrastructure that will not hold a streaming connection open for the length of a scan.
The lifecycle is:
SubmitSearch — enqueue the work, receive a job_id.GetSearchJob — poll until status is terminal. Honour
retry_after_ms; it reflects real queue depth.GetSearchResults — page through the completed sources' payloads. Results are retained for a limited window after completion (see
expires_at) and then deleted. Fetch what you need before then.
Cancels a job that has not yet reached a terminal state. Sources already completed keep their results and stay fetchable; sources not yet started are dropped.
| Connect-Protocol-Version required | number (Connect-Protocol-Version) Value: 1 Define the version of the Connect protocol Value: 1 |
| Connect-Timeout-Ms | number (Connect-Timeout-Ms) Define the timeout, in ms |
| jobId | string (job_id) non-empty |
{- "jobId": "string"
}{- "jobId": "string",
- "status": "UNSPECIFIED",
- "completedSources": 0
}Reports a job's progress. Poll this until status is terminal
(SUCCEEDED, PARTIAL, FAILED, EXPIRED or CANCELLED).
Respect retry_after_ms rather than polling on a fixed interval —
polling faster does not make a scan finish sooner and will be rate
limited.
| Connect-Protocol-Version required | number (Connect-Protocol-Version) Value: 1 Define the version of the Connect protocol Value: 1 |
| Connect-Timeout-Ms | number (Connect-Timeout-Ms) Define the timeout, in ms |
| jobId | string (job_id) non-empty |
{- "jobId": "string"
}{- "jobId": "string",
- "requestId": "string",
- "status": "UNSPECIFIED",
- "totalSources": 0,
- "completedSources": 0,
- "failedSources": 0,
- "retryAfterMs": 0,
- "error": {
- "code": "UNSPECIFIED",
- "message": "string",
- "remark": "string"
}, - "submittedAt": "2023-01-15T01:30:15.01Z",
- "completedAt": "2023-01-15T01:30:15.01Z",
- "expiresAt": "2023-01-15T01:30:15.01Z"
}Fetches a completed job's results, one page at a time.
Callable as soon as completed_sources is non-zero, so a long-running job
can be drained incrementally rather than only at the end — sources already
finished are returned even while others are still running.
| Connect-Protocol-Version required | number (Connect-Protocol-Version) Value: 1 Define the version of the Connect protocol Value: 1 |
| Connect-Timeout-Ms | number (Connect-Timeout-Ms) Define the timeout, in ms |
| jobId | string (job_id) non-empty |
| pageSize | integer or null <int32> (page_size) [ 1 .. 100 ] Maximum sources to return in this page. Defaults to 25 when omitted. |
| pageToken | string or null (page_token)
|
| sourceIds | Array of integers <int32> (source_ids) [ items <int32 > ] Return only these source IDs. Omit for all of them. Useful for draining a running job source by source as each one finishes. |
{- "jobId": "string",
- "pageSize": 1,
- "pageToken": "string",
- "sourceIds": [
- 0
]
}{- "jobId": "string",
- "status": "UNSPECIFIED",
- "flightResults": [
- {
- "sourceId": 0,
- "sourceName": "string",
- "status": "UNSPECIFIED",
- "error": {
- "code": "UNSPECIFIED",
- "message": "string",
- "remark": "string"
}, - "data": {
- "hasOffers": true,
- "offerCount": 0,
- "capture": {
- "collector": "string",
- "collectorVersion": "string",
- "timestamp": "2023-01-15T01:30:15.01Z",
- "device": "string",
- "pointOfSale": "string"
}, - "resolvedQuery": {
- "originIataCode": "string",
- "destinationIataCode": "string",
- "outboundDate": "string",
- "inboundDate": "string",
- "adults": 0,
- "youngAdults": 0,
- "children": 0,
- "infants": 0,
- "cabinClass": "string",
- "currency": "string",
- "pointOfSale": "string"
}, - "offers": [
- {
- "isAvailable": true,
- "outboundFlight": {
- "carrier": "string",
- "operatingCarrier": "string",
- "aircraftType": "string",
- "flightNumber": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "tripDurationMinutes": 0,
- "layoverMinutes": 0,
- "layoverSummary": "string",
- "layoverIatas": [
- "string"
], - "segments": [
- {
- "originIataCode": "string",
- "destinationIataCode": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "carrier": "string",
- "flightNumber": "string",
- "durationMinutes": 0,
- "operatingCarrier": "string",
- "cabinCode": "string"
}
], - "cabinClass": "string",
- "rateName": "string",
- "fareBasisCode": "string",
- "bookingClassCode": "string",
- "displayPrice": 0,
- "basePrice": 0,
- "currency": "string",
- "taxes": [
- {
- "code": "string",
- "name": "string",
- "amount": 0.1
}
], - "baggage": 0,
- "cabinBag": 0,
- "cancellationPolicy": "string",
- "brokerName": "string",
- "awardPoints": 0,
- "loyaltyProgram": "string",
- "awardSurcharge": {
- "amount": 0.1,
- "currency": "string"
}, - "priceMode": "UNSPECIFIED"
}, - "inboundFlight": {
- "carrier": "string",
- "operatingCarrier": "string",
- "aircraftType": "string",
- "flightNumber": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "tripDurationMinutes": 0,
- "layoverMinutes": 0,
- "layoverSummary": "string",
- "layoverIatas": [
- "string"
], - "segments": [
- {
- "originIataCode": "string",
- "destinationIataCode": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "carrier": "string",
- "flightNumber": "string",
- "durationMinutes": 0,
- "operatingCarrier": "string",
- "cabinCode": "string"
}
], - "cabinClass": "string",
- "rateName": "string",
- "fareBasisCode": "string",
- "bookingClassCode": "string",
- "displayPrice": 0,
- "basePrice": 0,
- "currency": "string",
- "taxes": [
- {
- "code": "string",
- "name": "string",
- "amount": 0.1
}
], - "baggage": 0,
- "cabinBag": 0,
- "cancellationPolicy": "string",
- "brokerName": "string",
- "awardPoints": 0,
- "loyaltyProgram": "string",
- "awardSurcharge": {
- "amount": 0.1,
- "currency": "string"
}, - "priceMode": "UNSPECIFIED"
}, - "url": "string",
- "evidenceUrls": [
- "string"
], - "rank": 0,
- "providerExtras": {
- "fields": {
- "property1": { },
- "property2": { }
}
}
}
]
}, - "metadata": {
- "executionId": "string",
- "scanStartTime": "2023-01-15T01:30:15.01Z",
- "scanEndTime": "2023-01-15T01:30:15.01Z",
- "executionDurationMs": 0,
- "deepLink": "string",
- "requestedCurrency": "string"
}
}
], - "hotelResults": [
- {
- "sourceId": 0,
- "sourceName": "string",
- "status": "UNSPECIFIED",
- "error": {
- "code": "UNSPECIFIED",
- "message": "string",
- "remark": "string"
}, - "data": {
- "hasOffers": true,
- "offerCount": 0,
- "capture": {
- "collector": "string",
- "collectorVersion": "string",
- "timestamp": "2023-01-15T01:30:15.01Z",
- "device": "string",
- "pointOfSale": "string"
}, - "resolvedQuery": {
- "destination": "string",
- "propertyCode": "string",
- "checkInDate": "string",
- "checkOutDate": "string",
- "nights": 0,
- "rooms": 0,
- "adults": 0,
- "children": 0,
- "childAges": [
- 0
], - "currency": "string",
- "pointOfSale": "string"
}, - "offers": [
- {
- "isAvailable": true,
- "property": {
- "propertyCode": "string",
- "propertyName": "string",
- "brand": "string",
- "starRating": 0,
- "reviewScore": 0,
- "reviewScoreScale": 0,
- "address": "string",
- "city": "string",
- "countryCode": "string",
- "latitude": 0,
- "longitude": 0
}, - "offer": {
- "roomType": "string",
- "rateCode": "string",
- "rateName": "string",
- "boardBasis": "string",
- "maxOccupancy": 0,
- "roomsLeft": 0,
- "displayPrice": 0,
- "basePrice": 0,
- "pricePerNight": 0,
- "currency": "string",
- "taxes": [
- {
- "code": "string",
- "name": "string",
- "amount": 0.1
}
], - "cancellationPolicy": "string",
- "isRefundable": true,
- "freeCancellationUntil": "string",
- "brokerName": "string",
- "awardPoints": 0,
- "loyaltyProgram": "string",
- "awardSurcharge": {
- "amount": 0.1,
- "currency": "string"
}, - "priceMode": "UNSPECIFIED"
}, - "url": "string",
- "evidenceUrls": [
- "string"
], - "rank": 0,
- "providerExtras": {
- "fields": {
- "property1": { },
- "property2": { }
}
}
}
]
}, - "metadata": {
- "executionId": "string",
- "scanStartTime": "2023-01-15T01:30:15.01Z",
- "scanEndTime": "2023-01-15T01:30:15.01Z",
- "executionDurationMs": 0,
- "deepLink": "string",
- "requestedCurrency": "string"
}
}
], - "nextPageToken": "string",
- "totalResults": 0
}Enqueues a search and returns immediately with a job identifier.
Submission does not validate provider availability — only the request itself. A job that was accepted here can still complete with every source failed.
| Connect-Protocol-Version required | number (Connect-Protocol-Version) Value: 1 Define the version of the Connect protocol Value: 1 |
| Connect-Timeout-Ms | number (Connect-Timeout-Ms) Define the timeout, in ms |
required | object (search.v1.FlightSearchRequest) What to search for, and where to search for it. | ||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||
| callbackUrl | string or null (callback_url) URL to POST a notification to when the job reaches a terminal state, so you can skip polling entirely. The callback carries the | ||||||||||||||||||||||||||||||||||
| resultTtlSeconds | integer or null <int32> (result_ttl_seconds) [ 60 .. 604800 ] How long to keep the results available for after completion. Clamped to your account's maximum retention; omit to use the account default. | ||||||||||||||||||||||||||||||||||
{- "callbackUrl": "string",
- "resultTtlSeconds": 60,
- "flightSearch": {
- "requestId": "string",
- "sourceIds": [
- -30
], - "parameters": {
- "currency": "string",
- "sourceIata": "string",
- "destinationIata": "string",
- "departureDate": "string",
- "returnDate": "string",
- "pointOfSale": "string",
- "adults": 1,
- "youngAdults": 0,
- "children": 0,
- "infants": 0,
- "maxStops": 0,
- "isRoundtrip": true,
- "cabinClass": "UNSPECIFIED"
}
}
}{- "jobId": "string",
- "requestId": "string",
- "status": "UNSPECIFIED",
- "totalSources": 0,
- "retryAfterMs": 0,
- "submittedAt": "2023-01-15T01:30:15.01Z"
}Realtime travel search.
Both RPCs are server-streaming: you send one request naming several sources, and results arrive one source at a time as each collector finishes. Use this when a caller is waiting on the answer and you want to show the first results without waiting for the slowest provider.
Sources are dispatched concurrently and are independent of one another. A
source that fails, times out or finds nothing still produces a response
carrying its status and error — it never fails the call or suppresses
the other sources. That means a stream can complete with every source having
failed, and the RPC will still report success; the per-source status is
the authoritative outcome, not the RPC's.
Responses arrive in completion order, not request order. Correlate on
source_id, and treat the stream as complete only when it closes — not when
a particular source arrives.
A scan takes seconds, and a stream is held open for its whole duration. If your caller cannot hold a connection that long — a batch job, a scheduled refresh, or anything behind a proxy with an aggressive idle timeout — use TravelJobService instead, which does the same work and lets you poll for the result.
Covers both cash and award pricing: each result's price_mode says which
applies, with display_price carrying cash and award_points carrying rewards.
| Connect-Protocol-Version required | number (Connect-Protocol-Version) Value: 1 Define the version of the Connect protocol Value: 1 |
| Connect-Timeout-Ms | number (Connect-Timeout-Ms) Define the timeout, in ms |
required | object (search.v1.FlightSearchParameters) The travel itinerary being priced. flight_search_parameters.roundtrip_return_date // return_date is required for roundtrip searches flight_search_parameters.route // source_iata and destination_iata must differ | ||||||||||||||||||||||||||
| |||||||||||||||||||||||||||
| requestId | string (request_id) Caller-supplied idempotency and correlation key. Echoed on every response and recorded in platform telemetry — send a unique value per logical search and quote it in support requests. | ||||||||||||||||||||||||||
| sourceIds | Array of integers <int32> (source_ids) non-empty [ items <int32 > >= -30 ] Sources to search, by ID (e.g. Each requested source is dispatched independently and concurrently, and produces exactly one response — a source that fails does not prevent the others from returning. Source IDs are issued per account; ask for the catalogue that applies to yours. Negative IDs address the mock source, which synthesizes results
deterministically without touching the live collector fleet, so you can
exercise every success and failure path during integration: | ||||||||||||||||||||||||||
{- "requestId": "string",
- "sourceIds": [
- -30
], - "parameters": {
- "currency": "string",
- "sourceIata": "string",
- "destinationIata": "string",
- "departureDate": "string",
- "returnDate": "string",
- "pointOfSale": "string",
- "adults": 1,
- "youngAdults": 0,
- "children": 0,
- "infants": 0,
- "maxStops": 0,
- "isRoundtrip": true,
- "cabinClass": "UNSPECIFIED"
}
}{- "sourceId": 0,
- "sourceName": "string",
- "status": "UNSPECIFIED",
- "error": {
- "code": "UNSPECIFIED",
- "message": "string",
- "remark": "string"
}, - "data": {
- "hasOffers": true,
- "offerCount": 0,
- "capture": {
- "collector": "string",
- "collectorVersion": "string",
- "timestamp": "2023-01-15T01:30:15.01Z",
- "device": "string",
- "pointOfSale": "string"
}, - "resolvedQuery": {
- "originIataCode": "string",
- "destinationIataCode": "string",
- "outboundDate": "string",
- "inboundDate": "string",
- "adults": 0,
- "youngAdults": 0,
- "children": 0,
- "infants": 0,
- "cabinClass": "string",
- "currency": "string",
- "pointOfSale": "string"
}, - "offers": [
- {
- "isAvailable": true,
- "outboundFlight": {
- "carrier": "string",
- "operatingCarrier": "string",
- "aircraftType": "string",
- "flightNumber": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "tripDurationMinutes": 0,
- "layoverMinutes": 0,
- "layoverSummary": "string",
- "layoverIatas": [
- "string"
], - "segments": [
- {
- "originIataCode": "string",
- "destinationIataCode": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "carrier": "string",
- "flightNumber": "string",
- "durationMinutes": 0,
- "operatingCarrier": "string",
- "cabinCode": "string"
}
], - "cabinClass": "string",
- "rateName": "string",
- "fareBasisCode": "string",
- "bookingClassCode": "string",
- "displayPrice": 0,
- "basePrice": 0,
- "currency": "string",
- "taxes": [
- {
- "code": "string",
- "name": "string",
- "amount": 0.1
}
], - "baggage": 0,
- "cabinBag": 0,
- "cancellationPolicy": "string",
- "brokerName": "string",
- "awardPoints": 0,
- "loyaltyProgram": "string",
- "awardSurcharge": {
- "amount": 0.1,
- "currency": "string"
}, - "priceMode": "UNSPECIFIED"
}, - "inboundFlight": {
- "carrier": "string",
- "operatingCarrier": "string",
- "aircraftType": "string",
- "flightNumber": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "tripDurationMinutes": 0,
- "layoverMinutes": 0,
- "layoverSummary": "string",
- "layoverIatas": [
- "string"
], - "segments": [
- {
- "originIataCode": "string",
- "destinationIataCode": "string",
- "departureTimestamp": "2023-01-15T01:30:15.01Z",
- "arrivalTimestamp": "2023-01-15T01:30:15.01Z",
- "carrier": "string",
- "flightNumber": "string",
- "durationMinutes": 0,
- "operatingCarrier": "string",
- "cabinCode": "string"
}
], - "cabinClass": "string",
- "rateName": "string",
- "fareBasisCode": "string",
- "bookingClassCode": "string",
- "displayPrice": 0,
- "basePrice": 0,
- "currency": "string",
- "taxes": [
- {
- "code": "string",
- "name": "string",
- "amount": 0.1
}
], - "baggage": 0,
- "cabinBag": 0,
- "cancellationPolicy": "string",
- "brokerName": "string",
- "awardPoints": 0,
- "loyaltyProgram": "string",
- "awardSurcharge": {
- "amount": 0.1,
- "currency": "string"
}, - "priceMode": "UNSPECIFIED"
}, - "url": "string",
- "evidenceUrls": [
- "string"
], - "rank": 0,
- "providerExtras": {
- "fields": {
- "property1": { },
- "property2": { }
}
}
}
]
}, - "metadata": {
- "executionId": "string",
- "scanStartTime": "2023-01-15T01:30:15.01Z",
- "scanEndTime": "2023-01-15T01:30:15.01Z",
- "executionDurationMs": 0,
- "deepLink": "string",
- "requestedCurrency": "string"
}
}Covers both cash and award pricing, on the same price_mode convention
as SearchFlights. Note that one property offering several rate plans
yields several results — group on property.property_code.
| Connect-Protocol-Version required | number (Connect-Protocol-Version) Value: 1 Define the version of the Connect protocol Value: 1 |
| Connect-Timeout-Ms | number (Connect-Timeout-Ms) Define the timeout, in ms |
required | object (search.v1.HotelSearchParameters) The stay being priced. hotel_search_parameters.destination // either destination or property_code must be set hotel_search_parameters.stay_dates // check_out_date must be later than check_in_date | ||||||||||||||||||||||
| |||||||||||||||||||||||
| requestId | string (request_id) Caller-supplied idempotency and correlation key. Echoed on every response and recorded in platform telemetry. | ||||||||||||||||||||||
| sourceIds | Array of integers <int32> (source_ids) non-empty [ items <int32 > >= -30 ] Sources to search, by ID. At least one is required. Dispatched independently and concurrently, one response per source. Negative IDs address the mock collector — see FlightSearchRequest.source_ids. | ||||||||||||||||||||||
{- "requestId": "string",
- "sourceIds": [
- -30
], - "parameters": {
- "currency": "string",
- "destination": "string",
- "propertyCode": "string",
- "checkInDate": "string",
- "checkOutDate": "string",
- "rooms": 1,
- "adults": 1,
- "children": 0,
- "childAges": [
- 0
], - "pointOfSale": "string",
- "minStarRating": 5
}
}{- "sourceId": 0,
- "sourceName": "string",
- "status": "UNSPECIFIED",
- "error": {
- "code": "UNSPECIFIED",
- "message": "string",
- "remark": "string"
}, - "data": {
- "hasOffers": true,
- "offerCount": 0,
- "capture": {
- "collector": "string",
- "collectorVersion": "string",
- "timestamp": "2023-01-15T01:30:15.01Z",
- "device": "string",
- "pointOfSale": "string"
}, - "resolvedQuery": {
- "destination": "string",
- "propertyCode": "string",
- "checkInDate": "string",
- "checkOutDate": "string",
- "nights": 0,
- "rooms": 0,
- "adults": 0,
- "children": 0,
- "childAges": [
- 0
], - "currency": "string",
- "pointOfSale": "string"
}, - "offers": [
- {
- "isAvailable": true,
- "property": {
- "propertyCode": "string",
- "propertyName": "string",
- "brand": "string",
- "starRating": 0,
- "reviewScore": 0,
- "reviewScoreScale": 0,
- "address": "string",
- "city": "string",
- "countryCode": "string",
- "latitude": 0,
- "longitude": 0
}, - "offer": {
- "roomType": "string",
- "rateCode": "string",
- "rateName": "string",
- "boardBasis": "string",
- "maxOccupancy": 0,
- "roomsLeft": 0,
- "displayPrice": 0,
- "basePrice": 0,
- "pricePerNight": 0,
- "currency": "string",
- "taxes": [
- {
- "code": "string",
- "name": "string",
- "amount": 0.1
}
], - "cancellationPolicy": "string",
- "isRefundable": true,
- "freeCancellationUntil": "string",
- "brokerName": "string",
- "awardPoints": 0,
- "loyaltyProgram": "string",
- "awardSurcharge": {
- "amount": 0.1,
- "currency": "string"
}, - "priceMode": "UNSPECIFIED"
}, - "url": "string",
- "evidenceUrls": [
- "string"
], - "rank": 0,
- "providerExtras": {
- "fields": {
- "property1": { },
- "property2": { }
}
}
}
]
}, - "metadata": {
- "executionId": "string",
- "scanStartTime": "2023-01-15T01:30:15.01Z",
- "scanEndTime": "2023-01-15T01:30:15.01Z",
- "executionDurationMs": 0,
- "deepLink": "string",
- "requestedCurrency": "string"
}
}