Cross-Origin Resource Sharing (CORS)

This guide covers how we support CORS on our domain and how you can avoid the browser making unnecessary ‘preflight’ requests.

You shouldn't need to make any configuration changes to allow browsers to utilize CORS, it's supported by default for all accounts and domains.

What is CORS? #

For security reasons, web browsers restrict cross-origin HTTP requests.
The XMLHttpRequest and Fetch APIs adhere to what’s called the “same-origin policy”, which means, by default, browsers won’t allow scripts on your domain to access resources from our domain.

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows our servers to indicate which other origins (ie. domains) can run scripts which access our domain directly from the browser.

How does it work? #

CORS is triggered when the browser sends any request which includes an Origin header. This is handled automatically by the browser.

Our servers will respond by adding Access-Control headers to the response:

curl -i -X GET \
  -H 'Origin: http://example.com' \
  'https://api.geocode.earth/v1/autocomplete'

Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: *

Simple Requests #

If the request you’re making meets all the conditions listed here it is considered a “Simple Request”.

We recommend using “Simple Requests” whenever possible, the browser will only send a single request, instead of two requests for preflighted requests.

In practice, the most important condition is that the request you’re sending doesn’t include any headers other than Accept, Accept-Language Content-Language or Content-Type.

Web frameworks often set the non-standard X-Requested-With header which is not allowed for Simple Requests.

Preflighted Requests #

If for any reason you’re not able to configure your client library to send Simple Requests you’ll see the browser making an OPTIONS request before the regular request is sent.

In the example below the browser has detected the X-FooBar request header does not adhere to the Simple Request conditions. It sends a preflight request first to ensure that the header is acceptable. This is handled automatically by the browser.

Our servers will respond by adding Access-Control headers to the response:

curl -i -X OPTIONS \
  -H 'Origin: http://example.com' \
  -H 'Access-Control-Request-Method: GET' \
  -H 'Access-Control-Request-Headers: X-FooBar' \
  'https://api.geocode.earth/v1/autocomplete'

Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type, Accept, X-FooBar
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 86400
OPTIONS requests are not billable and don't count towards your plan limits.

Content Security Policy #

In rare situations the server which renders your HTML could be configured to return a Content-Security-Policy header which disables CORS.

In this case you’ll see an error in the console with additional information, such as:

Refused to connect to 'https://api.geocode.earth/v1/autocomplete' because it violates
the following Content Security Policy directive: "connect-src 'self'"

This can be resolved by modifying the policy to allow access to our domain.