API v2 · Search
Agent brief

One endpoint, four prices.

Filters or free text in, ranked hotel cards out, with cached prices when you send dates.

Send a query, filters, or both. A query makes the call loose and we parse it; filters alone keep it structured. ranking decides between plain filter order and semantic ranking on each hotel's photos, reviews and description.

Where the query and the filters disagree, filters win, and resolved.overrides says so. When a search can't go on without an answer (two Cambridges), it returns needs_clarification, which costs nothing. Answer by sending the same request again with its search_id and answers (each a clarification_id and an option_id); there's no separate follow-up shape. A question's answer_type is single_choice, multi_choice or free_text.

A budget is always per room per night (basis: per_room_per_night) and needs a currency. near needs both lat and lng. A stay without rooms means one room for two adults.

Search

The four prices

The price follows the input and the ranking. Pages of the same search_id are free; results past 10 on a page add 5% of the base price each.

InputRankingSKUPrice
StructuredFilterssearch.structured.filters$0.003
LooseFilterssearch.loose.filters$0.005
StructuredSemanticsearch.structured.semantic$0.008
LooseSemanticsearch.loose.semantic$0.012
Search

Search hotels

POST/v2/search
Mode
Sync · 200
Price
$0.003–$0.012 / search
SKU
search.structured.filters, search.loose.filters, search.structured.semantic, search.loose.semantic, search.extra_results
Auth
Scope search

Synchronous; needs the search scope. Send a natural-language query, structured filters, or both; at least one of query, filters.location, filters.near or filters.hotel_ids is required. Billed per call: a query makes it loose (else structured) and ranking picks filters or semantic, giving search.structured.filters, search.loose.filters, search.structured.semantic or search.loose.semantic, plus search.extra_results for each result beyond 10. Further pages of the same search_id are free, and a needs_clarification response is free; answer it with {search_id, answers}.

Billing

query present → loose, else structured; ranking picks filters or semantic. Results beyond 10 add search.extra_results (5% of the base price each). Pages of the same search_id are free. A needs_clarification response is free; the answered follow-up is billed at the original price. An empty result with status: completed is billed; a 503 is not.

Request body

FieldTypeDescription
querystring | nullWhat the traveller asked for in their own words; dates, budget, place and amenities are read from it, and it makes the search bill as loose.
filtersobject | nullHard constraints, which win over anything read from query.
filters.locationobject | nullCity or place to search in.
filters.location.citystring | nullCity name, for example Rome; with no country an ambiguous city may come back as a clarification.
filters.location.countrystring | nullISO 3166-1 alpha-2 country code of the city, for example IT.
filters.location.place_idstring | nullA resolved.location.place_id from an earlier search, a slug of city and country such as rome-it.
filters.nearobject | nullPoint and radius to search around.
filters.near.lat
REQUIRED
numberLatitude of the centre in decimal degrees. -90–90.
filters.near.lng
REQUIRED
numberLongitude of the centre in decimal degrees. -180–180.
filters.near.radius_mintegerSearch radius in metres, 50 to 50,000; also the anchor for each card's distance_m. Default 2000.
filters.hotel_idsstring (uuid)[] | nullLimit the search to these hotels, up to 10,000 uuids, for example your own inventory; results never include other hotels.
filters.stayStay | nullDates and rooms of a stay, up to 30 nights and 9 rooms.
filters.budgetobject | nullPrice band per room per night.
filters.budget.minstring | nullLowest acceptable price per room per night, a decimal string in currency; values of zero or less are ignored.
filters.budget.maxstring | nullHighest acceptable price per room per night, a decimal string in currency; values of zero or less are ignored.
filters.budget.currency
REQUIRED
stringISO 4217 currency of min and max.
filters.budget.basisstringWhat the amounts cover; per_room_per_night is the only value. Always per_room_per_night.
filters.min_starsinteger | nullMinimum official star rating, 1 to 5.
filters.amenitiesstring[] | nullUppercase amenity codes from GET /v2/amenities, up to 30; a hotel must have all of them, and a group code matches any of its members.
filters.hotel_namestring | nullPart of the hotel's name to match.
preferencesobject | nullSoft signals for semantic ranking.
preferences.textstring | nullFree-text taste, for example romantic, great breakfast, added to the semantic query; ignored when ranking is filters.
preferences.tagsstring[]Short free-form tags such as ROMANTIC, up to 20, added to the semantic query and matched against review aspects.
rankingstring | nullsemantic ranks by fit to the query and preferences using reviews and images and fills why[]; filters ranks matches by review score. Defaults to semantic when query is set, else filters. One of filters, semantic.
limitintegerHotels per page, 1 to 50; each result beyond 10 bills search.extra_results, and at most 50 results can be paged in total. Default 10.
cursorstring | nullThe next_cursor of an earlier response, valid for 30 minutes; the page is served free from that search and other fields are ignored.
ratesstring | nullcached adds the latest stored rate to each card and needs filters.stay; none skips rates. Defaults to cached when a stay is set, else none. Search never fetches live prices. One of none, cached.
imagesintegerImages per card, 0 to 10; thumbnail is returned even at 0. Default 6.
currencystring | nullISO 4217 currency assumed for a budget written in query without one; card prices stay in the currency they were observed in.
localestring | nullLanguage tag of the caller; it does not change the search response and only selects the language of the hotel detail prepared for a follow-up GET /v2/hotels/{hotel_id}.
clarificationobject | nullWhat to do when the request is ambiguous; auto when omitted.
clarification.policystringauto returns needs_clarification with a question (free); never returns partial with no hotels and the ambiguous field in resolved.unresolved (also free). One of auto, never. Default auto.
search_idstring | nullWith answers: the search_id of a needs_clarification response being answered, within 30 minutes.
answersClarificationAnswer[] | nullWith search_id: the chosen option for the pending clarification; the original search then runs and is billed at its original price. At most 10.
answers[].clarification_id
REQUIRED
stringThe clarifications[].id being answered.
answers[].option_idstring | nullThe chosen clarifications[].options[].id, for a single_choice question.
answers[].valuestring | nullThe answer in the traveller's words, for a free_text question, for example Lisbon.

