List Available Countries
const options = {
method: 'GET',
headers: {'x-api-key': '<x-api-key>', 'x-organization-id': '<x-organization-id>'}
};
fetch('https://api.dcycle.io/v1/hotel-stays/available-countries', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/v1/hotel-stays/available-countries"
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>"
}
response = requests.get(url, headers=headers)
print(response.text)curl --request GET \
--url https://api.dcycle.io/v1/hotel-stays/available-countries \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>'{
"array": {}
}List Available Countries
The ISO-2 country codes that have a hotel emission factor, so you only offer destinations that can be calculated
GET
/
v1
/
hotel-stays
/
available-countries
List Available Countries
const options = {
method: 'GET',
headers: {'x-api-key': '<x-api-key>', 'x-organization-id': '<x-organization-id>'}
};
fetch('https://api.dcycle.io/v1/hotel-stays/available-countries', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/v1/hotel-stays/available-countries"
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>"
}
response = requests.get(url, headers=headers)
print(response.text)curl --request GET \
--url https://api.dcycle.io/v1/hotel-stays/available-countries \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>'{
"array": {}
}← Hotel Stays API
List the countries that have a hotel emission factor behind them. A stay in a country outside this list has no factor to calculate against, so this is what you call to build a destination picker that cannot produce an uncalculable record.
The response is ISO-2 country codes in upper case, not country names. You get
["ES", "FR", "DE", "GB"], never ["Spain", "France", …]. Comparing a user-facing country name against this list matches nothing — map your names to ISO-2 codes first.Reference data, not your data. The list is the same for every organization and does not depend on where you have actually booked stays — fetch it once and cache it. It is drawn from the hotel factor tables as a whole, which today means DEFRA plus Greenview; a handful of countries are covered only by the latter, so do not assume every code has a DEFRA factor behind it.
Request
Headers
string
required
Your API key.
string
required
UUID of your organization.Format: UUID
The organization header is required even though the list is global. The response is not scoped to an organization, but the router’s authentication dependency resolves one from this header before the handler runs. Omitting it returns
422, not 401.Response
Returns a flat array of ISO-2 country codes, upper case, not an object wrapping one. There is noitems, no total_count, no pagination.
array[string]
Upper-case ISO-2 codes of the countries that have a hotel emission factor —
ES, FR, GB.Example
curl -X GET "https://api.dcycle.io/v1/hotel-stays/available-countries" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-organization-id: YOUR_ORGANIZATION_ID"
import requests
countries = requests.get(
"https://api.dcycle.io/v1/hotel-stays/available-countries",
headers={
"x-api-key": "YOUR_API_KEY",
"x-organization-id": "YOUR_ORGANIZATION_ID",
},
timeout=30,
).json()
# The response is the list itself — no unwrapping
print(len(countries), "countries with factors")
def can_calculate(iso2_code):
# Compare ISO-2 codes, not names: "Spain" is never in this list
return iso2_code.upper() in countries
const response = await fetch(
"https://api.dcycle.io/v1/hotel-stays/available-countries",
{
headers: {
"x-api-key": "YOUR_API_KEY",
"x-organization-id": "YOUR_ORGANIZATION_ID",
},
},
);
const countries = await response.json();
// Compare ISO-2 codes, not names
const canCalculate = (iso2Code) => countries.includes(iso2Code.toUpperCase());
Successful Response
Returns200 OK.
["AE", "AR", "AT", "AU", "BE", "BR", "CA", "CH", "CL", "DE", "ES", "FR", "GB"]
Common Errors
422 Unprocessable Entity
Cause:x-organization-id is missing. This fires before any credential check, so it is what a request with no headers at all returns.
{
"detail": [
{
"loc": ["header", "x-organization-id"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
401 Unauthorized
Cause: The organization header is present but the credentials are not.{
"code": "CREDENTIALS_REQUIRED",
"detail": "Credentials required (API key or JWT token)"
}
Use Cases
Offer only destinations that can be calculated
Build your country dropdown from this list instead of from a general country catalogue, keying the options by ISO-2 code. A stay recorded in a country with no factor still saves, but it will not produce emissions — and nothing in the record itself makes that obvious afterwards.Validate an import before you send it
When loading hotel stays in bulk, map each row’s country to its ISO-2 code and check it against this list first. Rejecting the row up front, with a message naming the country, is far easier to act on than discovering later that part of the batch has no emissions.Related Endpoints
Create Hotel Stay
Record a stay in one of these countries
Upload Hotel Stays CSV
Bulk load, where validating countries first pays off most
Impact Calculation
How a stay turns into emissions
Hotel Stays API
Everything the Hotel Stays API covers
Was this page helpful?