# Getting started The Felt REST API allows you to programmatically interact with the Felt platform, enabling you to integrate Felt's powerful mapping capabilities into your own workflows and pipelines. You are able to create and manipulate Maps, Layers, Annotations, Sources, Projects and more. This feature is available to customers on the [Enterprise plan](https://felt.com/pricing). Reach out to [set up a trial](https://felt.com/sales). ## Endpoints All Felt API endpoints are hosted at the following base URL: ``` https://felt.com/api/v2 ``` ## Create an API token All calls to the Felt API must be authenticated. The easiest way to authenticate your API calls is by creating a API token and providing it as a `Bearer` token in the request header. You can create an API token in the [Developers tab of the Workspace Settings page](https://felt.com/maps/latest/developers):

You can generate as many API tokens as you need. Make sure to copy them to a secure location!

Learn more about API tokens here: {% content-ref url="authentication" %} [authentication](https://developers.felt.com/rest-api/authentication) {% endcontent-ref %} ## Install our Python library (optional) The easiest way to interact with the Felt API is by using our `felt-python` SDK. You can install it with the following command: ```bash pip install felt-python ``` ## Example: Creating a new map Creating a new map is as simple as making a POST request to the maps endpoint. {% tabs %} {% tab title="curl" %} ```bash # Your API token should look like this: # FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8" FELT_API_TOKEN="" curl -L \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${FELT_API_TOKEN}" \ "https://felt.com/api/v2/maps" \ -d '{"title": "My newly created map"}' ``` {% endtab %} {% tab title="Python" %} ```python import requests # This looks like: # api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8" api_token = "" r = requests.post( "http://felt.com/api/v2/maps", json={"title": "My newly created map"}, headers={"Authorization": f"Bearer {api_token}"} ) assert r.ok map_id = r.json()["id"] print(r.json()) ``` {% endtab %} {% tab title="felt-python" %} ```python import os from felt_python import create_map # Setting your API token as an env variable can save # you from repeating it in every function call os.environ["FELT_API_TOKEN"] = "" response = create_map( title="My newly created map", lat=40, lon=-3, public_access="private", ) map_id = response["id"] ``` {% endtab %} {% endtabs %} Notice in the response the `"id"` property. Every map has a unique ID, which is also a part of the map's URL. Let's take note of it for future API calls. Also part of the response is a `"url"` property, which is the URL to your newly-created map. Feel free to open it! For now, it should just show a blank map. ## Example: Uploading a layer from a URL Now that we've created a new map, let's add some data to it. We'll need the `map_id` included in the previous call's response. Felt supports [many kinds of file and URL imports](https://help.felt.com/upload-anything/files). In this case, we'll import all the recent earthquakes from [the USGS' live GeoJSON feed](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php): {% tabs %} {% tab title="curl" %} ```bash # Store the map ID from the previous call: # MAP_ID="CjU1CMJPTAGofjOK3ICf1D" MAP_ID="" curl -L \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${FELT_API_TOKEN}" \ "https://felt.com/api/v2/maps/${MAP_ID}/upload" \ -d '{"import_url":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson", "name": "USGS Earthquakes"}' ``` {% endtab %} {% tab title="Python" %} ```python r = requests.post( f"http://felt.com/api/v2/maps/{map_id}/upload", json={ "import_url":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson", "name": "USGS Earthquakes", }, headers={"Authorization": f"Bearer {api_token}"} ) assert r.ok layer_id = r.json()["layer_id"] print(r.json()) ``` {% endtab %} {% tab title="felt-python" %} ```python from felt_python import upload_url url_upload = upload_url( map_id=map_id, layer_url="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson", layer_name="USGS Earthquakes", ) layer_id = url_upload["layer_id"] ``` {% endtab %} {% endtabs %} Like maps, layers also have unique identifiers. Let's take note of this one (also called `"id"` in the response) so we can style it in the next call. You can see the uploaded result in your map:

Since we imported a live data feed, the points on your layer may look different.

## Example: Styling a layer {% hint style="info" %} Layer styles are defined in the [Felt Style Language](https://github.com/felt/developer-docs/blob/main/rest-api/broken-reference/README.md), a JSON-based specification that allows customizing a layer's style, legend, label and popups. {% endhint %} Layers can be styled at upload time or afterwards. Let's change the style of our newly-created earthquakes layer so that points are bigger and in green color: {% tabs %} {% tab title="curl" %} ```bash # Store the layer ID from the previous call: # LAYER_ID="CjU1CMJPTAGofjOK3ICf1D" LAYER_ID="" curl -L \ -X POST \ "https://felt.com/api/v2/maps/${MAP_ID}/layers/${LAYER_ID}/update_style" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${FELT_API_TOKEN}" \ --data '{"style": {"paint": {"color": "green", "opacity": 0.9, "size": 30, "strokeColor": "auto", "strokeWidth": 1}, "legend": {}, "type": "simple", "version": "2.1"}}' ``` {% endtab %} {% tab title="Python" %} ```python new_fsl = { "paint": { "color": "green", "opacity": 0.9, "size": 30, "strokeColor": "auto", "strokeWidth": 1 }, "legend": {}, "type": "simple", "version": "2.1" } r = requests.post( f"http://felt.com/api/v2/maps/{map_id}/layers/{layer_id}/update_style", json={"style": new_fsl}, headers={"Authorization": f"Bearer {api_token}"} ) assert r.ok print(r.json()) ``` {% endtab %} {% tab title="felt-python" %} ```python from felt_python import update_layer_style new_fsl = { "paint": { "color": "green", "opacity": 0.9, "size": 30, "strokeColor": "auto", "strokeWidth": 1 }, "legend": {}, "type": "simple", "version": "2.1" } update_layer_style( map_id=map_id, layer_id=layer_id, style=new_fsl, ) ``` {% endtab %} {% endtabs %} Go to your map to see how your new layer looks:

Since we imported a live data feed, the points on your layer may look different.

## Example: Refreshing a live data layer {% hint style="warning" %} A layer must have finished uploading successfully before it can be refreshed {% endhint %} Similar to [a URL upload](https://developers.felt.com/rest-api/uploading-files-and-urls), refreshing an existing URL layer is just a matter of making a single `POST` request: {% tabs %} {% tab title="curl" %} ```bash curl -L \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${FELT_API_TOKEN}" \ "https://felt.com/api/v2/maps/${MAP_ID}/layers/${LAYER_ID}/refresh" ``` {% endtab %} {% tab title="Python" %} ```python r = requests.post( f"https://felt.com/api/v2/maps/{map_id}/layers/{layer_id}/refresh", headers={"Authorization": f"Bearer {api_token}"} ) assert r.ok print(r.json()) ``` {% endtab %} {% tab title="felt-python" %} ```python from felt_python import refresh_url_layer refresh_url_layer(map_id, layer_id) ``` {% endtab %} {% endtabs %} Now go to your map and see if any new earthquakes have occured!