Example

Request
curl -X POST 'https://api.vistalink.com/v2/search' \
  -H "Authorization: Bearer $VISTALINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "quiet place near the Trevi Fountain with a rooftop, under 500 a night",
  "filters": {
    "location": {
      "city": "Rome",
      "country": "IT"
    },
    "stay": {
      "check_in": "2026-11-14",
      "check_out": "2026-11-16",
      "rooms": [
        {
          "adults": 2,
          "children_ages": []
        }
      ]
    },
    "budget": {
      "min": "100",
      "max": "500",
      "currency": "EUR",
      "basis": "per_room_per_night"
    },
    "min_stars": 4,
    "amenities": [
      "POOL",
      "SPA"
    ]
  },
  "preferences": {
    "text": "romantic, great breakfast",
    "tags": [
      "ROMANTIC"
    ]
  },
  "ranking": "semantic",
  "limit": 10,
  "rates": "cached",
  "images": 6,
  "currency": "EUR",
  "locale": "en",
  "clarification": {
    "policy": "auto"
  }
}'
Response
200
{
  "billing": {
    "amount": "0.012",
    "currency": "USD",
    "sku": "search.loose.semantic",
    "units": 1
  },
  "clarifications": [],
  "hotels": [
    {
      "amenities": [
        "POOL",
        "SPA"
      ],
      "hotel_id": "43d0be71-5f3c-4c8e-9a52-1d7e2b6f0a19",
      "hotel_type": "hotel",
      "images": [
        {
          "height": 427,
          "image_id": "b2e4d6f8-0a1c-4e3a-9d5b-7f9a1c3e5d2c",
          "label": "room",
          "url": "https://images.vistalink.com/h/43d0be71/room.jpg?w=640",
          "width": 640
        }
      ],
      "location": {
        "address": "Via dell'Umiltà 36",
        "city": "Rome",
        "country": "IT",
        "distance_m": 420,
        "lat": 41.9,
        "lng": 12.48
      },
      "name": "Umiltà 36",
      "rank": 1,
      "rate": {
        "currency": "EUR",
        "includes_taxes_and_fees": true,
        "nights": 2,
        "observed_at": "2026-10-07T09:30:00Z",
        "offer_id": "off_t3c8e1a9b4f2d7e6a5c0b",
        "source": "direct",
        "status": "observed",
        "total": "962.00"
      },
      "review_count": 2056,
      "review_score": 9.1,
      "star_rating": 5,
      "summary": "A quiet boutique hotel a few minutes from the Trevi Fountain.",
      "thumbnail": {
        "image_id": "a1f3c5e7-9b2d-4f6a-8c0e-2d4f6a8c0e1b",
        "label": "building",
        "url": "https://images.vistalink.com/h/43d0be71/ext.jpg?w=640"
      },
      "why": [
        {
          "assessment": "supported",
          "criterion": "quiet",
          "evidence": "review"
        }
      ]
    }
  ],
  "next_cursor": "c_eyJzIjoic3JjaF8zZjljMmE3ZTRiMWQ0YzhhOWU2ZjBiMmQ1YTdjMWU5MyIsIm8iOjEwfQ",
  "request_id": "req_8f2c1a9b3d4e5f60",
  "resolved": {
    "amenities": [
      {
        "code": "POOL",
        "origin": "filters"
      }
    ],
    "budget": {
      "basis": "per_room_per_night",
      "currency": "EUR",
      "max": "500",
      "origin": "query"
    },
    "location": {
      "label": "Rome, IT",
      "lat": 41.9,
      "lng": 12.5,
      "origin": "filters",
      "place_id": "rome-it"
    },
    "overrides": [],
    "stay": {
      "check_in": "2026-11-14",
      "check_out": "2026-11-16",
      "origin": "filters",
      "rooms": [
        {
          "adults": 2,
          "children_ages": []
        }
      ]
    },
    "unresolved": []
  },
  "search_id": "srch_3f9c2a7e4b1d4c8a9e6f0b2d5a7c1e93",
  "status": "completed",
  "total_estimate": 143,
  "versions": {
    "contract": "2.0",
    "ranking": "r2026.10"
  },
  "warnings": [
    {
      "code": "rates_unavailable",
      "message": "Some hotels have no observed rate for these dates."
    }
  ]
}

