# Welcome to Geoflow

Craft dynamic experiences for your Webflow website in a matter of minutes, delivering personalized content to your visitors with no-code and low-code.

### Overview

Geoflow is a no-code and low-code friendly personalization engine, designed to make creating unique experiences for your Webflow site seamless. Forget the static, stale content and serve a website based on over 30 different visitor data properties.

Take things further with a little JavaScript and the methods, callback functions and events; or stick with purely no-code by implementing valid HTML data attributes.

***

### How To Integrate Geoflow

Copy the following Geoflow \<script> and add it to the footer code section under the custom code tab in your site settings. Learn more about adding custom code at [Webflow University](https://university.webflow.com/lesson/custom-code-in-the-head-and-body-tags?topics=site-settings#custom-code-in-site-settings:~:text=Click%20Save%20changes-,Footer%20code,-Code%20entered%20in).

All Geoflow JavaScript files are served on the [global jsDelivr network](https://www.jsdelivr.com/network). This means no matter if your visitor is in North America, Australia or Africa, the files will load in a few milliseconds.

```html
<!-- [ Powered by Geoflow /// getgeoflow.com ] -->
<script src="https://cdn.jsdelivr.net/npm/@geoflow/geoflow@latest/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

## Get Started

{% embed url="<https://www.youtube.com/watch?v=VPV75ZdciW0>" %}

{% content-ref url="/pages/AfEiyCBPbGIx7OiLLCOj" %}
[Visitor Data Properties](/geoflow-docs/overview/visitor-data-properties)
{% endcontent-ref %}

## Advanced

The Geoflow script loads and constructs a client-side JavaScript object named ‘geoflow’ which exposes a series of properties (the visitor data), methods, callback functions, and events.

{% content-ref url="/pages/Bmjf3gbmirQJOkLdMDif" %}
[Methods](/geoflow-docs/advanced/methods)
{% endcontent-ref %}

{% content-ref url="/pages/7hHek7Nmuzl91hJc1gWK" %}
[Callbacks](/geoflow-docs/advanced/callbacks)
{% endcontent-ref %}

{% content-ref url="/pages/2yucAogWYtZtLf33fdVA" %}
[Events](/geoflow-docs/advanced/events)
{% endcontent-ref %}

### REST API

Geoflow offers a REST API that allows you to implement advanced functionality through your own backend or via Zapier, Make, Airtable, and more.

{% content-ref url="/pages/7jCROZBRdNQuxLumctNf" %}
[REST API](/geoflow-docs/advanced/api)
{% endcontent-ref %}


# Visitor Data Properties

Geoflow provides you with easy access to over 30 visitor data properties—from the country to the currency to the device type, and much more.

<table data-full-width="false"><thead><tr><th width="270">Property Name</th><th>Property Variable</th><th width="96">Type</th><th>Property Example</th></tr></thead><tbody><tr><td>Continent Name</td><td><mark style="color:yellow;"><code>continentName</code></mark></td><td>String</td><td>Oceania</td></tr><tr><td>Continent Code</td><td><mark style="color:yellow;"><code>continentCode</code></mark></td><td>String</td><td>OC</td></tr><tr><td>Country Name</td><td><mark style="color:yellow;"><code>countryName</code></mark></td><td>String</td><td>Australia</td></tr><tr><td>Country Code</td><td><mark style="color:yellow;"><code>countryCode</code></mark></td><td>String</td><td>AU</td></tr><tr><td>Region</td><td><mark style="color:yellow;"><code>region</code></mark></td><td>String</td><td>Oceania</td></tr><tr><td>National Capital</td><td><mark style="color:yellow;"><code>nationalCapital</code></mark></td><td>String</td><td>Canberra</td></tr><tr><td>City</td><td><mark style="color:yellow;"><code>city</code></mark></td><td>String</td><td>Melbourne</td></tr><tr><td>State Name</td><td><mark style="color:yellow;"><code>stateName</code></mark></td><td>String</td><td>Victoria</td></tr><tr><td>State Code</td><td><mark style="color:yellow;"><code>stateCode</code></mark></td><td>String</td><td>VIC</td></tr><tr><td>Postal/ZIP Code</td><td><mark style="color:yellow;"><code>postalCode</code></mark></td><td>String</td><td>3000</td></tr><tr><td>Is EU Visitor?</td><td><mark style="color:yellow;"><code>isEU</code></mark></td><td>Boolean</td><td>true</td></tr><tr><td>Time Zone</td><td><mark style="color:yellow;"><code>timezone</code></mark></td><td>String</td><td>Australia/Melbourne</td></tr><tr><td>Latitude</td><td><mark style="color:yellow;"><code>latitude</code></mark></td><td>String</td><td>-37.81590</td></tr><tr><td>Longitude</td><td><mark style="color:yellow;"><code>longitude</code></mark></td><td>String</td><td>144.96690</td></tr><tr><td>Airport Code</td><td><mark style="color:yellow;"><code>airportCode</code></mark></td><td>String</td><td>MEL</td></tr><tr><td>Currency Code</td><td><mark style="color:yellow;"><code>currencyCode</code></mark></td><td>String</td><td>AUD</td></tr><tr><td>Currency Symbol</td><td><mark style="color:yellow;"><code>currencySymbol</code></mark></td><td>String</td><td>$</td></tr><tr><td>Calling Code</td><td><mark style="color:yellow;"><code>callingCode</code></mark></td><td>Number</td><td>61</td></tr><tr><td>Language</td><td><mark style="color:yellow;"><code>language</code></mark></td><td>String</td><td>en-AU</td></tr><tr><td>Autonomous System Number</td><td><mark style="color:yellow;"><code>ASN</code></mark></td><td>Number</td><td>4804</td></tr><tr><td>Internet Service Provider</td><td><mark style="color:yellow;"><code>ISP</code></mark></td><td>String</td><td>Optus</td></tr><tr><td>Is Mobile Visitor?</td><td><mark style="color:yellow;"><code>isMobile</code></mark></td><td>Boolean</td><td>false</td></tr><tr><td>Device Type</td><td><mark style="color:yellow;"><code>deviceType</code></mark></td><td>String</td><td>Desktop</td></tr><tr><td>Mobile Data Saver</td><td><mark style="color:yellow;"><code>dataSaver</code></mark></td><td>Boolean</td><td>false</td></tr><tr><td>Reduced Motion</td><td><mark style="color:yellow;"><code>reducedMotion</code></mark></td><td>Boolean</td><td>false</td></tr><tr><td>Color Preference</td><td><mark style="color:yellow;"><code>colorPreference</code></mark></td><td>String</td><td>dark</td></tr><tr><td>Operating System</td><td><mark style="color:yellow;"><code>OS</code></mark></td><td>String</td><td>Windows</td></tr><tr><td>Current Page URL</td><td><mark style="color:yellow;"><code>currentPage</code></mark></td><td>String</td><td>getgeoflow.com</td></tr><tr><td>Page Referer</td><td><mark style="color:yellow;"><code>referer</code></mark></td><td>String</td><td>webflow.com</td></tr><tr><td>User Agent</td><td><mark style="color:yellow;"><code>userAgent</code></mark></td><td>String</td><td>Chrome/118.0.0.0</td></tr><tr><td>IP Address</td><td><mark style="color:yellow;"><code>IP</code></mark></td><td>String</td><td>192.168.1.1</td></tr></tbody></table>

{% hint style="info" %}
**Developer Tip**: Gain access to even more visitor data properties by enabling one or more of the optional script extensions offered. Visit this page [here](/geoflow-docs/feature/script-extensions) for more information.
{% endhint %}


# Geo Visibility

Set the visibility of any element on the current page, based on one or more conditions you have defined with the visitor data properties.

### How Does It Work?

Geoflow evaluates the conditions defined in the Geo Visibility data attribute against the visitor data properties. If the conditions match (returns true), the element will become visible. Otherwise, the hidden attribute will be applied to the element.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="266.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-visibility</td><td>conditionName:conditionValue</td><td>Any Element</td></tr></tbody></table>

The condition name is case-sensitive and must match the 'Property Variable' for that visitor data property in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties).

The case sensitivity and validity for the condition value depend on the data type. For example, when defining a condition based on a country code, the value must be an [ISO Alpha-2 Code](https://www.iso.org/obp/ui/#search/code/).

### Examples

<table data-card-size="large" data-view="cards"><thead><tr><th>Attribute Value</th><th>Description</th><th data-hidden>Attribute Name</th></tr></thead><tbody><tr><td><mark style="color:yellow;"><code>countryCode:AU</code></mark></td><td>The element is only visible to visitors currently in the country Australia (AU).</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>isMobile:true;countryCode:CA</code></mark></td><td>The element is visible to mobile visitors or anyone currently in Canada.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>language:fr</code></mark></td><td>The element is only visible if the primary browser language is set to French.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>deviceType:Desktop;isEU:true</code></mark></td><td>The element is only visible to visitors in the European Union or desktop computer users.</td><td></td></tr></tbody></table>

### Explore Further

{% content-ref url="/pages/IeYvEIDkuJWO3LPzhmk4" %}
[Define Multiple Conditions](/geoflow-docs/feature/visibility/define-multiple-conditions)
{% endcontent-ref %}

{% content-ref url="/pages/A4jokfuTJVgZDB6RLJ3x" %}
[Match All Conditions](/geoflow-docs/feature/visibility/match-all-conditions)
{% endcontent-ref %}

{% content-ref url="/pages/b8KR6d6BlQlwShVWYKXW" %}
[Partially Match Condition](/geoflow-docs/feature/visibility/partially-match-condition)
{% endcontent-ref %}

{% content-ref url="/pages/A0Tod12fCq0H54Ny4Hbj" %}
[Reverse Condition Value](/geoflow-docs/feature/visibility/reverse-condition-value)
{% endcontent-ref %}

{% content-ref url="/pages/RPqI82B6kStXnqVJczgo" %}
[Custom Classes](/geoflow-docs/feature/visibility/custom-classes)
{% endcontent-ref %}


# Define Multiple Conditions

Setting multiple conditions on your element is supported by appending a semicolon (;) to the value, serving as a separator between the conditions.

### How Does It Work?

Having multiple conditions for your element is supported by using the semicolon (;) as a separator between each condition that you have defined.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="268.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-visibility</td><td>conditionName:conditionValue;<br>conditionName:conditionValue</td><td>Any Element</td></tr></tbody></table>

The semicolon must be added after the value or any special characters.

### Examples

<table data-card-size="large" data-view="cards"><thead><tr><th>Attribute Value</th><th>Description</th><th data-hidden>Attribute Name</th></tr></thead><tbody><tr><td><mark style="color:yellow;"><code>countryCode:AU;countryCode:CA</code></mark></td><td>The element is only visibile to visitors in either Australia or Canada.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>isMobile:true;countryCode:CA</code></mark></td><td>The element is visible to mobile visitors or anyone currently in Canada.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>city:Sydney;city:Melbourne</code></mark></td><td>The element is visibile to anyone that is currently in the cities Sydney or Melbourne.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>deviceType:Desktop;isEU:true</code></mark></td><td>The element is only visible to visitors in the European Union or desktop computer users.</td><td></td></tr></tbody></table>


# Match All Conditions

Instruct Geoflow to only display an element if all of the conditions you have defined match the visitor data properties.

### How Does It Work?

By default, Geoflow will display an element if any conditions you have defined match (return true). This means if you have added three conditions and one of them is true, then the element is visible.

You can override this default behaviour by applying the attribute name and value noted below.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="268.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-match</td><td>all</td><td>Any element with the <strong>Geo Visibility</strong> data attribute.</td></tr></tbody></table>

Any value other than 'all' added to this data attribute will have no effect.

### Examples

<table data-card-size="large" data-view="cards"><thead><tr><th>Attribute Value</th><th>Description</th><th data-hidden>Attribute Name</th></tr></thead><tbody><tr><td><mark style="color:yellow;"><code>countryCode:!AU</code></mark></td><td>The element is visibile to everyone around the globe, except for those in Australia.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>isMobile:true;countryCode:!CA</code></mark></td><td>The element is only visible to mobile visitors  not currently in Canada.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>language:!fr</code></mark></td><td>The element is visibile to anyone whose primary browser language is not currently set as French.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>deviceType:!Desktop;isEU:true</code></mark></td><td>The element is only visible to visitors in the European Union who are not on a desktop computer (e.g. Tablet and Mobile visitors).</td><td></td></tr></tbody></table>


# Partially Match Condition

Partially match a condition you have defined by appending a caret (^) or dollar sign ($) to the value (e.g. postalCode:^30).

### How Does It Work?

Partially matching the condition(s) that you define allows you to take the visibility feature further.

Append Caret (^): Your condition will be matched (return true) if the visitor data property begins with the value you have specified.

Append Dollar Sign ($): Your condition will be matched (return true) if the visitor data property ends with the value you have specified.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="273.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-visibility</td><td>conditionName:conditionValue^</td><td>Any Element</td></tr><tr><td>data-geo-visibility</td><td>conditionName:conditionValue$</td><td>Any Element</td></tr></tbody></table>

The character must be added after the value and only one can be present at a time. If a caret and dollar sign are added, the first one will be treated as part of the value and break your condition. If you are setting multiple conditions, then the semicolon goes after the caret or dollar sign.

### Examples

<table data-card-size="large" data-view="cards"><thead><tr><th>Attribute Value</th><th>Description</th><th data-hidden>Attribute Name</th></tr></thead><tbody><tr><td><mark style="color:yellow;"><code>postalCode:30^</code></mark></td><td>The element is visibile to everyone whose postal/ZIP code begins with "30".</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>postalCode:50$</code></mark></td><td>The element is visibile to everyone whose postal/ZIP code ends with "50".</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>language:en^</code></mark></td><td>The element is displayed to visitors whose primary browser language begins with "en".</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>referer:ca$</code></mark></td><td>The element is displayed to visitors that came from a website that ends with "ca".</td><td></td></tr></tbody></table>


# Reverse Condition Value

Reverse the result of an evaluated condition you have defined by prepending an exclamation mark (!) to the value (e.g. countryCode:!AU).

### How Does It Work?

In JavaScript, the exclamation mark is frequently used to negate a boolean expression.

When appended to a value, Geoflow will reverse the outcome of the evaluated condition. This means that if the original result is true, it will be negated to return false, and vice versa.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="268.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-visibility</td><td>conditionName:!conditionValue</td><td>Any Element</td></tr></tbody></table>

The exclamation mark (!) must be placed after the semicolon and before the condition value.

### Examples

<table data-card-size="large" data-view="cards"><thead><tr><th>Attribute Value</th><th>Description</th><th data-hidden>Attribute Name</th></tr></thead><tbody><tr><td><mark style="color:yellow;"><code>countryCode:!AU</code></mark></td><td>The element is visibile to everyone around the globe, except for those in Australia.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>isMobile:true;countryCode:!CA</code></mark></td><td>The element is only visible to mobile visitors or anyone not in Canada.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>language:!fr</code></mark></td><td>The element is visibile to anyone whose primary browser language is not currently set as French.</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>deviceType:!Desktop;isEU:true</code></mark></td><td>The element is only visible to visitors in the European Union or anyone not on a desktop computer (e.g. Tablet and Mobile visitors).</td><td></td></tr></tbody></table>


# Custom Classes

Apply a custom class, overriding the default, to any element that is displayed or hidden by Geoflow according to the condition(s) defined.

### How Does It Work?

By default, Geoflow will apply one of two classes to an element based on its visibility status.

**Shown Elements**: gv-shown\
**Hidden Elements**: gv-hidden

You can override this default behaviour and set your own custom classes by applying one or both of the data attributes noted below in the table.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="268.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-gv-class:show</td><td>your-custom-class</td><td>Any element with the <strong>Geo Visibility</strong> data attribute.</td></tr><tr><td>data-gv-class:hidden</td><td>your-custom-class</td><td>Any element with the <strong>Geo Visibility</strong> data attribute.</td></tr></tbody></table>

Any valid string of text, number(s) or special character(s) will be accepted as the value.


# Geo Form

Enhance the forms on your Webflow website by autofilling fields or appending visitor data properties to gain more insights into submissions.

### How Does It Work?

Apply the Geo Form data attribute to your *Form* element (not the *Form Block*).

An input field (set to hidden) will be generated for each available visitor data property. When the form is submitted, the data will be accessible alongside anything else included in the submission. For privacy reasons, the visitor's IP address is not automatically included.

To include or exclude specific properties, add the respective attribute noted in the table below, along with a comma-separated list of property names as the value. The property name is case-sensitive and must match the 'Property Variable' noted in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties).

In order to improve page performance, Geoflow will wait until the visitor has interacted with the page (any element is clicked), before adding the hidden field(s) to the form(s).

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="266.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-form<mark style="color:red;">*</mark></td><td>N/A</td><td>&#x3C;form></td></tr><tr><td>data-gf-include</td><td>propertyName, propertyName</td><td>Any element with the <strong>Geo Form</strong> data attribute.</td></tr><tr><td>data-gf-exclude</td><td>propertyName, propertyName</td><td>Any element with the <strong>Geo Form</strong> data attribute.</td></tr></tbody></table>

No value is needed for the Geo Form data attribute; any value added will have no effect.

<mark style="color:red;">\*</mark>‎‏‏‎ ‎Attribute names with a red asterisk are required; all others listed in the table are optional.

### Explore Further

{% content-ref url="/pages/icWxAmTabxKqPOQVQixb" %}
[Autofill Form Fields](/geoflow-docs/feature/form/autofill-form-field)
{% endcontent-ref %}

{% content-ref url="/pages/p4HysLREiIYEMMRcKIOK" %}
[Auto-Populate Select Fields](/geoflow-docs/feature/form/auto-populate-select-fields)
{% endcontent-ref %}


# Autofill Form Fields

Autofilling a field in your form can save visitors time and improve the completion rate, conversions, and user experience.

### How Does It Work?

Apply the Geo Input data attribute to a \<input> or \<textarea> element, using a value corresponding to a visitor data property to autofill that field.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="268.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-input</td><td>propertyName</td><td>&#x3C;input> or &#x3C;textarea></td></tr></tbody></table>

Only one property name is supported in the value. The property name is case-sensitive and must match the 'Property Variable' noted in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties).

If the \<input> field is a checkbox or radio and if the visitor data property returns a boolean (true or false), then the \<input> field will be checked/unchecked accordingly.

The Geo Form data attribute does not need to be added to the \<form> element for the Geo Input data attribute to function.

### Examples

```html
<!-- This Text Field Will Be Prefilled with the Visitor's Country Name-->
<input type="text" data-geo-input="countryName">

<!-- This Checkbox Will Be Checked If the Visitor Is From the EU -->
<input type="checkbox" data-geo-input="isEU">

<!-- This URL Field Will Be Prefilled with the Visitor's Referer -->
<input type="url" data-geo-input="referer">
```


# Auto-Populate Select Fields

Auto-populate the options in your \<select> field based on a category you specify in the data attribute and add an optional custom placeholder.

### How Does It Work?

Apply the Geo Select data attribute to a \<select> element, using a value corresponding to the variable name for one of the available categories in the table at the bottom.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="268.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-select<mark style="color:red;">*</mark></td><td>category-name</td><td>&#x3C;select></td></tr><tr><td>data-gs-placeholder</td><td>Your Custom Placeholder</td><td>Any element with the <strong>Geo Select</strong> data attribute.</td></tr></tbody></table>

The category name is case-sensitive and must match the respective 'Category Variable'.

The default placeholder option for the \<select> element will be 'Choose an Option'. You can override this by setting the placeholder data attribute noted above.

The Geo Form data attribute does not need to be added to the \<form> element for the Geo Select data attribute to function.

<mark style="color:red;">\*</mark>‎‏‏‎ ‎Attribute names with a red asterisk are required; all others listed in the table are optional.

{% hint style="info" %}
**Developer Tip**: With a little JavaScript, you can dynamically update the options in one \<select> based on what was chosen in another. For example, if someone chooses 'Canada', add Canadian provinces and territories. [View the code snippet](/geoflow-docs/advanced/code-snippets#populate-list-of-provinces-states-based-on-chosen-country).
{% endhint %}

### Available Categories

| Category Name                      | Category Variable            |
| ---------------------------------- | ---------------------------- |
| African Countries                  | af-countries                 |
| All Countries                      | all-countries                |
| Antarctican Countries              | an-countries                 |
| Asian Countries                    | as-countries                 |
| Australian States and Territories  | au-states-and-territories    |
| Canadian Provinces and Territories | ca-provinces-and-territories |
| European Countries                 | eu-countries                 |
| North American Countries           | na-countries                 |
| Oceania Countries                  | oc-countries                 |
| South American Countries           | sa-countries                 |
| United Kingdom Countries           | uk-countries                 |
| American States                    | us-states                    |

### Examples

```html
<!-- This <select> Will Be Populated with North American Countries -->
<select data-geo-select="na-countries" data-gs-placeholder="Choose a Country">
</select>

<!-- This <select> Will Be Populated with American States -->
<select data-geo-select="us-states" data-gs-placeholder="Choose a State">
</select>

<!-- This <select> Will Be Populated with Australian States and Territories -->
<select data-geo-select="au-states-and-territories" data-gs-placeholder="Choose a State or Territory">
</select>
```


# Geo Text

Replace the text content for any element based on a visitor data property. For example, the visitor's country name or currency symbol.

### How Does It Work?

Apply the Geo Text data attribute to an element, using a value corresponding to a visitor data property, to dynamically update its text content. Ensure the element has appropriate default text in the event an error occurs or the property is not available.

To prevent potential content flashing, you can apply the Geo Opacity data attribute. When the element's text content changes, its opacity will be set to 1. Take things further by adding custom CSS to your page that targets elements with this data attribute so you can integrate a transition.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="266.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>data-geo-text<mark style="color:red;">*</mark></td><td>propertyName</td><td>Any Element (See Below)</td></tr><tr><td>data-geo-opacity</td><td>N/A</td><td>Any element with the <strong>Geo Text</strong> data attribute.</td></tr></tbody></table>

The property name is case-sensitive and must match the 'Property Variable' for that visitor data property in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties).

While the Geo Text data attribute can technically be added to virtually any HTML element, you may experience an unintended or adverse result with certain elements.

No value is needed for the Geo Opacity data attribute; any value added will have no effect.

<mark style="color:red;">\*</mark>‎‏‏‎ ‎Attribute names with a red asterisk are required; all others listed in the table are optional.

### Examples

<table data-card-size="large" data-view="cards"><thead><tr><th>Attribute Value</th><th>Description</th><th data-hidden>Attribute Name</th></tr></thead><tbody><tr><td><mark style="color:yellow;"><code>countryName</code></mark></td><td>The element's text content will be changed to the visitor's country name (e.g. Canada).</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>city</code></mark></td><td>The element's text content will be changed to the visitor's city (e.g. Melbourne).</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>deviceType</code></mark></td><td>The element's text content will be changed to the visitor's device type (e.g. Mobile).</td><td>data-geo-visibility</td></tr><tr><td><mark style="color:yellow;"><code>OS</code></mark></td><td>The element's text content will be changed to the visitor's OS (e.g. Windows).</td><td></td></tr></tbody></table>


# Geo Style

Conditionally apply internal or external styles, based on one or more conditions you have defined with the visitor data properties.

### How Does It Work?

Geoflow evaluates the conditions defined in the Geo Style data attribute against the visitor data properties. If the conditions match (returns true), the internal or external styles will be applied. Otherwise, they will be left as-is and not applied.

By default, Geoflow will apply the styles if any conditions you have defined match (return true). You can override this default behaviour by applying the Geo Match data attribute.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="266.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>type<mark style="color:red;">*</mark></td><td>text/geoflow</td><td>&#x3C;style> or &#x3C;link></td></tr><tr><td>data-geo-style<mark style="color:red;">*</mark></td><td>conditionName:conditionValue</td><td>&#x3C;style> or &#x3C;link></td></tr><tr><td>data-geo-match</td><td>all</td><td>Any element with the <strong>Geo Style</strong> data attribute.</td></tr></tbody></table>

The type attribute is required to prevent the browser from automatically running the CSS.

The condition name is case-sensitive and must match the 'Property Variable' for that visitor data property in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties).

The case sensitivity and validity for the condition value depend on the data type. For example, when defining a condition based on a country code, the value must be an [ISO Alpha-2 Code](https://www.iso.org/obp/ui/#search/code/).

Any value other than 'all' added for the Geo Match data attribute will have no effect.

<mark style="color:red;">\*</mark>‎‏‏‎ ‎Attribute names with a red asterisk are required; all others listed in the table are optional.

### Example

```html
<!--
If the Visitor IS In Australia, Every Element's Font Color Will Change to Red
-->
<style type="text/geoflow" data-geo-style="countryCode:AU">

        * { color: red; }
        
</style>
```


# Geo Script

Conditionally run internal or external JavaScript code, based on one or more conditions you have defined with the visitor data properties.

### How Does It Work?

Geoflow evaluates the conditions defined in the Geo Script data attribute against the visitor data properties. If the conditions match (returns true), the internal or external JavaScript code will run. Otherwise, it will be left as-is and the code won't run.

By default, Geoflow will run the code if any conditions you have defined match (return true). You can override this default behaviour by applying the Geo Match data attribute.

### How To Implement

<table><thead><tr><th>Attribute Name</th><th width="266.3333333333333">Attribute Value</th><th>Which Page Element?</th></tr></thead><tbody><tr><td>type<mark style="color:red;">*</mark></td><td>text/geoflow</td><td>&#x3C;script></td></tr><tr><td>data-geo-script<mark style="color:red;">*</mark></td><td>conditionName:conditionValue</td><td>&#x3C;script></td></tr><tr><td>data-geo-match</td><td>all</td><td>Any element with the <strong>Geo Script</strong> data attribute.</td></tr></tbody></table>

The type attribute is required to prevent the browser from automatically running the JS.

The condition name is case-sensitive and must match the 'Property Variable' for that visitor data property in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties).

The case sensitivity and validity for the condition value depend on the data type. For example, when defining a condition based on a country code, the value must be an [ISO Alpha-2 Code](https://www.iso.org/obp/ui/#search/code/).

Any value other than 'all' added for the Geo Match data attribute will have no effect.

<mark style="color:red;">\*</mark>‎‏‏‎ ‎Attribute names with a red asterisk are required; all others listed in the table are optional.

### Example

```html
<!--
If the Visitor Is NOT In the EU, The Cookie Banner Will Be Removed
-->
<script type="text/geoflow" data-geo-script="isEU:false">

    document.getElementById('cookie-banner')?.remove();

</script>
```


# Script Extensions

Script extensions allow you to extend the functionality offered by the default Geoflow script, without writing a single line of code.

### How Does It Work?

Optional script extensions were created so you can extend Geoflow's initial functionality. The default script is kept lightweight by offering additional features through these extensions.

{% hint style="info" %}
**Developer Tip**: Send all the visitor data to an external source by adding the endpoint data attribute to the Geoflow \<script> tag; visit this page [here](/geoflow-docs/feature/optional-settings/script-tag-data-attributes) for more information.
{% endhint %}

### How To Implement

| Attribute Name  | Attribute Value      | Which Page Element?       |
| --------------- | -------------------- | ------------------------- |
| data-extensions | See Extensions Table | \<script> Tag for Geoflow |

### Extensions

<table><thead><tr><th width="215">Extension Name</th><th width="183">Extension Variable</th><th>Extension Description</th></tr></thead><tbody><tr><td>Performance</td><td>performance</td><td>Analyze how your website performs for visitors around the globe by collecting Real User Monitoring (RUM) data.</td></tr><tr><td>Marketing Parameters</td><td>marketing-params</td><td>Automatically capture and log every URL parameter related to marketing within each form on your page.</td></tr></tbody></table>

You can enable more than one script extension by including a comma-separated list in the extensions data attribute on the Geoflow \<script> tag.

### Example

```html
<script data-extensions="performance" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

### Browse The Extensions

{% content-ref url="/pages/2qfoJcmlye9ITgRqWqla" %}
[Performance](/geoflow-docs/feature/script-extensions/performance)
{% endcontent-ref %}

{% content-ref url="/pages/hsB8PLTZ40JM94uYJ5Za" %}
[Marketing Parameters](/geoflow-docs/feature/script-extensions/marketing-parameters)
{% endcontent-ref %}


# Performance

Analyze how your website performs for visitors around the globe by collecting Real User Monitoring (RUM) data.

### How Does It Work?

This script extension helps you view your Webflow website's performance from the user's perspective by collecting Real User Monitoring (RUM) data.

The metrics noted in the table below, measured in milliseconds, are collected and made accessible through the 'geoflow' object—alongside the other visitor data properties.

<table data-full-width="false"><thead><tr><th width="255">Property Name</th><th width="388">Property Variable</th><th>Type</th></tr></thead><tbody><tr><td>First Paint</td><td><mark style="color:yellow;"><code>Performance_FP</code></mark></td><td>Number</td></tr><tr><td>First Contentful Paint</td><td><mark style="color:yellow;"><code>Performance_FCP</code></mark></td><td>Number</td></tr><tr><td>Largest Contentful Paint</td><td><mark style="color:yellow;"><code>Performance_LCP</code></mark></td><td>Number</td></tr><tr><td>Total Blocking Time</td><td><mark style="color:yellow;"><code>Performance_TBT</code></mark></td><td>Number</td></tr><tr><td>Cumulative Layout Shift</td><td><mark style="color:yellow;"><code>Performance_CLS</code></mark></td><td>Number</td></tr><tr><td>First Input Delay</td><td><mark style="color:yellow;"><code>Performance_FID</code></mark></td><td>Number</td></tr><tr><td>Time to First Byte</td><td><mark style="color:yellow;"><code>Performance_TTFB</code></mark></td><td>Number</td></tr><tr><td>DOM Interactive</td><td><mark style="color:yellow;"><code>Performance_DOM</code></mark></td><td>Number</td></tr><tr><td>Total Load Time</td><td><mark style="color:yellow;"><code>Performance_TLT</code></mark></td><td>Number</td></tr></tbody></table>

### How To Implement

| Attribute Name  | Attribute Value | Which Page Element?       |
| --------------- | --------------- | ------------------------- |
| data-extensions | performance     | \<script> Tag for Geoflow |

### Example

```html
<script data-extensions="performance" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```


# Marketing Parameters

Automatically capture and log every URL parameter related to marketing within each form on your page.

### How Does It Work?

This script extension will check the current URL for any marketing-related parameter and if one is found, an input field (set to hidden) will be generated with the parameter's name and value; the field will be added to every form on the page. When the form is submitted, the value(s) for the parameter(s) will be accessible alongside anything else included in the submission.&#x20;

The URL parameters noted in the table below are the ones that will be recorded if found. The names and values will not be accessible through the 'geoflow' object.

<table data-full-width="false"><thead><tr><th width="255">URL Parameter Name</th><th width="220">URL Parameter Variable</th></tr></thead><tbody><tr><td>Ref</td><td><mark style="color:yellow;"><code>ref</code></mark></td></tr><tr><td>Referrer</td><td><mark style="color:yellow;"><code>referrer</code></mark></td></tr><tr><td>Source</td><td><mark style="color:yellow;"><code>source</code></mark></td></tr><tr><td>UTM_Source</td><td><mark style="color:yellow;"><code>utm_source</code></mark></td></tr><tr><td>UTM_Medium</td><td><mark style="color:yellow;"><code>utm_medium</code></mark></td></tr><tr><td>UTM_Campaign</td><td><mark style="color:yellow;"><code>utm_campaign</code></mark></td></tr><tr><td>UTM_Term</td><td><mark style="color:yellow;"><code>utm_term</code></mark></td></tr><tr><td>UTM_Content</td><td><mark style="color:yellow;"><code>utm_content</code></mark></td></tr><tr><td>UTM_ID</td><td><mark style="color:yellow;"><code>utm_id</code></mark></td></tr></tbody></table>

### How To Implement

| Attribute Name  | Attribute Value  | Which Page Element?       |
| --------------- | ---------------- | ------------------------- |
| data-extensions | marketing-params | \<script> Tag for Geoflow |

### Example

```html
<script data-extensions="marketing-params" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```


# Optional Settings

Adjust the default functionality for Geoflow globally with data attributes on the \<script> tag or a page-level basis with \<meta> tags.

### How Does It Work?

Geoflow's default functionality can be overridden or disabled by applying a set of data attributes to the \<script> tag or adding \<meta> tags on your page(s). The former approach is designed for applying adjustments globally (site-wide), while the latter approach is for a page-level basis.

### Example

```html
<script data-extensions="performance" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

### Browse The Optional Settings

{% content-ref url="/pages/vb2Ve3iFD5udAeOD0tVy" %}
[Script Tag Data Attributes](/geoflow-docs/feature/optional-settings/script-tag-data-attributes)
{% endcontent-ref %}

{% content-ref url="/pages/lBf7Tuq3Zf4ob0qkDDGT" %}
[Meta Tags](/geoflow-docs/feature/optional-settings/meta-tags)
{% endcontent-ref %}


# Script Tag Data Attributes

Adjust the default functionality by applying one or more of these data attributes to the \<script> tag for Geoflow.

### Enable Manual Mode

By default, Geoflow will be initialized automatically—including the visitor data properties being fetched—and the script extensions (if any) will run. To enable manual mode instead, apply the manual data attribute and call [geoflow.run()](/geoflow-docs/advanced/methods/run) when you want Geoflow to run.

The Geo Select feature will not be affected by this, as it doesn't require any visitor data properties.

{% code title="data-manual=true" %}

```html
<script data-manual="true" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Honouring Do Not Track (DNT) and Global Privacy Control (GPC)

DNT and GPC are two privacy preferences that a user can enable either through their browser or an application/extension. To instruct Geoflow to honour these preferences, apply the privacy data attribute to the \<script> tag. The visitor data properties will not be fetched automatically, nor will the script extensions (if any) run unless you manually initialize Geoflow by calling [geoflow.run()](/geoflow-docs/advanced/methods/run).

{% code title="data-privacy=true" %}

```html
<script data-privacy="true" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Ignore Visitor Data Properties

Define a comma-separated list of the visitor data properties you would like to have ignored.

The property name is case-sensitive and must match the 'Property Variable' noted in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties). The properties added here will be excluded from the 'geoflow' JS object.

{% code title="data-ignore=propName" %}

```html
<script data-ignore="countryName, countryCode" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Send The Visitor Data Somewhere

Define an endpoint that you would like the visitor data properties sent to when the visitor leaves your website. The endpoint must be a valid secure URL (including the https\:// part and a TLD); it can be anything that supports accepting a POST request (e.g. Zapier webhook).

If the URL that you provide is not valid, an error will be displayed in the browser console.

We recommend using our preferred webhook provider, [Hookdeck](https://hookdeck.com/), for your data endpoint.

{% code title="data-endpoint=URL" %}

```html
<script data-endpoint="https://hook.example.com" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Ignore Canonical

The Current Page URL (currentPage) value in the visitor data properties is set based on the canonical tag on the page, if available. Override this and tell Geoflow to use the current URL.

{% code title="data-canonical=false" %}

```html
<script data-canonical="false" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Disable Cache

When Geoflow attempts to fetch the visitor data properties, the script will check if they have been cached in the visitor's browser from a previous request in the last four hours. Applying this data attribute will instruct Geoflow always to fetch fresh data.

We recommend only using this data attribute during development on the staging website because disabling the cache will affect your website's performance.

{% code title="data-cache=false" %}

```html
<script data-cache="false" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Script Extensions

Script extensions allow you to extend the functionality offered by the default Geoflow script without writing a single line of code.

Learn more about the different [script extensions](/geoflow-docs/feature/script-extensions).

{% code title="data-extensions=extName" %}

```html
<script data-extensions="performance" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

***

### Cloudflare Rocket Loader

If you use Cloudflare's DNS proxy and have *Rocket Loader* activated, we encourage adding this data attribute to the \<script> tag to avoid potential issues.

Learn more about the data attribute in the [Cloudflare Docs](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/ignore-javascripts/).

{% code title="data-cfasync=false" %}

```html
<script data-cfasync="false" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}

### Turbo (formerly Turbolinks)

If you use Turbo (formerly Turbolinks) on your website, we strongly encourage adding this data attribute to the \<script> tag to avoid potential issues.

Learn more about the data attribute in the [Turbo Docs](https://turbo.hotwired.dev/handbook/building#working-with-script-elements).

{% code title="data-turbo-eval=false" %}

```html
<script data-turbo-eval="false" src="https://cdn.getgeoflow.com/beta/script.min.js" crossorigin="anonymous" fetchpriority="auto"></script>
```

{% endcode %}


# Meta Tags

Adjust the default functionality by adding one or more of these \<meta> tags to a page or two on your Webflow website.

### Ignore Visitor Data Properties

Define a comma-separated list of the visitor data properties you would like to have ignored.

The property name is case-sensitive and must match the 'Property Variable' noted in the [Visitor Data Properties table](/geoflow-docs/overview/visitor-data-properties). The properties added here will be excluded from the 'geoflow' JS object.

```html
<meta name="geoflow-ignore" content="countryName, countryCode">
```

### Send The Visitor Data Somewhere

Define an endpoint that you would like the visitor data properties sent to when the visitor leaves your website. The endpoint must be a valid secure URL (including the https\:// part and a TLD); it can be anything that supports accepting a POST request (e.g. Zapier webhook).

If the URL that you provide is not valid, an error will be displayed in the browser console.

We recommend using our preferred webhook provider, [Hookdeck](https://hookdeck.com/), for your data endpoint.

```html
<meta name="geoflow-endpoint" content="https://hook.example.com">
```

### Script Extensions

Script extensions allow you to extend the functionality offered by the default Geoflow script without writing a single line of code.

Learn more about the different [script extensions](/geoflow-docs/feature/script-extensions).

```html
<meta name="geoflow-extensions" content="performance, marketing-params">
```

{% hint style="info" %}
**Developer Tip**: The \<meta> tags are helpful if you would like to adjust the default functionality on a page-level basis. The \<meta> tag will be ignored if the data attribute for the same optional setting is also applied to the Geoflow \<script> tag.
{% endhint %}


# Code Snippets

Expand upon Geoflow's standard offerings with a little JavaScript.

<details>

<summary>Conditionally Change CSS Variable</summary>

```javascript
const root = document.documentElement;

const CSSvariable = 'primary-color';

window.addEventListener('geoflowReady', function () {

    const visitorCountry = geoflow.countryName;

    // If the Visitor's Country Name Cannot Be Detected, Stop the Script
    
    if (!visitorCountry){

    console.error('Unable to detect the visitor\'s country name.');
    return;
      
    }

    if (visitorCountry === 'United States') { // If Visitor is from the US

        root.style.setProperty(`--${CSSvariable}`, '#1e88e5'); // Set the Primary Color to Blue

    } else if (visitorCountry === 'Canada') { // If Visitor is from Canada

        root.style.setProperty(`--${CSSvariable}`, '#f44336'); // Set the Primary Color to Red

    }

});
```

</details>

<details>

<summary>Conditionally Change Text Content</summary>

```javascript
window.addEventListener('geoflowReady', function () {

  // Get the Country Name of the Visitor
  const visitorCountry = geoflow.countryName;

  // If the Visitor's Country Name Cannot Be Detected, Stop the Script
  if (!visitorCountry){

    console.error('Unable to detect the visitor\'s country name.');
    return;
      
  }

  // Add the ID for the Element You Want to Change the Text Content of
  const personalizedGreeting = document.getElementById('personalized-greeting');

  // Conditionally Change the Text Content of the Element
  switch (visitorCountry) {

    case 'Australia': // If the Visitor is in Australia
      personalizedGreeting.textContent = `G'Day Mate!`;
      break;
      
    case 'New Zealand': // If the Visitor is in New Zealand
      personalizedGreeting.textContent = `Kia ora!`;
      break;
      
    case 'Canada': // If the Visitor is in Canada
      personalizedGreeting.textContent = `How's It Goin', Eh?`;
      break;

    case 'United Kingdom': // If the Visitor is in the UK
      personalizedGreeting.textContent = `Fancy a Cuppa?`;
      break;

    default: // If the Visitor is in Any Other Country, Do Nothing
      break;

  }

});
```

</details>

<details>

<summary>Change App Download Link Based on OS</summary>

```javascript
window.addEventListener('geoflowReady', function () {

  // Get the Operating System of the Visitor
  let visitorOS = geoflow.OS;

  // If the Visitor's OS Cannot Be Detected, Stop the Script
  if (!visitorOS){

    console.error('Unable to detect the visitor\'s operating system.');
    return;
  
  }

  // Add the ID for the Link You Want to Change
  const downloadAppLink = document.getElementById('download-app-link');

  // Create a Regular Expression for Mac OS
  const macOSRegex = /(Mac OS|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/i; // Use 'i' flag for Case-Insensitivity
  visitorOS = macOSRegex.test(visitorOS) ? 'Mac OS' : visitorOS; // If the Visitor's OS Matches the Regular Expression, Change the OS Name to 'Mac OS'

  // Conditionally Change the Link
  switch (visitorOS) {
      
    case 'iOS': // If the Visitor is on iOS
      downloadAppLink.href = `https://example.com`;
      break;

    case 'Mac OS': // If the Visitor is on Mac OS
      downloadAppLink.href = `https://example.com`;
      break;

    case 'Android': // If the Visitor is on Android
      downloadAppLink.href = `https://example.com`;
      break;

    case 'Windows': // If the Visitor is on Windows
      downloadAppLink.href = `https://example.com`;
      break;

    default: // If the Visitor is on Any Other OS, Do Nothing
      break;

  }

});
```

</details>

<details>

<summary>Populate List of Provinces/States Based on Chosen Country</summary>

```javascript
document.addEventListener('DOMContentLoaded', function () {

  // Add the ID for Your <select> Element Where A Country Is Chosen
  const chooseCountrySelect = document.getElementById('choose-country');

  chooseCountrySelect.addEventListener('change', function () {
    
    // Get the Chosen Country
    const chosenCountry = chooseCountrySelect.options[chooseCountrySelect.selectedIndex].value;

    switch (chosenCountry) {

      case 'australia':
        geoflow.select('#choose-state', 'au-states-and-territories', 'Choose Your State/Territory');
        break;

      case 'canada':
        geoflow.select('#choose-state', 'ca-provinces-and-territories', 'Choose Your Province/Territory');
        break;

      case 'united-states':
        geoflow.select('#choose-state', 'us-states', 'Choose Your State');
        break;

      default:
        break;

    }

  });

});
```

</details>

<details>

<summary>Wait for Cookiebot Consent to Run Geoflow</summary>

```javascript
function CookiebotCallback_OnAccept() { geoflow.run(); }
```

Visit the [Cookiebot Developer Resources](https://www.cookiebot.com/en/developer/) for more information on using the CookiebotCallback\_OnAccept callback to run Geoflow manually.

</details>


# Methods

The following methods are made accessible anywhere on the page, through the 'geoflow' client-side JavaScript object by Geoflow.

<table data-full-width="false"><thead><tr><th width="193">Method Name</th><th>Method Description</th></tr></thead><tbody><tr><td>run</td><td>The primary initialization function for Geoflow is responsible for calling getData and running the script extensions (if enabled).</td></tr><tr><td>getData</td><td>Fetches the visitor data properties.</td></tr><tr><td>updateData</td><td>Use this to override any visitor data property, simulating what different visitors may experience on your website.</td></tr><tr><td>displayData</td><td>Output the visitor data properties that are currently available.</td></tr><tr><td>clearData</td><td>Force clear any visitor data properties saved in the browser's session storage. This will not effect the 'geoflow' JS object.</td></tr><tr><td>checkCondition</td><td>Returns a boolean based on the condition and value passed.</td></tr><tr><td>select</td><td>Appends one or more &#x3C;option> elements to a &#x3C;select> element based on the category passed and an optional placeholder.</td></tr></tbody></table>

### Examples

```javascript
// Clear the Current Visitor Data Properties Saved in Session Storage
geoflow.clearData();

// Change the Current Country Code to US (United States)
geoflow.updateData({ countryCode: 'US' });

// Add All Countries to the <select> with an ID of 'choose-country'
geoflow.select('#choose-country', 'all-countries', 'Choose a Country');
```


# run

The primary initialization function for Geoflow is responsible for calling getData and running the script extensions (if enabled).

### Description

This method is the primary initialization function that controls Geoflow; it is responsible for calling getData to populate the visitor data properties and running any specified script extensions.

If you added **\[data-manual=true]** or **\[data-privacy=true]** on the \<script> tag, then you can use this method to run Geoflow manually. Learn more about those data attributes [here](/geoflow-docs/feature/optional-settings/script-tag-data-attributes).

### Parameters

```
None
```

### Using This Method

```javascript
geoflow.run();
```

### Output

```javascript
None
```


# getData

Fetches the visitor data properties.

### Description

This method fetches the available data properties for the current visitor. Unless you have specified the manual or privacy data attribute on the \<script> tag (see more [here](/geoflow-docs/feature/optional-settings/script-tag-data-attributes)), getData will be automatically called by the initialization method.

The geoflowReady event will be fired, and the Geoflow\_Ready callback will be triggered.

### Parameters

```
None
```

### Using This Method

```javascript
geoflow.getData();
```

### Output

```javascript
true (boolean)
```


# updateData

Use this to override any visitor data property, simulating what different visitors may experience on your website.

### Description

This method allows you to change any visitor data property; the changes are reflected in the 'geoflow' JS object and session storage. One advantage to this is that it allows you to simulate what different visitors may experience on your Webflow website.

An object containing key-value pairs of visitor data properties, separated by commas, is accepted. Each key-value pair consists of a propertyName (e.g. countryCode) as the key and its corresponding propertyValue (e.g. US) as the value. Both are treated as strings.

The geoflowUpdated event will be fired, and the Geoflow\_Updated callback will be triggered.

### Parameters

```vbnet
{ propertyName (string key): propertyValue (string) }
```

### Using This Method

```javascript
geoflow.updateData({ countryCode: 'US' });
```

### Output

```javascript
true (boolean)
```


# displayData

Output the visitor data properties that are currently available.

### Description

This method will return a JavaScript object containing the available visitor data properties. Any properties that were ignored or had no value available will not be included.

### Parameters

```
None
```

### Using This Method

```javascript
geoflow.displayData();
```

### Output

```javascript
{
  "continentName": "Oceania",
  "continentCode": "OC",
  "countryName": "Australia",
  "countryCode": "AU",
  "region": "Oceania",
  "nationalCapital": "Canberra",
  "city": "Melbourne",
  "stateName": "Victoria",
  "stateCode": "VIC",
  "postalCode": "3000",
  "isEU": true,
  "timezone": "Australia/Melbourne",
  "latitude": "-37.81590",
  "longitude": "144.96690",
  "airportCode": "MEL",
  "currencyCode": "AUD",
  "currencySymbol": "$",
  "callingCode": 61,
  "language": "en-AU",
  "ASN": 4804,
  "ISP": "Optus",
  "isMobile": false,
  "deviceType": "Desktop",
  "dataSaver": false,
  "reducedMotion": false,
  "colorPreference": "dark",
  "OS": "Windows",
  "currentPage": "getgeoflow.com",
  "referer": "webflow.com",
  "userAgent": "Chrome/118.0.0.0",
  "IP": "192.168.1.1"
} (object)
```


# clearData

Force clear any visitor data properties saved in the browser's session storage. This will not effect the 'geoflow' JS object.

### Description

This method will clear the data properties currently saved in the visitor's browser through the session storage. The 'geoflow' JS object will not be affected.

### Parameters

```
None
```

### Using This Method

```javascript
geoflow.clearData();
```

### Output

```javascript
true (boolean)
```


# checkCondition

Returns a boolean based on the condition and value passed.

### Description

This method lets you manually check a condition by passing a property name and value.

The value you pass will be checked against that property name in the visitor data properties. Either true or false will be returned in the response.

### Parameters

```vbnet
propertyName (string), propertyValue (string)
```

### Using This Method

```javascript
geoflow.checkCondition('countryCode', 'US');
```

### Output

```javascript
true (boolean) or false (boolean)
```


# select

Appends one or more \<option> elements to a \<select> element based on the category passed and an optional placeholder.

### Description

This method can programmatically populate a \<select> element with \<option> elements based on a specified category. An optional can also be passed, appearing as the first \<option> element. Otherwise, the default placeholder will be used 'Choose an Option'.

The first parameter should be the CSS Selector for the \<select> element (e.g. #chooseCountry), followed by the category of options (e.g. all-countries) you would like to use and lastly, an optional placeholder if you'd like to override the default one (e.g. Choose a Country).

The available categories are specified on this page [here](/geoflow-docs/feature/form/auto-populate-select-fields).

### Parameters

```vbnet
elementIdentifier (string), category (string), placeholder (string, optional)
```

### Using This Method

```javascript
geoflow.select('#choose-country', 'all-countries', 'Choose a Country');
```

### Output

```javascript
true (boolean)
```


# Callbacks

Geoflow triggers the following callbacks and can be accessed anywhere on the page, allowing you to add custom functionality.

<table><thead><tr><th width="218">Callback Name</th><th>Callback Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Geoflow_Ready</td><td>The asynchronous callback is triggered when the visitor data properties are ready.</td><td></td></tr><tr><td>Geoflow_Error</td><td>The asynchronous callback is triggered when an error was thrown while the visitor data properties were being fetched.</td><td></td></tr><tr><td>Geoflow_Updated</td><td>The asynchronous callback is triggered when the 'geoflow' object has been successfully updated after the updateData method is called.</td><td></td></tr><tr><td>Geoflow_ExtComplete</td><td>The asynchronous callback is triggered when a script extension has finished running. The extension name is passed as a function parameter.</td><td></td></tr></tbody></table>

{% hint style="info" %}
**Developer Tip**: When using the *Geoflow\_Ready* and *Geoflow\_Updated* callbacks, the current Geoflow object can also be accessed through the function parameter.
{% endhint %}

### Examples

```javascript
function Geoflow_Ready(geoflow) {

    console.log('Geoflow Is Ready!', geoflow);

}

function Geoflow_Error(error) {

    console.error('Geoflow Error!', error);

}

function Geoflow_Updated(geoflow) {

    console.log('Geoflow Was Updated!', geoflow);

}

function Geoflow_ExtComplete(extName) {

    console.log('This Script Extension Finished Running:', extName);

}
```


# Events

Geoflow fires the following events on the window object and can be accessed anywhere on the page, allowing you to add custom functionality.

<table><thead><tr><th width="206">Event Name</th><th>Event Description</th><th data-hidden></th></tr></thead><tbody><tr><td>geoflowReady</td><td>Fires when the visitor data properties are ready.</td><td></td></tr><tr><td>geoflowError</td><td>Fires when an error was thrown while the visitor data properties were being fetched (e.g. due to a server error).</td><td></td></tr><tr><td>geoflowUpdated</td><td>Fires when the 'geoflow' object has been successfully updated after the <a href="/geoflow-docs/advanced/methods">updateData()</a> method is called.</td><td></td></tr><tr><td>geoflowExtComplete</td><td>Fires when a script extension has finished running. The extension name can be accessed on the event's detail property.</td><td></td></tr></tbody></table>

{% hint style="info" %}
**Developer Tip**: When listening for the *geoflowReady* and *geoflowUpdated* events, the current 'geoflow' object can also be accessed through the event's detail property.
{% endhint %}

### Examples

```javascript
window.addEventListener('geoflowReady', function (e) {

    console.log('Geoflow Is Ready!', e.detail);

});

window.addEventListener('geoflowError', function (e) {

    console.log('Geoflow Error!', e.detail);

});

window.addEventListener('geoflowUpdated', function (e) {

    console.log('Geoflow Was Updated!', e.detail);

});

window.addEventListener('geoflowExtComplete', function (e) {

    console.log('This Script Extension Finished Running:', e.detail);

});
```


# REST API

Geoflow offers a REST API that allows you to implement advanced functionality through your own backend or via Zapier, Make, Airtable, and more.

{% hint style="info" %}
If you want to try the REST API, please contact us at **<developer@getgeoflow.com>** and share what you would like to build with it, along with any other necessary information.

If your request is accepted, you will receive an API Key and further instructions.
{% endhint %}

### Base REST URL

```
https://getgeoflow.com/beta/api
```

### Authentication

```
Authorization: Bearer <TOKEN>
```

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}

### Rate Limit

25 Requests per Second

### Available Endpoints

<table><thead><tr><th>Endpoint Name</th><th width="222.33333333333331">Endpoint Path</th><th>Endpoint Description</th><th data-hidden></th></tr></thead><tbody><tr><td>Get Visitor IP</td><td>/get-visitor-ip</td><td>Get the IP address for a visitor or online device.</td><td></td></tr><tr><td>Get Visitor Data</td><td>/get-visitor-data</td><td>Get the data associated with a specific IP address.</td><td></td></tr><tr><td>Add Website</td><td>/add-website/:accountID</td><td>Add a single website to your account.</td><td></td></tr><tr><td>Delete Website</td><td>/delete-website/:siteID</td><td>Delete a single website from your account.</td><td></td></tr><tr><td>Update Website</td><td>/edit-website/:siteID</td><td>Update a single website that is in your account.</td><td></td></tr><tr><td>List Websites</td><td>/list-websites/:accountID</td><td>List all the websites that are in your account.</td><td></td></tr><tr><td>Get Website</td><td>/get-website/:siteID</td><td>Get a single website that is in your account.</td><td></td></tr></tbody></table>


# Get Visitor IP

## Get the IP address for a visitor or online device.

<mark style="color:blue;">`GET`</mark> `https://getgeoflow.com/beta/api/get-visitor-ip`

#### Headers

| Name                                            | Type   | Description     |
| ----------------------------------------------- | ------ | --------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN> |

{% tabs %}
{% tab title="200: OK IP Address Found" %}

```json
{
    "visitor_ip": "192.168.1.1"
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found No IP Address Found or Invalid Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or the IP address could not be found. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# Get Visitor Data

## Get the data associated with a specific IP address.

<mark style="color:blue;">`GET`</mark> `https://getgeoflow.com/beta/api/get-visitor-data`

The same properties outlined in the [Visitor Data Properties](/geoflow-docs/overview/visitor-data-properties) table will be returned in the response, where available or applicable.

This will be based on an IP address you provide in the `X-Visitor-IP` header. If the header is omitted, the first IP address found in the `X-Forwarded-For` header will be used.

#### Headers

| Name                                            | Type   | Description        |
| ----------------------------------------------- | ------ | ------------------ |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN>    |
| X-Visitor-IP                                    | String | Visitor IP Address |

{% tabs %}
{% tab title="200: OK Visitor Data Found" %}

```json
{
  "continentName": "Oceania",
  "continentCode": "OC",
  "countryName": "Australia",
  "countryCode": "AU",
  "region": "Oceania",
  "nationalCapital": "Canberra",
  "city": "Melbourne",
  "stateName": "Victoria",
  "stateCode": "VIC",
  "postalCode": "3000",
  "isEU": true,
  "timezone": "Australia/Melbourne",
  "latitude": "-37.81590",
  "longitude": "144.96690",
  "airportCode": "MEL",
  "currencyCode": "AUD",
  "currencySymbol": "$",
  "callingCode": 61,
  "language": "en-AU",
  "ASN": 4804,
  "ISP": "Optus",
  "isMobile": false,
  "deviceType": "Desktop",
  "dataSaver": false,
  "reducedMotion": false,
  "colorPreference": "dark",
  "OS": "Windows",
  "currentPage": "getgeoflow.com",
  "referer": "webflow.com",
  "userAgent": "Chrome/118.0.0.0",
  "IP": "192.168.1.1"
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found No Visitor Data Found or Invalid Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or the visitor data could not be found based on the IP address used. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# Add Website

## Add a single website to your account.

<mark style="color:green;">`POST`</mark> `https://getgeoflow.com/beta/api/add-website/:accountID`

Add a single website to your Geoflow account by passing a valid URL (including https) and the Webflow site ID. Optionally provide a name for your website, otherwise one will be randomly generated for you.

#### Path Parameters

| Name                                        | Type   | Description     |
| ------------------------------------------- | ------ | --------------- |
| accountID<mark style="color:red;">\*</mark> | String | Your Account ID |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | application/json |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN>  |

#### Request Body

| Name                                         | Type   | Description                  |
| -------------------------------------------- | ------ | ---------------------------- |
| websiteURL<mark style="color:red;">\*</mark> | String | Valid Website URL with HTTPS |
| websiteID<mark style="color:red;">\*</mark>  | String | Your Webflow Site ID         |
| websiteName                                  | String | Your Website Name            |

{% tabs %}
{% tab title="201: Created Website Added Successfully" %}

```json
{
    "status": 201,
    "message": "Success",
    "description": "Your website was successfully added to your Geoflow account."
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found Invalid Account ID or Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or an invalid account ID was added as a parameter. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# Delete Website

## Delete a single website from your account.

<mark style="color:red;">`DELETE`</mark> `https://getgeoflow.com/beta/api/delete-website/:siteID`

Delete a single website from your Geoflow account by passing the Webflow site ID.

#### Path Parameters

| Name                                     | Type   | Description          |
| ---------------------------------------- | ------ | -------------------- |
| siteID<mark style="color:red;">\*</mark> | String | Your Webflow Site ID |

#### Headers

| Name                                            | Type   | Description     |
| ----------------------------------------------- | ------ | --------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN> |

{% tabs %}
{% tab title="200: OK Website Deleted Successfully" %}

```json
{
    "status": 200,
    "message": "Success",
    "description": "Your website has been successfully deleted from your Geoflow account."
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found Invalid Site ID or Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or an invalid site ID was added as a parameter. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# Update Website

## Update a single website that is in your account.

<mark style="color:purple;">`PATCH`</mark> `https://getgeoflow.com/beta/api/update-website/:siteID`

Update a single website in your Geoflow account by passing a new name or URL. If for any reason you need to modify the site ID, please contact support.

#### Path Parameters

| Name                                     | Type   | Description          |
| ---------------------------------------- | ------ | -------------------- |
| siteID<mark style="color:red;">\*</mark> | String | Your Webflow Site ID |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Content-Type<mark style="color:red;">\*</mark>  | String | application/json |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN>  |

#### Request Body

| Name        | Type   | Description                  |
| ----------- | ------ | ---------------------------- |
| websiteURL  | String | Valid Website URL with HTTPS |
| websiteName | String | Your Website Name            |

{% tabs %}
{% tab title="200: OK Website Updated Successfully" %}

```json
{
    "status": 200,
    "message": "Success",
    "description": "Your website was successfully updated in your Geoflow account."
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found Invalid Site ID or Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or an invalid site ID was added as a parameter. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# List Websites

## List of all the websites that are in your account.

<mark style="color:blue;">`GET`</mark> `https://getgeoflow.com/beta/api/list-websites/:accountID`

#### Path Parameters

| Name      | Type   | Description     |
| --------- | ------ | --------------- |
| accountID | String | Your Account ID |

#### Headers

| Name                                            | Type   | Description     |
| ----------------------------------------------- | ------ | --------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN> |

{% tabs %}
{% tab title="200: OK Websites Found" %}

```json
{
  "websites": [
    {
      "id": "123ABC",
      "name": "Example 1",
      "url": "https://example.com",
      "lastUpdated": "2023-10-29T15:34:00Z",
      "added": "2023-01-14T12:12:00Z"
    },
    {
      "id": "123ABC",
      "name": "Example 2",
      "url": "https://example.com",
      "lastUpdated": "2023-10-20T09:45:00Z",
      "added": "2023-05-22T10:10:00Z"
    },
    {
      "id": "123ABC",
      "name": "Example 3",
      "url": "https://example.com",
      "lastUpdated": "2023-10-25T18:30:00Z",
      "added": "2023-03-15T14:15:00Z"
    }
  ]
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found Invalid Account ID or Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or an invalid account ID was added as a parameter. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}

{% tab title="204: No Content No Websites Found" %}

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# Get Website

## Get a single website that is in your account.

<mark style="color:blue;">`GET`</mark> `https://getgeoflow.com/beta/api/get-website/:siteID`

#### Path Parameters

| Name   | Type   | Description          |
| ------ | ------ | -------------------- |
| siteID | String | Your Webflow Site ID |

#### Headers

| Name                                            | Type   | Description     |
| ----------------------------------------------- | ------ | --------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer \<TOKEN> |

{% tabs %}
{% tab title="200: OK Website Found" %}

```json
{
      "id": "123ABC",
      "name": "Example 1",
      "url": "https://example.com",
      "lastUpdated": "2023-10-29T15:34:00Z",
      "added": "2023-01-14T12:12:00Z"
}
```

{% endtab %}

{% tab title="401: Unauthorized Unauthorized Request" %}

```json
{
    "status": 401,
    "message": "Unauthorized",
    "description": "No API key was provided or you do not have access to this resource. Please provide a valid Geoflow REST API key or contact support."
}
```

{% endtab %}

{% tab title="429: Too Many Requests Exceeded Rate Limit" %}

```json
{
    "status": 429,
    "message": "Too Many Requests",
    "description": "You have sent too many requests in a given amount of time. Please wait before sending more requests."
}
```

{% endtab %}

{% tab title="404: Not Found Invalid Site ID or Endpoint" %}

```json
{
    "status": 404,
    "message": "Not Found",
    "description": "The endpoint you are trying to access does not exist or has been moved, or an invalid site ID was added as a parameter. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="405: Method Not Allowed Prohibited Method" %}

```json
{
    "status": 405,
    "message": "Method Not Allowed",
    "description": "The HTTP method used is not supported for this endpoint. Please refer to the Geoflow REST API documentation for further information or contact support."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unknown Error" %}

```json
{
    "status": 500,
    "message": "Internal Server Error",
    "description": "An unexpected error occurred on the server. The Geoflow API may be down or encountering another issue. Please try again later or contact support."
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Developer Warning**: Never share your API key with anyone or add it to client-side code. Where possible, use environment variables in your backend to keep your API key secure.
{% endhint %}


# License Agreement

By using Geoflow, you acknowledge that you have read, understood, and agree to be bound by this License Agreement.

This License Agreement (“Agreement”) is entered into between Geoflow, hereafter referred to as the "Licensor", and the end user, hereafter referred to as the "User".

1. **Provision of the Solution**: The Licensor hereby grants the User a license to access and use Geoflow (hereafter referred to as the "Solution") per the terms of this Agreement. This license is non-exclusive, non-sublicensable, non-transferable, and subject to the terms and conditions set forth herein.<br>
2. **As-Is Basis**: The Solution is provided "as-is" without any warranties, express or implied, including but not limited to fitness for a particular purpose, merchantability, non-infringement, or accuracy. The Licensor shall not be liable for any damages, including but not limited to direct, indirect, incidental, consequential, or special damages, arising out of or in connection with the User's use of the Solution.<br>
3. **Prohibited Activities**:<br>
   * **Copying**: The User shall not copy, reproduce, or create derivative works from the Solution.
   * **Modifying**: The User shall not modify, reverse engineer, decompile, or disassemble the Solution in any manner.
   * **Selling**: The User is prohibited from selling, renting, leasing, distributing, or otherwise transferring the Solution.
   * **Self-Hosting**: The User shall not host, deploy, or make the Solution available on any server or platform other than those expressly provided by the Licensor.<br>
4. **Intellectual Property Rights**: The User acknowledges that Geoflow, including its software, interfaces, functionalities, updates, and documentation, is the exclusive property of the Licensor, protected under intellectual property laws. This encompasses all related copyrights, trademarks, patents, trade secrets, and other proprietary rights. The User agrees not to assert any ownership, right, title, or interest in or to such intellectual property at any time. The User is granted a license to use Geoflow per the terms of this Agreement, but no ownership rights are transferred hereby. The User acknowledges that the use of Geoflow does not confer upon them any rights to the underlying intellectual property, except for the limited use rights expressly granted in this Agreement.<br>
5. **Feedback**: The User is encouraged to provide feedback, suggestions, or comments about the Solution. All feedback provided by the User shall be deemed non-confidential and the Licensor shall be free to use such feedback without any restrictions.<br>
6. **Updates and Maintenance**: The Licensor may from time to time provide updates or upgrades to the Solution, but is not under any obligation to do so. Such updates or upgrades shall be subject to the terms and conditions of this Agreement unless the Licensor specifies otherwise.<br>
7. **Indemnification**: The User agrees to indemnify, defend, and hold harmless the Licensor and its affiliates, officers, agents, employees, and licensors from any claim, demand, loss, damage, or expense, including attorneys' fees, arising out of the User's use of the Solution, violation of this Agreement, or violation of any rights of another.<br>
8. **Limitation of Liability**: In no event will the Licensor be liable for any indirect, incidental, special, punitive, or consequential damages, or any loss of profits, revenue, data, or use, incurred by the User or any third party, whether in an action in contract or tort, even if the Licensor has been advised of the possibility of such damages.<br>
9. **Termination**: The Licensor reserves the right to terminate this Agreement and revoke the User's access to the Solution at any time, with or without cause. Upon termination, the User shall cease all use of the Solution and destroy all copies, documentation, and related materials.<br>
10. **Modification of Agreement**: The Licensor reserves the right to modify this Agreement at any time. Continued use of the Solution after any such changes shall constitute the User's consent to such changes.<br>
11. **Severability**: If any provision of this Agreement is found to be invalid or unenforceable, the remaining provisions will remain in full force and effect.