Response 200

Successful Response

FieldTypeDescription
request_id
REQUIRED
stringOpaque id of this request, also sent as the X-Request-Id header; quote it when contacting support.
billingBilling | nullWhat a billed call cost. Present on every billed response; billing is null on free ones.
search_id
REQUIRED
stringId of this search, srch_ plus 32 hex characters, valid for 30 minutes for paging, answering a clarification and GET /v2/hotels/{hotel_id}?search_id=.
status
REQUIRED
stringcompleted when the search ran (even with no hotels), needs_clarification when a question must be answered first (free), partial when policy never stopped an ambiguous search (free). One of completed, needs_clarification, partial.
resolvedobjectWhat the search understood and applied.
resolved.locationobject | nullThe place searched; null when the search had no location (for example hotel_ids only).
resolved.location.place_idstring | nullSlug of city and country, such as rome-it, reusable as filters.location.place_id; null for a near search.
resolved.location.labelstring | nullReadable name of the place, City, CC; null for a near search.
resolved.location.latnumber | nullLatitude of the city centre or the near point; null when only the city name is known.
resolved.location.lngnumber | nullLongitude of the city centre or the near point; null when only the city name is known.
resolved.location.originstring | nullquery when the place was read from the query text, filters when it came from filters. One of query, filters.
resolved.stayobject | nullThe stay used for rates; null when none was given or read.
resolved.stay.check_instring (date) | nullArrival date, YYYY-MM-DD.
resolved.stay.check_outstring (date) | nullDeparture date, YYYY-MM-DD.
resolved.stay.roomsOccupancy[]The party per room; a party read from the query is split evenly over its rooms and has no children.
resolved.stay.rooms[].adults
REQUIRED
integerAdults in the room.
resolved.stay.rooms[].children_agesinteger[]Age of each child in the room; empty for adults only.
resolved.stay.originstring | nullquery when the stay was read from the query text, filters when it came from filters.stay; null on hotel detail. One of query, filters.
resolved.budgetobject | nullThe price band applied; null when none.
resolved.budget.minstring | nullLowest price per room per night, a decimal string in currency.
resolved.budget.maxstring | nullHighest price per room per night, a decimal string in currency.
resolved.budget.currencystring | nullISO 4217 currency of the band; null when the query named an amount without a currency and none was sent.
resolved.budget.basisstring | nullWhat the amounts cover; always per_room_per_night. Always per_room_per_night.
resolved.budget.originstring | nullquery when the band was read from the query text, filters when it came from filters.budget. One of query, filters.
resolved.amenitiesResolvedAmenity[]Amenity requirements applied, all of which a hotel must have.
resolved.amenities[].code
REQUIRED
stringAmenity code, a group code such as POOL when the term named a group.
resolved.amenities[].originstring | nullquery when the amenity was read from the query text, filters when it came from filters.amenities. One of query, filters.
resolved.overridesOverride[]Conflicts between the query and filters, which the filters won.
resolved.overrides[].field
REQUIRED
stringThe criterion in conflict: location, stay, budget or hotel_name. One of location, stay, budget, hotel_name.
resolved.overrides[].query_saidstring | nullThe value read from the query, for example Paris or 2026-11-14/2026-11-16.
resolved.overrides[].filters_saidstring | nullThe value from filters, which was used.
resolved.overrides[].used
REQUIRED
stringWhich value the search used; always filters. One of query, filters.
resolved.unresolvedstring[]Criteria the search could not apply: location, stay (dates in the query could not be read), budget_currency (a budget without a currency), amenities (a term with no amenity code). One of location, stay, budget_currency, amenities.
clarificationsClarification[]The question to answer when status is needs_clarification; empty otherwise.
clarifications[].id
REQUIRED
stringClarification id to send back as answers[].clarification_id.
clarifications[].field
REQUIRED
stringThe criterion that is ambiguous or missing; location (a city or landmark with several matches, or no place at all) is the only one asked today.
clarifications[].question
REQUIRED
stringThe question to show the traveller, in English.
clarifications[].answer_typestringHow to answer: single_choice (send one of options as option_id) or free_text (no options; send the traveller's answer as value, for example a city when the search named no place). One of single_choice, multi_choice, free_text. Default single_choice.
clarifications[].optionsClarificationOption[]The possible answers: at least two for single_choice, none for free_text.
clarifications[].options[].id
REQUIRED
stringOption id to send back as answers[].option_id, for example opt_gb.
clarifications[].options[].label
REQUIRED
stringWhat to show the traveller, for example Cambridge, England.
hotelsSearchHotel[]This page of results, best first; empty unless status is completed.
total_estimateinteger | nullSize of the ranked candidate pool behind the results, not a catalogue-wide count; at most 50 can be paged. Null unless status is completed.
next_cursorstring | nullPass as cursor for the next page, free of charge; null on the last page.
warningsWarning_[]Things the search could not fully do.
versionsobjectContract and ranking versions.
versions.contractstringAPI contract version, 2.0. Default 2.0.
versions.rankingstring | nullVersion of the ranking model, for example r2026.10; results from the same version are comparable.

Errors

StatusCodeWhen
400bad_requestValidation errors carry details.fields[].
401unauthorizedNo key, or the key is unknown or revoked.
402insufficient_creditNot enough credit for the call. Checked before any work starts, so nothing was billed.
403forbiddenMissing scope.
429rate_limitedOver the per-minute limit for the tier. Wait Retry-After seconds.
503unavailableWe're temporarily unable to serve the call. Retry with backoff.
Chat

Conversational hotel search

POST/v2/chat
Mode
Sync · 200
Price
$0.03 / turn
SKU
chat.turn
Auth
Scope chat

Synchronous; needs the chat scope and bills chat.turn per turn, except turns that only ask a clarifying question, which are free. Same request as /v1/chat plus search_id; hotels[] use the search card shape, and the conversation is remembered per session_id.

Billing

Billed per turn. Clarification-only turns are free.

Request body

FieldTypeDescription
message
REQUIRED
stringWhat the traveller said, up to 4,000 characters.
session_idstring | nullConversation to continue, a uuid from an earlier response; omit to start a new conversation.
guest_idstring | nullYour id for the traveller, a uuid, recorded on a new conversation; ignored when session_id is set.
currencystring | nullISO 4217 currency the assistant should talk in; card prices stay in the currency they were observed in.
localestring | nullLanguage of the conversation as a language tag; en when omitted.
contextobject | nullStructured context passed to the assistant, for example a stay as check_in, check_out, rooms and adults; with a stay, hotel cards carry cached rates.
clarification_idstring | nullThe clarification_pending.clarification_id being answered.
clarification_option_idstring | nullThe chosen option of that clarification.
user_locationobject | nullThe traveller's current position, for questions like 'near me'.
user_location.lat
REQUIRED
numberLatitude in decimal degrees. -90–90.
user_location.lng
REQUIRED
numberLongitude in decimal degrees. -180–180.
user_location.accuracynumber | nullAccuracy radius of the position in metres.
search_idstring | nullAccepted for symmetry with search; not used as input.

Example

Request
curl -X POST 'https://api.vistalink.com/v2/chat' \
  -H "Authorization: Bearer $VISTALINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "message": "Somewhere quiet near the Pantheon for two nights in November",
  "currency": "EUR",
  "locale": "en"
}'
Response
200
{
  "billing": {
    "amount": "0.03",
    "currency": "USD",
    "sku": "chat.turn",
    "units": 1
  },
  "hotels": [],
  "message": "Here are three quiet options a short walk from the Pantheon.",
  "request_id": "req_8f2c1a9b3d4e5f60",
  "search_id": "srch_3f9c2a7e4b1d4c8a9e6f0b2d5a7c1e93",
  "session_id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f"
}

Response 200

Successful Response

FieldTypeDescription
request_id
REQUIRED
stringOpaque id of this request, also sent as the X-Request-Id header; quote it when contacting support.
billingBilling | nullWhat a billed call cost. Present on every billed response; billing is null on free ones.
session_id
REQUIRED
stringConversation id; send it back to continue the conversation.
message
REQUIRED
stringThe assistant's reply in plain text.
hotelsSearchHotel[]Hotels the reply refers to, up to 20, in the search card shape.
poisobject[]A place the turn located, as {name, lat, lng, ...}; at most one per turn.
routesobject[]Travel routes computed in the turn; always empty today.
referencesobject[]Web sources cited in the turn as {url, title, domain, index}; always empty today.
clarification_pendingobject | nullA question the assistant needs answered, with clarification_id, question and options[]; null otherwise. Answer it with clarification_id and clarification_option_id.
segmentsobject[]The reply split for rendering, each {type, id} plus content for text, hotel_id for hotel_ref or hotel_ids for trip_suggestion.
search_idstring | nullA search_id for the hotels in this turn, valid for 30 minutes with GET /v2/hotels/{hotel_id}?search_id=; null when the turn returned no hotels.
warningsWarning_[]Things the turn could not fully do, such as rates_unavailable or channel_unavailable.

Errors

StatusCodeWhen
400bad_requestValidation errors carry details.fields[].
401unauthorizedNo key, or the key is unknown or revoked.
402insufficient_creditNot enough credit for the call. Checked before any work starts, so nothing was billed.
403forbiddenMissing scope.
429rate_limitedOver the per-minute limit for the tier. Wait Retry-After seconds.
503unavailableWe're temporarily unable to serve the call. Retry with backoff.
Search

Chat turns

POST /v2/chat answers with the assistant's message, the hotels it talked about as the same cards search returns, and any pois, routes, references and segments the answer leans on. Send the session_id back on the next turn and the conversation carries on.

When the assistant needs an answer before it can search, clarification_pending holds the question; otherwise it's null. Reply with clarification_id and clarification_option_id, or in words. A turn that only asks a question is free.

A turn that searched returns a search_id, so hotel detail is warm for its cards. Put check_in and check_out in context to get cached prices on the cards, and send user_location (lat, lng, optional accuracy) for anything near the user.

Objects

Shared objects.

Objects that appear in more than one place. Billing is on the Billing page and ErrorBody under Errors & limits.

Stay

Dates and rooms of a stay, up to 30 nights and 9 rooms.

FieldTypeDescription
check_in
REQUIRED
string (date)Arrival date, YYYY-MM-DD.
check_out
REQUIRED
string (date)Departure date, YYYY-MM-DD, after check_in and at most 30 nights later.
roomsRoomOccupancy[]One entry per room, 1 to 9; defaults to one room for two adults. At most 9.
rooms[].adultsintegerAdults in this room, 1 to 16. Default 2.
rooms[].children_agesinteger[]Age of each child in this room, 0 to 17, one entry per child; empty for adults only. At most 8.

SearchHotel

One hotel in search or chat results.

FieldTypeDescription
hotel_id
REQUIRED
string (uuid)The hotel's id, for GET /v2/hotels/{hotel_id} and the other endpoints.
rank
REQUIRED
integerPosition in the full result list, starting at 1 and continuing across pages.
name
REQUIRED
stringHotel name.
hotel_typestring | nullKind of property as catalogued, free text such as hotel; null when unknown.
thumbnailImageRef | nullAn image on a search card, resized to 640 pixels wide.
imagesImageRef[]Up to images gallery images in gallery order, at 640 pixels wide.
star_ratingnumber | nullOfficial star rating, 1 to 5; null when unrated.
review_scorenumber | nullAverage guest review score on a 0 to 10 scale; null when there are no reviews.
review_countinteger | nullNumber of guest reviews behind review_score; null when none.
locationobject | nullWhere the hotel is.
location.latnumber | nullLatitude in decimal degrees.
location.lngnumber | nullLongitude in decimal degrees.
location.citystring | nullCity the hotel is in.
location.countrystring | nullISO 3166-1 alpha-2 country code, or the country name when no code is known.
location.addressstring | nullStreet address on one line, from street and number to country.
location.distance_mnumber | nullStraight-line distance in metres from filters.near or the landmark named in the query; null when the search had neither.
amenitiesstring[]Up to 20 uppercase amenity codes, group codes such as POOL first.
summarystring | nullThe start of the hotel's description, at most 400 characters, cut at a sentence or word boundary; null when there is no description.
rateobject | nullThe cheapest stored price for the stay; null when rates is none or no stay was given.
rate.status
REQUIRED
stringobserved when seen recently (within 4 hours for stays in the next 14 days, else 24 hours), stale when older but within 7 days, unknown when there is no usable price and the other fields are null. One of observed, stale, unknown.
rate.totalstring | nullPrice for the whole stay and all rooms, a decimal string in currency with taxes and fees included where known.
rate.currencystring | nullISO 4217 currency the price was observed in; never converted.
rate.nightsinteger | nullNumber of nights the total covers.
rate.includes_taxes_and_feesboolean | nullTrue when total includes taxes and fees, false when some are charged on top, null when unknown.
rate.sourcestring | nullWhere the price was observed: direct for the hotel's own booking engine, third_party for the Enterprise third-party channel. One of direct, third_party.
rate.observed_atstring (date-time) | nullWhen the price was observed, RFC 3339 UTC.
rate.offer_idstring | nullThe offer behind this price, bookable with POST /v2/bookings for 30 minutes.
whyWhyItem[]Evidence for the hotel on each criterion of the query, up to 6 items; empty unless ranking is semantic (chat fills it from its own reasoning).
why[].criterion
REQUIRED
stringThe traveller's own word or requirement being checked, for example quiet or pool.
why[].assessment
REQUIRED
stringsupported when the evidence backs the criterion, contradicted when it goes against it (reviews only), unknown when it is inconclusive. One of supported, contradicted, unknown.
why[].evidencestring | nullWhat was checked: review (guest review sentiment), image (photos), amenity (the amenity list) or description (chat only). One of review, image, amenity, description.

Warning

Something the response could not fully do, without failing it.

FieldTypeDescription
code
REQUIRED
stringStable warning code: rates_unavailable (some hotels have no stored rate), rates_need_stay (rates asked for without a stay), channel_unavailable (the third-party channel was left out), constraints_relaxed (no exact match, so some constraints were loosened), semantic_unavailable, unresolved (with clarification policy never), search_id_unavailable (the search cannot be paged or referenced), on chat price_redacted (a price in the reply that is not a direct rate was replaced with "a rate on request"), and on rates currency_unavailable.
messagestring | nullExplanation in English.
channelstring | nullThe channel left out, third_party; set only on channel_unavailable. Always third_party.

ImageRef

An image on a search card, resized to 640 pixels wide.

FieldTypeDescription
image_idstring (uuid) | nullImage id; the same image keeps the same id across responses.
url
REQUIRED
string (uri)CDN URL of the image at 640 pixels wide.
labelstring | nullWhat the image shows, for example building, room, bathroom or swimming pool outdoor; null when unlabelled.
widthinteger | nullWidth in pixels of the image at url; null on thumbnail and when unknown.
heightinteger | nullHeight in pixels of the image at url; null on thumbnail and when unknown.