arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 60

Home

Loading...

REST API

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

JS SDK

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Felt Style Language

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

API Reference

Layer Uploads

APIs to upload data

With these APIs, you can upload your data to create new layers.

Elements

APIs for drawing spatially

Elements enable you to annotate maps with custom shapes, text, and markers.

With these APIs, you can create, update, and delete map elements.

Layer Library

APIs to publish layers

With these APIs, you can publish your layers to your workspace library.

Comments

APIs for programatic collaboration

Comments bring conversations to mapping.

With these APIs, you can export, resolve, and delete map comments and collaboration threads.

Users

APIs for user information

Users represent the people in your workspace.

With these APIs, you can retrieve user profile information.

Projects

APIs to organize maps

Projects help you organize maps and manage team permissions.

With these APIs, you can manage the projects in your workspace.

Layers

APIs to visualize spatial data

Layers enable you to visualize, style and interact with your spatial data.

With these APIs, you can upload data, manage layer styling, publish and refresh live data layers.

Maps

APIs for building maps

Maps are the centerpiece of Felt.

With these APIs, you can create, retrieve, update, delete, move, and duplicate maps programmatically.

Embed Tokens

APIs to share maps securely

Embed tokens enable safely sharing your private maps.

With these APIs, you can generate secure tokens for embedding maps.

Layer Exports

APIs to export layer data

With these APIs, you can export data to CSV, GeoJSON, and other formats.

Overview

hashtag
Felt’s Developer Tools

There are a variety of ways to interact with Felt’s modern GIS platform outside of the user interface. They can be grouped into two buckets: tools for programmatically creating and modifying maps, and tools for building custom experiences for map viewers. These tools can be used to solve distinct challenges and also be used in tandem with one another.

hashtag

Sources

APIs to connect your data

Sources connect your databases to Felt.

With these APIs, you can configure data source connections, credentials, and sync settings to create live maps.

Creating and modifying maps

Felt’s REST API allows editors to interact with the Felt platform via code, performing actions such as creating new maps, adding data to maps, styling layers, and more. The REST API can be leveraged from any environment that is capable of sending GET and POST requests.

For Python users, interactions with the REST API are simplified through the felt-pythonarrow-up-right module, which can be installed with pip and used to call the REST API endpoints directly from Python functions.

hashtag
Creating custom applications

Felt’s user interface allows a large amount of customization, offering the ability to generate complex cartographic designs, adding components to create a dashboard, and much more.

However, sometimes application developers need further control over the experience of viewing and/or interacting with a map. For example, they may want to run custom logic after a user clicks on a feature in a layer, or animate data on the map based on other types of user input elsewhere on the webpage. For these situations and many more, Felt’s JavaScript SDK allows developers to programmatically control maps in two ways: Extensionsarrow-up-right let you write custom code directly within Felt maps, with access to all SDK functionality. Alternatively, you can embed Felt maps into your own applications and use the SDK to control the embedded map experience.

circle-info

hashtag
Note: looking for Element-related documentation? They are now called Annotations.

References have been updated in the app and documentation, while naming in the REST API and JS SDK remains unchanged. See Working with annotations and Drawing annotationsfor more.

Controlling maps

The Felt SDK has a number of methods for interacting with maps, depending on how you set up your HTML.

All Felt maps are embedded in iframes, and the SDK can do this for you or can connect to an existing Felt iframe.

hashtag
Felt map IDs

Felt map IDs are unique identifiers for Felt maps. They are used to embed maps in iframes, and to connect to existing iframes.

To get the ID of a Felt map, click the Map settings button in the main toolbar, and then you can see the Map ID in the Developers section.

Alternatively, you can look at the URL of the map. For example, the map at https://felt.com/map/Map-title-xPV9BqMuYQxmUraVWy9C89BNA has the ID xPV9BqMuYQxmUraVWy9C89BNA.

Throughout the documentation, we'll use the placeholder FELT_MAP_ID to refer to a Felt map ID.

hashtag
Using Felt.embed to create an iframe

Create an HTML page with a container element:

Embed a Felt map in your container element and use the SDK to control it by calling Felt.embed, passing the container element as the first argument:

hashtag
Using Felt.embed to mount into an existing iframe

In some cases, you may want to add a "template" iframe to your page. This can be useful if you want to style your iframe in a specific way, or if you already have one map embedded and want to mount and control a different map.

In this case, you can call Felt.embed with the iframe element as the first argument:

hashtag
Using Felt.connect to connect to an existing embedded Felt map

There may be cases where you already have a Felt map embedded in an iframe, and you want to control it using the SDK. This can be useful if your HTML is server-rendered with the Felt map already embedded.

In this case, you can call Felt.connect with the iframe's window as the first argument:

Note that in this case, you don't need to pass the Felt map ID to Felt.connect, because we are connecting to a map that has already been embedded.

Getting started

The Felt SDK allows you to control your Felt maps and build powerful, interactive custom applications. You can control many aspects of the Felt UI and map contents, as well as receive notifications of events happening in the map such as clicks, selections, and more.

This feature is available to customers on the Enterprise planarrow-up-right. All new accounts automatically include a 7-day trial of Enterprise plan features.

See our examples page to explore what you can build with the SDK.

There are two main ways to use the Felt SDK:

  1. Extensions

  2. Embedded Maps

hashtag
Extensions

Write code directly within Felt using our feature. Extensions run directly within the Felt environment, giving you immediate access to all SDK functionality without embedding or connection steps.

When creating an extension, you automatically have access to a object with no setup required. This controller provides all the methods you need to interact with your Felt map, including getViewport, createElement, setLayerStyle, and many more.

hashtag
Embedded Maps

Embed Felt maps in your own applications and control them remotely. This approach requires connecting to a map embed.

hashtag
Installation

Install the SDK using your preferred package manager:

Create an HTML page with a container element:

Embed a Felt map in your container element and use the SDK to control it:

For more information on how to control a map, see .

hashtag
React Integration

If you are building a React application, you can use the to get started quickly.

You can also read our guide on to learn more about how to use the Felt SDK with React.

Authentication

All calls to the Felt API require authorization using a Bearer token in the request header:

Authorization: Bearer <API Token>

These are tokens associated to your account only, and that you have to manually provide to the application you want to use.

Since these tokens grant access to your account, you must store them securely and treat them as a password to your account.

circle-info

API tokens are scoped to a workspace, meaning that you can only work with resources associated to that workspace only.

You can create an API token in the :

Be sure to take note of the token before closing the dialog; you won’t have a second chance to view it.

Once you have your API token, you can authenticate your requests to the Felt API by using it as a bearer token in your Authorization header:

Here's an example showing how to create a new Felt map:

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 . Reach out to .

hashtag
Endpoints

All Felt API endpoints are hosted at the following base URL:

Getting started

The Felt Style Language is a way for advanced users to style data quickly, through simple JSON code. This document is a guide to use as you test data files in Felt. For an exhaustive guide to all supported properties see the Reference Documentation.

hashtag
Style definition blocks

Learn how to define and configure the code blocks that compose the Felt Style Language

hashtag
Types of visualizations

Learn about visualization types, including simple, categorical, numeric (color by & size by), heatmaps and hillshade.

hashtag
Legends

Details on how to customize legends on a per-layer basis.

hashtag
Errors

Definitions for errors raised when validating the Felt Style Language.

Style definition blockschevron-right
Types of visualizationschevron-right
Legendschevron-right
Errorschevron-right

Types of visualizations

Extensionsarrow-up-right
FeltControllerarrow-up-right
Controlling mapsarrow-up-right
Felt SDK React Starter Repoarrow-up-right
Integrating with React
Developers tab of the Workspace Settings pagearrow-up-right
Generate as many API tokens as you need
Give your API token a unique name
Make sure to copy your token to a secure location
<html>
  <body>
    <h1>My Felt app</h1>
    <div id="container"></div>
  </body>
</html>
import { Felt } from "@feltmaps/js-sdk";

const map = await Felt.embed(
  document.querySelector("#container"),
  "FELT_MAP_ID",
);

// Now use the SDK
const layers = await map.getLayers();
const elements = await map.getElements();

// You also have a reference to the iframe itself:
map.iframe.style.width = "50%";
<html>
  <body>
    <h1>My Felt app</h1>
    <iframe id="my-iframe"></iframe>
  </body>
</html>
import { Felt } from "@feltmaps/js-sdk";

const map = await Felt.embed(
  document.querySelector("#my-iframe"),
  "FELT_MAP_ID",
);
<html>
  <body>
    <h1>My Felt app</h1>
    <iframe src="https://felt.com/map/example-map-123" id="my-iframe"></iframe>
  </body>
</html>
import { Felt } from "@feltmaps/js-sdk";

const map = await Felt.connect(
  document.querySelector("#my-iframe").contentWindow
);
// In a Felt extension, the controller is automatically available
const layers = await felt.getLayers();
const elements = await felt.getElements();

// Listen for map events
felt.onSelectionChange((selection) => {
  console.log('Selection changed:', selection);
});
npm install @feltmaps/js-sdk
<html>
  <body>
    <div id="container"></div>
  </body>
</html>
import { Felt } from "@feltmaps/js-sdk";

const map = await Felt.embed(
  document.querySelector("#container"),
  "FELT_MAP_ID",
);

const layers = await map.getLayers();
const elements = await map.getElements();
Authorization: Bearer felt_pat_07T+Jmpk...
# This looks like:
# FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
FELT_API_TOKEN="<YOUR_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"}'
import requests

# This looks like:
# api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
api_token = "<YOUR_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
print(r.json())

hashtag
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 pagearrow-up-right:

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:

hashtag
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:

hashtag
Example: Creating a new map

Creating a new map is as simple as making a POST request to the maps endpoint.

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.

hashtag
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 importsarrow-up-right. In this case, we'll import all the recent earthquakes from the USGS' live GeoJSON feedarrow-up-right:

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.

hashtag
Example: Styling a layer

circle-info

Layer styles are defined in the Felt Style Languagearrow-up-right, a JSON-based specification that allows customizing a layer's style, legend, label and popups.

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:

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.

hashtag
Example: Refreshing a live data layer

circle-exclamation

A layer must have finished uploading successfully before it can be refreshed

Similar to a URL upload, refreshing an existing URL layer is just a matter of making a single POST request:

Now go to your map and see if any new earthquakes have occured!

Enterprise planarrow-up-right
set up a trialarrow-up-right
Authenticationchevron-right

Listening to updates using webhooks

A great way of building data-driven apps using Felt is by triggering a workflow whenever something changes on a map, like someone drawing a polygon around an area of interest or updating the details on a pin.

Instead of polling by listing annotations, comments or data layers on a fixed interval, a better alternative is to set up a webhook where Felt will send a notification any time a map is updated. This allows you to build integrations on top, such as sending a Slack message or performing calculations for the newly-drawn area.

hashtag
Requirements

Two things are needed in order to make use of webhooks:

  1. A Felt map which will serve as the basis for the webhook. Updates will be sent whenever something on this map changes.

  2. A webhook URL where the updates will be sent in the form of POST requests.

hashtag
Generating a new webhook

Workspace admins can set up webhooks in the .

Simply click on Create a new webhook, select a map to listen to changes and paste in a webhook URL where the updates will be sent to.

hashtag
Using your new webhook

In order to use webhooks effectively, a receiving layer must be set up to trigger actions based on the updates sent by the Felt API. Here are some examples of how to set up a webhook using Felt and an external service.

chevron-rightSetting up an example webhook using Pipedreamhashtag

is an easy way to collect webhook requests and even run custom code as a result.

  1. Create a free Pipedream account

  2. On the left-hand sidebar, navigate to

chevron-rightSetting up an example webhook using an AWS Lambdahashtag

Serverless functions like AWS Lambda or Google Cloud Functions are an excellent way of triggering code after a map update by setting them to run after a specific HTTP call.

  1. In the AWS console, navigate to Lambda and click on Create function

General concepts

This guide covers common patterns and concepts used throughout the Felt SDK.

By following these patterns consistently throughout the SDK, we aim to make the API predictable and easy to use while maintaining flexibility for future enhancements.

hashtag
Use of promises

All methods in the Felt SDK are asynchronous and return Promises. This means you'll need to use await or .then() when calling them:

hashtag
Getting entities

The SDK follows a consistent pattern for getting entities. For each entity type, there are usually two methods:

  1. A singular getter for retrieving one entity by ID:

  1. A plural getter that accepts constraints for retrieving multiple entities:

  1. The plural getters allow you to pass no constraints, in which case they'll return all entities of that type:

hashtag
Change listeners

Each entity type has a corresponding change listener method following the pattern on{EntityType}Change:

There are also various other setters and getters in the Felt SDK that follow this convention as much as possible. For example, selection:

And layer filters:

hashtag
Cleanup functions

All change listeners return an unsubscribe function that should be called when you no longer need the listener:

This is particularly important in frameworks like React where you should clean up listeners when components unmount:

hashtag
Handler and options structure

Change listeners always take a single object parameter containing both options and handler. This structure makes it easier to add new options in the future without breaking existing code:

hashtag
Entity nodes

When dealing with mixed collections of entities (like in selection events), each entity is wrapped in an EntityNode object that includes type information:

Refreshing live data layers

It's common to have data update on a regular basis, such as every week or every month. Instead of having to re-upload and style the new data, it can be very convenient to simply refresh a layer using a new data source.

circle-exclamation

A layer must have finished uploading successfully before it can be refreshed

hashtag
Refreshing a layer with a file

circle-info

Refreshing a file is a single function call using the felt-python library.

Just like , refreshing a layer with a new file is a two-step process:

hashtag
1. Request a refresh via the Felt API

Perform a POST request to receive an S3 presigned URL which you can later upload your files to:

hashtag
2. Upload your file(s) to Amazon s3

hashtag
Refreshing a layer with a URL

Similar to , refreshing an existing URL layer is just a matter of making a single POST request:

Uploading files and URLs

circle-info

Felt supports a myriad of formats, both as files and hosted URLs, up to a limit of 5GB. Check out the full list .

hashtag
Uploading a URL

The easiest way of uploading data into a Felt map via the API is to import from a URL. Here's an example importing all the recent earthquakes from :

Like maps, layers also have unique identifiers. Make sure to take note of them for subsequent calls, like styling a layer or removing it.

hashtag
Uploading a file

circle-info

Uploading a file is a single function call using the felt-python library.

Files aren't uploaded to the Felt app — instead, they're uploaded directly to Amazon S3. Therefore, creating a layer from a file on your computer is a two-step process:

hashtag
1. Request an upload via the Felt API

Perform a POST request to receive an S3 presigned URL which you can later upload your files to:

hashtag
2. Upload your file(s) to Amazon s3

hashtag
Monitoring progress

You can check the upload status of a layer by querying it:

Styling layers

hashtag
Understanding layer styles

A layer's style is defined in a JSON-based called the Felt Style Language, or FSL for short. Editors can view the current style of a layer inside a Felt map by clicking on Actions > Edit styles in a layer's overflow menu (three dots).

Here is an example of a simple visualization, expressed in FSL:

hashtag
Fetching a layer's current style

A layer's FSL can be retrieved by performing a simple GET request to a layer's endpoint:

hashtag
Updating an existing layer's style

To update a layer's style, we can send a POST request with the new FSL to the same layer's /update_style endpoint.

hashtag
FSL examples

You can find examples of FSL for different visualization types in of these docs:

  • : same color and size for all features (vector) or pixels (raster).

  • : different color per feature or pixel, based on a categorical attribute

  • : different color or size per feature or pixel, based on a numeric attribute.

Working with selection

The Felt SDK provides functionality for reading the current selection state and selecting features on the map programmatically. This is useful for building interactive experiences that respond to data analysis or user interactions.

hashtag
Selecting Features

Features are individual data points within layers. You can select features programmatically using the method. Only one feature can be selected at a time - selecting a new feature will replace the current selection.

The method accepts options to control the selection behavior:

  • showPopup (boolean, default: true) - Whether to display the feature information popup

  • fitViewport (boolean | { maxZoom: number }, default: true) - Whether to fit the viewport to the feature. Can be true, false

hashtag
Reading selection

You can get the current selection state using . This returns an array of objects, each representing a selected entity. The selection can include various types of entities at the same time, such as annotations and features:

hashtag
Clearing Selection

Remove current selections using :

hashtag
Reacting to selection changes

To stay in sync with selection changes, use the method:

hashtag
Best practices

  1. Clean up listeners: Always store and call the unsubscribe function when you no longer need to listen for selection changes:

  1. Handle empty selection: Remember that the selection array might be empty if nothing is selected:

By following these patterns, you can build robust interactions based on what users select in your Felt map.

Navigating maps and workspaces

hashtag
Workspaces and API tokens

Workspaces are the place where users in the same organization collaborate and share maps. A user may form part of several workspaces but, at the very least, always forms part of one.

API tokens are created per-workspace. If you wish to interact with several workspaces via the Felt API, you must create a different API token for each one.

The attributes block

The attributes block contains information on how attributes will be shown both on the popup and the table. Each attribute definition can contain the following properties:

Field name
Description

The filters block

The filters block contains information on how the layer is being filtered before displaying. In order for a feature to be shown on the map it must evaluate the filter expression to true.

Filters are written using a JSON infix notation that looks like one of [identifier, operator, operand], true or false .

  • Valid identifiers are either a feature property or a nested expression.

# Your API token should look like this:
# FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
FELT_API_TOKEN="<YOUR_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"}'
import requests

# This looks like:
# api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
api_token = "<YOUR_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())
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"] = "<YOUR_API_TOKEN>"

response = create_map(
    title="My newly created map",
    lat=40,
    lon=-3,
    public_access="private",
)
map_id = response["id"]
# Store the map ID from the previous call:
# MAP_ID="CjU1CMJPTAGofjOK3ICf1D"
MAP_ID="<YOUR_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"}'
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())
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"]
# Store the layer ID from the previous call:
# LAYER_ID="CjU1CMJPTAGofjOK3ICf1D"
LAYER_ID="<YOUR_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"}}'
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())
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,
)
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"
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())
from felt_python import refresh_url_layer

refresh_url_layer(map_id, layer_id)
https://felt.com/api/v2
pip install felt-python
{
  "config": {"labelAttribute": ["type"]},
  "legend": {},
  "paint": {
    "color": "blue",
    "opacity": 0.9,
    "size": 30,
    "strokeColor": "auto",
    "strokeWidth": 1
  },
  "type": "simple",
  "version": "2.1"
}
await felt.selectFeature({
  id: "feature-123",
  layerId: "buildings-layer"
});
await felt.selectFeature({
  id: "feature-123",
  layerId: "buildings-layer",
  showPopup: false,           // Whether to show the feature popup (default: true)
  fitViewport: { maxZoom: 15 } // Fit viewport to feature with zoom limit
});
regular file uploads
a URL upload
import requests

# Your API token should look like this:
# api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
api_token = "<YOUR_API_TOKEN>"
map_id = "<YOUR_MAP_ID>"
layer_id = "<YOUR_LAYER_ID>"

r = requests.post(
  f"http://felt.com/api/v2/maps/{map_id}/layers/{layer_id}/refresh",
  headers={"Authorization": f"Bearer {api_token}"}
)
assert r.ok
presigned_upload = r.json()
import os

from felt_python import refresh_file_layer

# Setting your API token as an env variable can save
# you from repeating it in every function call
os.environ["FELT_API_TOKEN"] = "<YOUR_API_TOKEN>"

map_id = "<YOUR_MAP_ID>"
layer_id = "<YOUR_LAYER_ID>"
new_file_name = "<PATH_TO_NEW_FILE>"

refresh_file_layer(
    map_id=map_id,
    layer_id=layer_id,
    file_name=new_file_name
)
Heatmaps: a density-based visualization style, for vector point layers.
  • Hillshade: a special kind of visualization for raster elevation layers.

  • the Felt Style Language section
    Simple visualizations
    Categorical visualizations
    Numeric visualizations

    displayName

    Optional. How this attribute will be shown in different parts of the Felt UI.

    format

    Optional. A numbroarrow-up-right object that encodes how numeric fields should be shown.

    Example of an attribute blocks block
    "attributes": {
      "faa": {
        "displayName": "FAA Code",
        "format": {
          "mantissa": 0,
          "thousandSeparated": true
        }
      },
      "wikipedia": {"displayName": "Wikipedia"},
    }
    Sources
    , then click on
    New source
    in the top-right corner.
  • Select HTTP / Webhook, then New Requests (Payload Only), and give your newly-created source a name.

  • Copy the endpoint URL. It will look like https://XXX.m.pipedream.net

  • In Felt, navigate to the Webhooks tab of your workspacearrow-up-right and click on Create new webhook

  • Paste the endpoint URL from Pipedream into the Webhook URL text field, select your map in the dropdown and click Create.

  • To test your webhook:

    1. Navigate to the Felt map that's linked to the webhook

    2. Make any change: add a pin, draw with the marker, change the color of a polygon, update sharing permissions...

    3. Back in Pipedream, verify that new events appear for the new source. The payload should look like this:

    1. You may also add configure a script to run using the above input.

    Choose a name and runtime and, under Advanced Settings, make sure to check Enable function URL

  • Set Auth type to NONE and click on Create function

  • In the next screen, copy the Function URL. It should look like https://{LAMBDA_ID}.lambda-url.{REGION}.on.aws

  • Continue configuring your Lambda function as usual by editing the code that will run on map updates

  • In Felt:

    1. Navigate to the Webhooks tab of your workspacearrow-up-right and click on Create new webhook

    2. Paste the function URL from AWS into the Webhook URL text field, select your map in the dropdown and click Create.

    Developers tab of the Workspace Settings pagearrow-up-right
    Pipedream's RequestBin arrow-up-right

    Valid operators are:

    • "lt" – Less than

    • "gt" – Greater than

    • "le" – Less than or equal to

    • "ge" – Greater than or equal to

    • "eq" – Equal to

    • "ne" – Not equal to

    • "and" – And, cast to boolean

    • "or" – Or, cast to boolean

    • "cn" – Contains the operand, cast to string

    • "nc" – Does not contain the operand, cast to string

    • "in" – Contained in the operand list

    • "ni" – Not contained in the operand list

    • "is" – Used to match against null values

    • "isnt" – Used to match against null values

  • Operands are:

    • A numerical value, a string value, a boolean value

    • An array of numerical, string, or boolean values, a shorthand expanded to these patterns:

      • Input 1: [id, "in", [element1, …, elementN]

      • Expansion 1: id is equal (”eq”) to one of more of the elements

      • Input 2: [id, "ni", [element1, …, elementN]

      • Expansion 2: id is not equal (”ne”) to any of the elements

      • Not defined for operators other than "in" and "ni"

    • A nested expression

  • In cases of type mismatch cast the identifier value to the operand’s type

    • Type casting applies element-wise to lists with "in" and "ni" operators

  • const layer = await felt.getLayer("layer-1");
    felt.getElements().then(elements => {
      console.log(elements);
    });
    const layer = await felt.getLayer("layer-1");
    const element = await felt.getElement("element-1");
    const layers = await felt.getLayers({ ids: ["layer-1", "layer-2"] });
    const legendItems = await felt.getLegendItems({ layerIds: ["layer-1", "layer-2"] });
    const layers = await felt.getLayers();
    const legendItems = await felt.getLegendItems();
    const unsubscribe = felt.onLayerChange({
      options: { id: "layer-1" },
      handler: ({ layer }) => {
        console.log("Layer updated:", layer);
      }
    });
    const selection = await felt.getSelection();
    const unsubscribe = felt.onSelectionChange({
      handler: ({ selection }) => {
        console.log("Selection updated:", selection);
      }
    });
    const filters = await felt.getLayerFilters("layer-1");
    await felt.setLayerFilters({
      layerId: "layer-1",
      filters: ["name", "eq", "Jane"],
    });
    const unsubscribe = felt.onLayerFiltersChange({
      options: {layerId: "layer-1"},
      handler: (filters) => console.log(filters)
    })
    const unsubscribe = felt.onLayerChange({
      options: { id: "layer-1" },
      handler: ({ layer }) => {
        console.log("Layer changed:", layer);
      }
    });
    
    // Later, when you're done listening:
    unsubscribe();
    useEffect(() => {
      const unsubscribe = felt.onViewportMove({
        handler: (viewport) => {
          console.log("Viewport changed:", viewport);
        }
      });
      
      // Clean up when the component unmounts
      return () => unsubscribe();
    }, []);
    // Current API
    felt.onElementChange({
      options: { id: "element-1" },
      handler: ({ element }) => { /* ... */ }
    });
    
    // If we need to add new options later, no breaking changes:
    felt.onElementChange({
      options: { 
        id: "element-1",
        newOption: "value" // Can add new options without breaking existing code
      },
      handler: ({ element }) => { /* ... */ }
    });
    felt.onSelectionChange({
      handler: ({ selection }) => {
        selection.forEach(node => {
          console.log(node.type);    // e.g., "element", "layer", "feature", ...
          console.log(node.entity);  // The actual entity object
          
          if (node.type === "element") {
            // TypeScript knows this is an Element
            console.log(node.entity.attributes);
          }
        });
      }
    });
    # This code is a continuation of the previous Python code block
    # and assumes you already have a "presigned_upload" variable
    url = presigned_upload["url"]
    presigned_attributes = presigned_upload["presigned_attributes"]
    # A 204 response indicates that the upload was successful
    with open(YOUR_FILE_WITH_EXTENSION, "rb") as file_obj:
        output = requests.post(
            url,
            # Order is important, file should come at the end
            files={**presigned_attributes, "file": file_obj},
        )
    # Nothing! Uploading a file is a single step with the felt-python library
    # Your API token and map ID should look like this:
    # FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    FELT_API_TOKEN="<YOUR_API_TOKEN>"
    MAP_ID="<YOUR_MAP_ID>"
    LAYER_ID="<YOUR_LAYER_ID>"
    
    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"
    import requests
    
    # Your API token and map ID should look like this:
    # api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    api_token = "<YOUR_API_TOKEN>"
    map_id = "<YOUR_MAP_ID>"
    layer_id = "<YOUR_LAYER_ID>"
    
    r = requests.post(
      f"http://felt.com/api/v2/maps/{map_id}/layers/{layer_id}/refresh",
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    print(r.json())
    from felt_python import refresh_url_layer
    
    refresh_url_layer(map_id, layer_id)
    # Your API token should look like this:
    # FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    FELT_API_TOKEN="<YOUR_API_TOKEN>"
    MAP_ID="<YOUR_MAP_ID>"
    LAYER_ID="<YOUR_LAYER_ID>"
    
    curl -L \
      -H "Authorization: Bearer ${FELT_API_TOKEN}" \
      "https://felt.com/api/v2/maps/${MAP_ID}/layers/${LAYER_ID}"
    import requests
    
    # Your API token should look like this:
    # api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    api_token = "<YOUR_API_TOKEN>"
    map_id = "<YOUR_MAP_ID>"
    layer_id = "<YOUR_LAYER_ID>"
    
    r = requests.get(
      f"http://felt.com/api/v2/maps/{map_id}/layers/{layer_id}",
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    print(r.json())
    import os
    
    from felt_python import get_layer_details
    
    # Setting your API token as an env variable can save
    # you from repeating it in every function call
    os.environ["FELT_API_TOKEN"] = "<YOUR_API_TOKEN>"
    
    map_id = "<YOUR_MAP_ID>"
    layer_id = "<YOUR_LAYER_ID>"
    
    layer_details = get_layer_details(map_id, 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"}}'
    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())
    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,
    )
    {
      "body": {
        "attributes": {
          "type": "map:update",
          "updated_at": "2024-04-29T12:16:46",
          "map_id": "Jzjr8gMKSrCOxZ1OSMT49CB"
        }
      }
    }
    Example of a filter block that filters out features with a value less than 50000 on the “acres” property
    "filters": ["acres", "lt", 50000]
    Example of a more complex filter block
    "filters": [["acres", "ge", 50000], "and", ["acres", "le", 70000]]
    , or an object with
    maxZoom
    to limit the zoom level used.
    hashtag
    Working with maps

    hashtag
    Creating a new map

    Creating a new map is as simple as making a POST request to the maps endpoint.

    # Your API token should look like this:
    # FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    FELT_API_TOKEN="<YOUR_API_TOKEN>
    
    import requests
    
    # Your API token should look like this:
    # api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    

    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.

    hashtag
    Getting a map's details

    Performing a GET request to a map URL will give you useful information about that map, including title, URL, layers, thumbnail URL, creation and visited timestamps.

    hashtag
    Deleting a map

    To remove a map from your workspace, simply perform a DELETE request to the map's URL:

    hashtag
    Moving a map

    To move a map to a different folder or project, send a POST request to the map's move URL:

    the USGS' live GeoJSON feedarrow-up-right
    import requests
    
    # Your API token should look like this:
    # api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    api_token = "<YOUR_API_TOKEN>"
    map_id = "<YOUR_MAP_ID>"
    
    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"]
    # Your API token and map ID should look like this:
    # FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    # MAP_ID="CjU1CMJPTAGofjOK3ICf1D"
    FELT_API_TOKEN="<YOUR_API_TOKEN>"
    MAP_ID="<YOUR_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"}'

    Working with annotations

    circle-exclamation

    hashtag
    Note: Annotations were previously referred to as Elements.

    References have been updated in the app and documentation, while naming in the REST API and JS SDK remains unchanged.

    Annotations live at the top layer of a map, and are created directly inside the Felt app.

    circle-info

    Combining annotations with is a great way to create interactive data apps in Felt.

    hashtag
    Listing all annotations on a map

    Annotations live at the top layer of a map, and are created directly inside the Felt app.

    Annotations are returned as a .

    hashtag
    Listing all annotation groups

    Returns a list of GeoJSON Feature Collections, one for each annotation group.

    hashtag
    Create or update new annotations

    Each annotation is represented by a feature in the POSTed GeoJSON Feature Collection.

    For each feature, including an existing annotation ID (felt:id) will result in the annotation being updated on the map. If no annotation ID is provided (or a non-existent one) , a new annotation will be created.

    hashtag
    Delete an annotation

    Annotations can be deleted by referencing them by ID

    Simple visualizations

    Simple visualizations are those that show each feature in a vector dataset using the same style or the image as it is in raster ones.

    Simple visualizations must define "type": "simple" and a single value for each supported style and label properties.

    hashtag
    Vector example

    The Airports layer in Felt is an example of a simple visualization using a vector dataset

    and is defined by the following style:

    hashtag
    Raster example

    This is an example of a simple visualization using a raster dataset

    and is defined by the following style:

    Reading entities

    The Felt SDK provides several methods for reading data from your map's entities (layers, elements, etc.) and staying in sync with their changes. This guide will show you how to read entity data and react to changes.

    hashtag
    Getting entities

    The Felt SDK provides both singular and plural versions of getter methods for various entity types. This allows you to retrieve either a single entity or multiple entities of the same type.

    For example, for layers:

    hashtag
    Using constraints

    All of the methods that return multiple entities accept constraint parameters to filter the results:

    hashtag
    Reacting to changes

    To stay in sync with entities, use the appropriate on[EntityType]Change method. For example, to monitor layer changes:

    hashtag
    Best practices

    1. Cleanup: Always store and call the unsubscribe functions when you're done listening for changes so that the listener doesn't continue to run in the background.

    2. Error handling: When getting entities, remember that the methods may return null if the entity doesn't exist:

    1. Batch operations: When you need multiple entities, use the bulk methods (getLayers, getElements, etc.) with constraints rather than making multiple individual calls:

    This approach to reading and monitoring entities gives you full control over your map's data and allows you to build interactive applications that stay in sync with the map's state.

    The popup block

    The popup block contains information on how the popup is displayed and which attributes to show.

    These are the fields that each popup block can contain:

    Field name
    Description

    titleAttribute

    Optional. The attribute that will be used to title the popup if available

    imageAttribute

    The legend block

    The legend block contains information on how the legend will be displayed for this visualization.

    Take a look at the legends section to see how it works.

    These are the fields that each legend block can contain:

    Field name
    Description

    displayName

    Optional. In categorical visualizations, a dictionary that maps from each category to what will be displayed on the legend. In or visualizations, a dictionary that maps from the index of each class to what will be displayed on the legend.

    Example of a categorical legend
    "legend": {
      "displayName": {
        "category-1": "Category 1",
        "category-2": "Category 2"
      }
    }
    Example of a numerical legend
    "legend": {
      "displayName": {
        "0": "-0.5", 
        "1": "0.5"
      }
    }

    Hillshade

    Hillshades are used to visualize the valleys and ridges encoded in elevation raster data.

    Hillshade visualizations are defined using “type”: “hillshade” and, support the following properties:

    Field name
    Description

    color

    An array of colors that will be used in the hillshade. From less elevation to more.

    The following map is an example of a raster layer using a hillshade visualization

    with the following style

    Felt also supports adding color to hillshades by defining a color property in the style

    which is defined by the following style

    Zoom-based Styling

    circle-info

    Zoom-based styling is useful to change how features and labels are shown at different zoom levels.

    Most of the properties used on the style and label blocks can be defined using interpolators to enable zoom-based styling. Take a look at the full list of properties that can be interpolated in the full specification.

    We support multiple types of interpolators: Step functions, linear, exponential and cubic bezier to enable your map looking like you want at each zoom level. See the Interpolators page.

    An example of a layer changing feature colors depending on the zoom level can be found below

    On zoom levels lower than 14, features of this layer will be rendered in red color. On zoom levels higher than 20, features of this layer will be rendered in blue color.

    In zooms between 14 and 20, color will be linearly interpolated between red and blue.

    Errors

    hashtag
    Unexpected value or type

    Problem: One of the values set in the style has an unsupported value or an invalid type.

    Solution: Change the value to be valid.

    Error messages:

    • Attribute 'displayName' on a legend item of type simple must be a string.

    • Attribute attribute_name is not a number.

    • Attribute attribute_name is not a string.

    • Attribute 'lineCap’ is not a supported value. Supported values are butt, round, square.

    • Attribute 'lineJoin’ is not a supported value. Supported values are bevel, round, miter.

    • Attribute ‘dashArray’ has to be a two-numbers array.

    • Attribute 'offset' must be either an array of numbers or a number.

    • Attribute 'placement' contains a not supported value. Supported values are N, NE, E, SE, S, SW, W, NW, Center.

    • Attribute 'placement' contains a not supported value. Supported values are Above, Center, Below.

    • All values in 'labelAttribute' must be a string.

    • Visualization 'type' definition must be one of simple, categorical.

    • Attribute 'showOther' must be one of above, below.

    hashtag
    Categorical visualization not working

    Problem: The style defines a categorical visualization, but the maps are not showing the layer

    Error messages:

    • Categories required. A categories array must be defined in the config block when defining a categorical visualization. Read more about categorical visualizations .

    • Not enough or too many attribute_name values. When defining a categorical visualization, all style and label properties must be an array with either a single value that will apply to all categories or an array with as many values as categories defined in the config block. Read more about categorical visualizations .

    Heatmaps

    Heatmaps are used to visualize the density of points on a map.

    Heatmaps visualizations are defined using “type”: “heatmap” and, allow the following properties to be set:

    Field name
    Description

    color

    An array of colors that will be used in the heatmap. From less density to more.

    This is an example of a heatmap visualization

    defined with the following visualization

    Heatmaps do not support labels.

    Layer filters

    The Felt SDK allows you to filter which features are visible in a layer using expressions that evaluate against feature properties. Filters can come from different sources and are combined to determine what's visible.

    By understanding how filters work and combine, you can create dynamic views of your data that respond to user interactions and application state.

    hashtag
    Understanding filter sources

    Layer filters can come from multiple sources, which are combined to create the final filter:

    Integrating with React

    To work with Felt embeds in React, we have a starter template that you can use as a starting point.

    This is available on GitHub in the repository.

    In that repo, you will find a feltUtils.ts file that demonstrates some ways to make using the Felt SDK in React easier.

    hashtag
    Embedding with useFeltEmbed

    H3

    H3 visualization is a way to aggregate point data into a grid of H3 cells.

    H3 visualizations are defined using “type”: “h3” . They generally share the same properties and behaviors as . Properties of specific relevance to H3 are:

    Field name
    Description
    const selection = await felt.getSelection();
    
    console.log(`${selection.length} items selected`);
    
    selection.forEach(node => {
      switch(node.type) {
        case 'feature':
          console.log('Selected feature:', node.entity.id, 'from layer:', node.entity.layerId);
          break;
        case 'element':
          console.log('Selected element:', node.entity.name || node.entity.type);
          break;
      }
    });
    // Clear all selections
    await felt.clearSelection();
    
    // Clear specific types of selections
    await felt.clearSelection({ 
      features: true,   // Clear feature selections
      elements: false   // Keep element selections
    });
    const unsubscribe = felt.onSelectionChange({
      handler: ({ selection }) => {
        // selection is an array of EntityNode objects
        console.log("Selected entities:", selection);
        
        // Check what's selected
        selection.forEach(node => {
          console.log("Entity type:", node.type);
          console.log("Entity ID:", node.entity.id);
        });
      }
    });
    
    // Don't forget to clean up when you're done
    unsubscribe();
    const unsubscribe = felt.onSelectionChange({
      handler: ({ selection }) => {
        // Handle selection...
      }
    });
    
    // Later, when you're done:
    unsubscribe();
    const unsubscribe = felt.onSelectionChange({
      handler: ({ selection }) => {
        if (selection.length === 0) {
          console.log("Nothing is selected");
          return;
        }
        // Handle selection...
      }
    });
    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"] = "<YOUR_API_TOKEN>"
    
    response = create_map(
        title="My newly created map",
        lat=40,
        lon=-3,
        public_access="private",
    )
    map_id = response["id"]
    curl -L \
      -H "Authorization: Bearer ${FELT_API_TOKEN}" \
      "https://felt.com/api/v2/maps/${MAP_ID}"
    r = requests.get(
      f"http://felt.com/api/v2/maps/{map_id}",
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    print(r.json())
    from felt_python import get_map
    
    get_map(map_id)
    curl -L \
      -X DELETE \
      -H "Authorization: Bearer ${FELT_API_TOKEN}" \
      "https://felt.com/api/v2/maps/${MAP_ID}"
    r = requests.delete(
      f"http://felt.com/api/v2/maps/{map_id}",
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    from felt_python import delete_map
    
    delete_map(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}/move" \
      -d '{"project_id": "${PROJECT_ID}"}'
    r = requests.post(
      f"http://felt.com/api/v2/maps/{map_id}/move",
      json={"project_id": project_id},
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    print(r.json())
    from felt_python import move_map
    
    move_map(map_id, project_id)
    import os
    
    from felt_python import upload_url
    
    # Setting your API token as an env variable can save
    # you from repeating it in every function call
    os.environ["FELT_API_TOKEN"] = "<YOUR_API_TOKEN>"
    
    map_id = "<YOUR_MAP_ID>"
    
    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"]
    r = requests.post(
        f"https://felt.com/api/v2/maps/{map_id}/upload",
        headers={
            "Authorization": f"Bearer {api_token}",
            "Content-Type": "application/json",
        },
        json={"name": "My new layer"},
    )
    assert r.ok
    layer_id = r.json()["layer_id"]
    
    presigned_upload = r.json()
    from felt_python import upload_file
    
    file_name = "<YOUR_FILE_WITH_EXTENSION>" # Example: regions.geojson
    
    upload_file(
      map_id=map_id,
      file_name="YOUR_FILE_WITH_EXTENSION",
      layer_name="My new layer",
    )
    # This code is a continuation of the previous Python code block
    # and assumes you already have a "presigned_upload" variable
    
    file_name = "<YOUR_FILE_WITH_EXTENSION>" # Example: regions.geojson
    
    url = presigned_upload["url"]
    presigned_attributes = presigned_upload["presigned_attributes"]
    # A 204 response indicates that the upload was successful
    with open(file_name, "rb") as file_obj:
        output = requests.post(
            url,
            # Order is important, file should come at the end
            files={**presigned_attributes, "file": file_obj},
        )
    # Nothing! Uploading a file is a single step with the felt-python library
    curl -L \
      "https://felt.com/api/v2/maps/${MAP_ID}/layers/{LAYER_ID}" \
      -H "Authorization: Bearer ${YOUR_API_TOKEN}"
    r = requests.get(
        f"https://felt.com/api/v2/maps/{map_id}/layers/{layer_id}",
        headers={"Authorization": f"Bearer {api_token}"},
    )
    assert r.ok
    print(r.json()["progress"])
    from felt_python import get_layer_details
    
    get_layer_details(map_id, layer_id)["progress"]
    // Get a single layer
    const layer = await felt.getLayer("layer-1");
    
    // Get all layers
    const layers = await felt.getLayers();
    "
    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"}'
    api_token = "<YOUR_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())
    herearrow-up-right
    here
    numeric
    heatmap
    in our Help Center
    webhooks
    GeoJSON Feature Collectionarrow-up-right
    # Your API token and map ID should look like this:
    # FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    # MAP_ID="CjU1CMJPTAGofjOK3ICf1D"
    FELT_API_TOKEN="<YOUR_API_TOKEN>"
    MAP_ID="<YOUR_MAP_ID>"
    
    curl -L \
      -H "Authorization: Bearer ${FELT_API_TOKEN}" \
      "https://felt.com/api/v2/maps/${MAP_ID}/elements"
    import requests
    
    # Your API token and map ID should look like this:
    # api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
    api_token = "<YOUR_API_TOKEN>"
    map_id = "<YOUR_MAP_ID>"
    
    r = requests.get(
      f"http://felt.com/api/v2/maps/{map_id}/elements",
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    print(r.json())

    Optional. The attribute that will be used to populate the popup image if available

    popupLayout

    Optional. One of either “table” or “list”. The way the popup will show its contents. Defaults to "table"

    keyAttributes

    Optional. A list of attributes to show in the popup following the order defined here. If it’s not defined, only attributes with a value will show in the popup. If it’s defined, all attributes here will show even if the selected feature doesn’t include them.

    source

    The light angle. 0 is North, 90 East, …

    intensity

    Controls the intensity of a hillshade.

    Features at zoom level 14
    Features at zoom level 17
    Features at zoom level 20

    size

    Controls the size of each point.

    intensity

    Controls the intensity of a heightmap.

    Style filters: Set by the map creator in the Felt UI

  • Component filters: Set through interactive legend components

  • Ephemeral filters: Set temporarily through the SDK

  • You can inspect these different filter sources using getLayerFilters:

    hashtag
    Setting filters

    Use setLayerFilters to apply ephemeral filters to a layer:

    hashtag
    Filter operators

    The following operators are available:

    • Comparison: lt (less than), gt (greater than), le (less than or equal), ge (greater than or equal), eq (equal), ne (not equal)

    • Text: cn (contains), nc (does not contain)

    • Boolean: and, or

    • Lookup: in (contained in list), ni (not contained in list)

    See herearrow-up-right for more details on filter operators.

    hashtag
    Compound filters

    You can combine multiple conditions using boolean operators:

    hashtag
    Practical example: Filtering by selected feature

    Here's a common use case where we filter a layer to show only features that match a property of a selected feature:

    hashtag
    Best practices

    1. Clear filters: Set filters to null to remove them entirely:

    1. Check existing filters: Remember that your ephemeral filters combine with existing style and component filters:

    1. Type safety: Use TypeScript to ensure your filter expressions are valid:

    chevron-rightuseFeltEmbed implementationhashtag

    hashtag
    Getting live data

    A common use case for building apps on Felt is to be notified when entities are updated. The main example of this is when you want to change the visibility of say a layer, and have your own UI reflect that change.

    Rather than keeping track of the visibility of entities yourself, you can use the Felt SDK to listen for changes to the visibility of entities.

    Here is an example of how you might do this for layers assuming you already have a reference to a Layer object, e.g. from calling map.getLayers():

    felt/js-sdk-starter-reactarrow-up-right
    import os
    
    from felt_python import list_elements
    
    # Setting your API token as an env variable can save
    # you from repeating it in every function call
    os.environ["FELT_API_TOKEN"] = "<YOUR_API_TOKEN>"
    
    map_id = "<YOUR_MAP_ID>"
    
    list_elements(map_id)
    curl -L \
      -H "Authorization: Bearer ${FELT_API_TOKEN}" \
      "https://felt.com/api/v2/maps/${MAP_ID}/element_groups"
    r = requests.get(
      f"http://felt.com/api/v2/maps/{map_id}/elements",
      headers={"Authorization": f"Bearer {api_token}"}
    )
    assert r.ok
    print(r.json())
    from felt_python import list_element_groups
    
    list_element_groups(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}/elements" \
      -d '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[[[15.478752514432728,15.576176978045694],[15.478752514432728,4.005934587045303],[29.892174099255755,4.005934587045303],[29.892174099255755,15.576176978045694],[15.478752514432728,15.576176978045694]]],"type":"Polygon"}}]}'
    new_elements = {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {},
          "geometry": {
            "coordinates": [
              [
                [
                  15.478752514432728,
                  15.576176978045694
                ],
                [
                  15.478752514432728,
                  4.005934587045303
                ],
                [
                  29.892174099255755,
                  4.005934587045303
                ],
                [
                  29.892174099255755,
                  15.576176978045694
                ],
                [
                  15.478752514432728,
                  15.576176978045694
                ]
              ]
            ],
            "type": "Polygon"
          }
        }
      ]
    }
    
    r = requests.post(
      f"http://felt.com/api/v2/maps/{map_id}/elements",
      headers={"Authorization": f"Bearer {api_token}"},
      json=new_elements
    )
    assert r.ok
    print(r.json())
    from felt_python import upsert_elements
    
    new_elements = {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {},
          "geometry": {
            "coordinates": [
              [
                [
                  15.478752514432728,
                  15.576176978045694
                ],
                [
                  15.478752514432728,
                  4.005934587045303
                ],
                [
                  29.892174099255755,
                  4.005934587045303
                ],
                [
                  29.892174099255755,
                  15.576176978045694
                ],
                [
                  15.478752514432728,
                  15.576176978045694
                ]
              ]
            ],
            "type": "Polygon"
          }
        }
      ]
    }
    
    upsert_elements(map_id, new_elements)
    curl -L \
      -X DELETE \
      -H "Authorization: Bearer ${FELT_API_TOKEN}" \
      "https://felt.com/api/v2/maps/${MAP_ID}/elements/{ELEMENT_ID}"
    element_id = "<YOUR_ELEMENT_ID>"
    
    r = requests.delete(
      f"http://felt.com/api/v2/maps/{map_id}/elements/{element_id}",
      headers={"Authorization": f"Bearer {api_token}"},
    )
    assert r.ok
    from felt_python import delete_element
    
    element_id = "<YOUR_ELEMENT_ID>"
    
    delete_element(map_id, element_id)
    {
      "attributes": {
        "ele": {"displayName": "Elevation (meters)"},
        "faa": {"displayName": "FAA Code"},
        "iata": {"displayName": "IATA Code"},
        "icao": {"displayName": "ICAO Code"},
        "name": {"displayName": "Name"},
        "name_en": {"displayName": "Name (EN)"},
        "wikipedia": {"displayName": "Wikipedia entry"}
      },
      "config": {"labelAttribute": ["name_en", "name"]},
      "filters": [["name", "isnt", null], "and", ["name", "ne", ""]],
      "label": {
        "color": "hsl(40,30%,40%)",
        "fontSize": {"linear": [[12, 12], [20, 20]]},
        "fontStyle": "Normal",
        "fontWeight": 400,
        "haloColor": "hsl(40,20%,85%)",
        "haloWidth": 1.5,
        "justify": "auto",
        "letterSpacing": 0.1,
        "lineHeight": 1.2,
        "maxLineChars": 10,
        "maxZoom": 23,
        "minZoom": 10,
        "offset": [8, 0],
        "padding": 10,
        "placement": ["E", "W"],
        "visible": true
      },
      "legend": {},
      "paint": {
        "color": "hsl(40,30%,80%)",
        "highlightColor": "#EA3891",
        "highlightStrokeColor": "#EA3891",
        "highlightStrokeWidth": {"linear": [[3, 0], [20, 2]]},
        "isSandwiched": false,
        "opacity": 1,
        "size": {"linear": [[3, 1], [20, 6]]},
        "strokeColor": "hsl(40,20%,55%)",
        "strokeWidth": {"linear": [[3, 0.5], [20, 2]]}
      },
      "version": "2.3"
    }
    {
      "version": "2.3",
      "type": "simple",
      "config": {},
      "paint": {"isSandwiched": false, "opacity": 0.93}
    }
    // Get elements with specific IDs
    const elements = await felt.getElements({
      ids: ["element-1", "element-2"]
    });
    
    // Get legend items belonging to a layer
    const legendItems = await felt.getLegendItems({
      layerIds: ["layer-1"],
    });
    felt.onLayerChange({
      options: {id: "layer-1"},
      handler: ({layer}) => {
        console.log(layer.visible);
      }
    });
    const layer = await felt.getLayer("layer-1");
    if (layer) {
      // Layer exists, safe to use
      console.log(layer.visible);
    } else {
      // Layer not found
      console.log("Layer not found");
    }
    // Better approach
    const layers = await felt.getLayers({ ids: ["layer-1", "layer-2"] });
    
    // Less efficient approach
    const layer1 = await felt.getLayer("layer-1");
    const layer2 = await felt.getLayer("layer-2");
    Example of a popup block
    "popup": {
      "keyAttributes": [
        "osm_id",
        "barriers",
        "highway",
        "ref",
        "is_in",
        "place",
        "man_made",
        "other_tags"
      ],
      "titleAttribute": "barriers",
      "popupLayout": "list"
    }
    {
      "version": "2.3",
      "type": "hillshade",
      "config": {"band": 1},
      "legend": {},
      "paint": {"isSandwiched": false}
    }
    {
      "config": {"band": 1, "steps": [-154.46435546875, 7987.457987843631]},
      "legend": {},
      "type": "hillshade",
      "version": "2.3",
      "paint": {
        "isSandwiched": false,
        "color": "@feltHeat",
        "source": 315,
        "intensity": 0.76
      }
    }
    "paint": {
      "color": {"linear": [[14, "red"], [20, "blue"]]},
      ...
    }
    {
      "version": "2.3",
      "type": "heatmap",
      "config": {},
      "legend": {"displayName": {"0": "Low", "1": "High"}},
      "paint": {"color": "@purpYlPink", "size": 10, "intensity": 0.2}
    }
    const filters = await felt.getLayerFilters("layer-1");
    console.log(filters.style);      // Base filters from the layer style
    console.log(filters.components); // Filters from legend components
    console.log(filters.ephemeral);  // Filters set through the SDK
    console.log(filters.combined);   // The final result of combining all filters
    felt.setLayerFilters({
      layerId: "layer-1",
      filters: ["POPULATION", "gt", 1000000]
    });
    felt.setLayerFilters({
      layerId: "layer-1",
      filters: [
        ["POPULATION", "gt", 1000000],
        "and",
        ["COUNTRY", "eq", "USA"]
      ]
    });
    // Listen for selection changes
    felt.onSelectionChange({
      handler: async ({ selection }) => {
        // Find the first selected feature
        const selectedFeature = selection.find(node => node.type === "feature");
        
        if (selectedFeature) {
          // Get the state code from the selected feature
          const stateCode = selectedFeature.entity.properties.STATE_CODE;
          
          // Filter the counties layer to show only counties in the selected state
          felt.setLayerFilters({
            layerId: "counties-layer",
            filters: ["STATE_CODE", "eq", stateCode]
          });
        } else {
          // Clear the filter when nothing is selected
          felt.setLayerFilters({
            layerId: "counties-layer",
            filters: null
          });
        }
      }
    });
    felt.setLayerFilters({
      layerId: "layer-1",
      filters: null
    });
    const filters = await felt.getLayerFilters("layer-1");
    
    // Check if there are any style filters before adding ephemeral ones
    if (filters.style) {
      console.log("This layer already has style filters");
    }
    import type { Filters } from "@feltmaps/sdk";
    
    const filter: Filters = ["POPULATION", "gt", 1000000];
    felt.setLayerFilters({
      layerId: "layer-1",
      filters: filter
    });
    import {
      Felt,
      FeltController,
      FeltEmbedOptions,
      Layer,
      LayerGroup,
    } from "@feltmaps/js-sdk";
    import React from "react";
    
    export function useFeltEmbed(mapId: string, embedOptions: FeltEmbedOptions) {
      const [felt, setFelt] = React.useState<FeltController | null>(null);
      const hasLoadedRef = React.useRef(false);
      const mapRef = React.useRef<HTMLDivElement>(null);
    
      React.useEffect(() => {
        async function loadFelt() {
          if (hasLoadedRef.current) return;
          if (!mapRef.current) return;
    
          hasLoadedRef.current = true;
          const felt = await Felt.embed(mapRef.current, mapId, embedOptions);
          setFelt(felt);
        }
    
        loadFelt();
      }, []);
    
      return {
        felt,
        mapRef,
      };
    }
    function MyComponent() {
      // get the felt controller (or null if it's not loaded yet) and a ref to the map container
      // into which we can embed the map
      const { felt, mapRef } = useFeltEmbed("wPV9BqMuYQxmUraVWy9C89BNA", {
        uiControls: {
          cooperativeGestures: false,
          fullScreenButton: false,
          showLegend: false,
        },
      });
    
      return (
        <div>
          {/* the map container */}
          <div ref={mapRef} />
    
          {/* a component that uses the Felt controller */}
          <MyFeltApp felt={felt} />
        </div>
      );
    }
    export function useLiveLayer(felt: FeltController, initialLayer: Layer) {
      // start with the layer we were given
      const [currentLayer, setLayer] = React.useState<Layer | null>(initialLayer);
    
      // listen for changes to the layer and update our state accordingly
      React.useEffect(() => {
        return felt.onLayerChange({
          options: { id: initialLayer.id },
          handler: ({ layer }) => setLayer(layer),
        });
      }, [initialLayer.id]);
    
      // return the live layer
      return currentLayer;
    }

    fixed (default), low, medium, or high. Determines if the resolution of H3 cell is fixed or automatically determined based on the current zoom of the map.

    baseBinLevel

    Required. If binMode is fixed, this is the that the map will use. H3 cells vary from resolution 1 (largest) to resolution 15 (smallest). If binMode is auto, this is the resolution that will be used for calculating class breaks. You will get best results choosing a resolution that matches the fixed resolution you would choose to fit the most commonly-viewed zoom for your map.

    numericAttribute

    The numeric column to aggregate. Required unless aggregation is count , in which case the column choice is irrelevant.

    This is an example of an H3 visualization

    defined with the following style

    aggregation

    The aggregation method that will be used on points within each cell. Supported values are count (default), sum, min, max, and mean .

    color range visualizations for polygons

    binMode

    Examples

    Explore examples of what you can build with the Felt SDK. These examples showcase different approaches to creating interactive map experiences - from extensions that run directly within Felt to embedded maps in custom applications.

    hashtag
    Extensions

    Extensions run directly within Felt maps, giving you immediate access to all SDK functionality. Here are some examples built using AI assistance:

    hashtag
    Commuter patterns

    Visualize transportation patterns by drawing lines to destination counties on click. Features travel mode options and filtering capabilities to analyze commuting data across different regions. View the map .

    hashtag
    Neighborhood comparison

    Compare neighborhoods side-by-side with automated analysis of land use patterns. This tool helps users understand demographic and geographic differences between areas. View the map .

    hashtag
    Animated data

    Bring geographic data to life with animations showing the flow of the Mississippi River Basin from headwaters to the Gulf of Mexico, demonstrating how to create compelling temporal visualizations. View the map .

    hashtag
    Story map

    Guide users through agricultural regions with an interactive narrative experience that combines storytelling with geographic exploration. View the map .

    hashtag
    Embedded maps

    Embed Felt maps in your own applications and control them with the SDK. Here are some examples built with React and hosted on CodeSandbox:

    hashtag
    Rooftop Solar Potential

    This interactive application leverages the Tool API to enable users to draw custom geometries that retrieve filtered GeoJSON data from an ESRI FeatureService. The application creates a dynamically styled GeoJSON layer to visualize solar potential data, helping users identify optimal locations for solar installations. View the app and code .

    hashtag
    Sales Dashboard

    Create powerful business intelligence tools by combining Felt's layer statistics with popular charting libraries. This example demonstrates how to build interactive visualizations that leverage layer filters. View the app and code .

    hashtag
    Custom legend with nested folders

    Enhance map usability with a custom legend that extracts and uses styling information to generate SVG icons. The code demonstrates how to build a nested folder structure with visibility toggles using layer filters, providing a pattern for organizing complex data layers. View the app and code .

    hashtag
    Inset maps

    Build comprehensive multi-view dashboards by embedding multiple Felt maps on a single page. This example demonstrates how to create synchronized map views that communicate with each other, enabling users to simultaneously view different geographic contexts or zoom levels of the same data. View the app and code .

    hashtag
    Lens Map

    Create engaging interactive experiences with customizable map lenses that reveal different data layers or styling as users explore. This technique allows for compelling before/after comparisons or the ability to highlight specific data attributes within a defined area. View the app and code .

    hashtag
    Isochrones

    Provides a pattern for integrating third-party geospatial APIs with Felt maps. This example demonstrates how to make API requests based on annotation geometry and map interactions, process the returned data, and visualise isochrones as dynamic layers. View the app and code .

    Legends

    Adding a legend block to a visualization makes a legend entry appear for this visualization.

    Each legend entry is shown with the geometry type and color defined by the dataset and the visualization block.

    While simple visualizations will generate a single legend entry, categorical visualizations will generate a legend entry per category.

    To see how a legend is defined, take a look at the legend block section.

    hashtag
    Simple legend

    The Biodiversity Hotspots layer in Felt has a simple visualization with a legend defined as follows:

    hashtag
    Categorical legend

    The Plant Hardiness Zones layer in Felt has a categorical visualization with a legend defined as follows:

    hashtag
    Numeric legends

    The visual display of numeric legends varies based on the style method (stepped or continuous) and the geometry type (point, line, polygon).

    The displayName can be modified in the legend block similar to simple and categorical style types.

    hashtag
    Stepped

    hashtag
    Continuous

    hashtag
    Heatmap legends

    Heatmap legends are defined as follows:

    Notice that the displayName mapping goes from 0 (left value) to 1 (right value)

    Categorical visualizations

    Categorical visualizations use a categorical attribute and the categories within it to apply styling to discrete categories of the attribute. On raster datasets, it uses a band instead of an attribute.

    Categorical visualizations are defined using "type": "categorical" and, for every supported style and label property used, either a single value that will apply to all categories or an array of different values for each category.

    hashtag
    Vector example

    The Global Power Plants layer in Felt is an example of a categorical layer on a vector dataset

    and is defined by the following style

    Notice that we are saying that the primary_fuel data attribute will be used to categorize elements and that the possible values of that attribute that we are interested in are "Nuclear", "Oil", "Coal", "Gas", "Wind", "Hydro" and "Solar". Also notice that we are defining either a single value that will apply to all categories (i.e. size) or a value for each category (i.e. color)

    hashtag
    Raster example

    The Cropscape CDL layer in Felt is an example of a categorical layer on a raster dataset

    and is defined by the following style:

    Style definition blocks

    hashtag
    The shape of a style definition

    A style in its most basic form contains a version definition but it can be extended to define how we want geometry and labels to show on the map, how the legend should look like, what information is shown in popups and the formatting used when displaying feature properties.

    The table below describes which properties can be used in the style definition.

    Field name
    Description

    Working with layers

    The Felt SDK allows you to add GeoJSON data to your maps from various sources:

    • Remote URLs

    • Local files

    • Programmatically generated GeoJSON data

    Map interactions and viewport

    The Felt SDK provides methods to control the map's viewport (the visible area of the map) and handle user interactions like clicking and hovering on the viewport.

    hashtag
    Working with the viewport

    hashtag

    Interpolators

    hashtag
    Interpolators

    Interpolators are functions that use the current zoom level to get you a value. The following interpolators are currently supported:

    hashtag
    Step

    {
      "config": {
        "steps": {"type": "quantiles", "count": 5},
        "aggregation": "sum",
        "binMode": "fixed",
        "baseBinLevel": 3,
        "numericAttribute": "capacity_mw"
      },
      "paint": {"color": "@riverine"},
      "type": "h3",
      "version": "2.3.1",
      "label": {},
      "legend": {"displayName": "auto"}
    }
    herearrow-up-right
    herearrow-up-right
    herearrow-up-right
    herearrow-up-right
    herearrow-up-right
    herearrow-up-right
    FSL
    herearrow-up-right
    herearrow-up-right
    herearrow-up-right
    herearrow-up-right
    H3 cell resolutionarrow-up-right
    Screenshot 2024-04-12 at 13.25.09.png
    Getting viewport state

    You can get the current viewport state using getViewport():

    hashtag
    Setting the viewport

    There are two main ways to set the viewport: moving to a specific point, or fitting to bounds.

    hashtag
    Moving to a point

    Use setViewport() to move the map to a specific location:

    hashtag
    Fitting to bounds

    Use fitViewportToBounds() to adjust the viewport to show a specific rectangular area:

    hashtag
    Responding to viewport changes

    To stay in sync with viewport changes, use the onViewportMove method:

    hashtag
    Map interactions

    hashtag
    Click events

    Listen for click events on the map using onPointerClick:

    hashtag
    Hover events

    Track mouse movement over the map using onPointerMove:

    hashtag
    Best practices

    1. Cleanup: Always store and call unsubscribe functions when you're done listening for events:

    1. Throttling: For pointer move events, consider throttling your handler if you're doing expensive operations:

    By using these viewport controls and interaction handlers, you can create rich, interactive experiences with your Felt map.

    "legend": {}
    "legend": {
      "displayName": {
        "13": "13: 60 to 70 °F",
        "12": "12: 50 to 60 °F",
        "11": "11: 40 to 50 °F",
        "10": "10: 30 to 40 °F",
        "9": "9: 20 to 30 °F",
        "8": "8: 10 to 20 °F",
        "7": "7: 0 to 10 °F",
        "6": "6: -10 to 0 °F",
        "5": "5: -20 to -10 °F",
        "4": "4: -30 to -20 °F",
        "3": "3: -40 to -30 °F",
        "2": "2: -50 to -40 °F",
        "1": "1: -60 to -50 °F"
      }
    }
    "legend": {
      "displayName": {
        "0": "5.14 to 19.46",
        "1": "19.46 to 26.43",
        "2": "26.43 to 34.06",
        "3": "34.06 to 45.06",
        "4": "45.06 to 100"
      }
    }
    "legend": {
      "displayName": {
        "0": "2.34M", 
        "1": "714.65K", 
        "2": "33K"
      }
    }
    "legend": {
      "displayName": {
        "0": "Low", 
        "1": "High"
     }
    }
    {
      "version": "2.3",
      "type": "categorical",
      "config": {
        "categoricalAttribute": "primary_fuel",
        "categories": ["Solar", "Hydro", "Wind", "Gas", "Coal", "Oil", "Nuclear"],
        "showOther": false
      },
      "legend": {"displayName": {}},
      "attributes": {
        "capacity_mw": {"displayName": "Capacity (MW)"},
        "name": {"displayName": "Name"},
        "primary_fuel": {"displayName": "Primary Fuel"}
      },
      "paint": {
        "color": [
          "#E5C550",
          "#7AB6C2",
          "#AB71A4",
          "#CC615C",
          "#AD7B68",
          "#EB9360",
          "#DEA145"
        ],
        "isSandwiched": false,
        "opacity": 1,
        "size": [{"linear": [[3, 1.5], [20, 8]]}]
      }
    }
    {
      "version": "2.3",
      "type": "categorical",
      "config": {
        "categories": [
          254,
          250,
          249,
          248,
          247,
          ...
          4,
          3,
          2,
          1,
          0
        ],
        "showOther": false
      },
      "legend": {
        "displayName": {
          "0": "Background",
          "1": "Corn",
          "2": "Cotton",
          "3": "Rice",
          "4": "Sorghum",
          ...
          "247": "Turnips",
          "248": "Eggplants",
          "249": "Gourds",
          "250": "Cranberries",
          "254": "Dbl Crop Barley/Soybeans"
        }
      },
      "paint": {
        "color": [
          "rgb(38, 113, 0)",
          "rgb(252, 105, 101)",
          "rgb(252, 105, 101)",
          "rgb(252, 105, 101)",
          "rgb(252, 105, 101)",
          ...
          "RGB(255, 158, 15)",
          "RGB(0, 169, 230)",
          "RGB(255, 38, 38)",
          "RGB(255, 212, 0)",
          "rgba(0, 0, 0, 0)"
        ],
        "isSandwiched": false,
        "opacity": 0.93
      }
    }
    const viewport = await felt.getViewport();
    console.log(viewport.center); // { latitude: number, longitude: number }
    console.log(viewport.zoom);   // number
    felt.setViewport({
      center: {
        latitude: 37.7749,
        longitude: -122.4194
      },
      zoom: 12
    });
    felt.fitViewportToBounds({
      bounds: [
        west,   // minimum longitude
        south,  // minimum latitude
        east,   // maximum longitude
        north   // maximum latitude
      ]
    });
    const unsubscribe = felt.onViewportMove({
      handler: (viewport) => {
        console.log("New center:", viewport.center);
        console.log("New zoom:", viewport.zoom);
      }
    });
    
    // Clean up when done
    unsubscribe();
    const unsubscribe = felt.onPointerClick({
      handler: (event) => {
        // Location of the click
        console.log("Click location:", event.center);
        
        // Features under the click
        console.log("Clicked features:", event.features);
        
        // The pixel coordinates of the cursor, measured from the top left corner of the map DOM element.
        console.log("Screen coordinates:", event.point);
        
        // Raster values, if applicable
        const {value, categoryName, color} = event.rasterValues;
      }
    });
    const unsubscribe = felt.onPointerMove({
      handler: (event) => {
        // Current mouse location
        console.log("Mouse location:", event.center);
        
        // Features under the cursor
        console.log("Hovered features:", event.features);
        
        // The pixel coordinates of the cursor, measured from the top left corner of the map DOM element.
        console.log("Screen coordinates:", event.point);
    
        // Raster values, if applicable
        const {value, categoryName, color} = event.rasterValues;
      }
    });
    const unsubscribe = felt.onPointerMove({
      handler: (event) => {
        // Handle event...
      }
    });
    
    // Later, when you're done:
    unsubscribe();
    import { throttle } from "lodash";
    
    felt.onPointerMove({
      handler: throttle((event) => {
        // Handle frequent mouse moves...
      }, 100) // Limit to once every 100ms
    });

    Optional. Defines how this layer will be shown on the layer panel.

    popup

    Optional. Defines how the popup is shown and what’s included.

    attributes

    Optional. Defines how attributes are shown both in the popup and the table.

    filters

    Optional. A data filter definition that defines which data will be rendered.

    version

    Mandatory. Defines which version this style adheres to

    type

    Optional. One of simple , categorical , numeric or heatmap. Defaults to simple.

    config

    Optional. A block that contains some configuration options to be used across the style. Learn more.

    style

    Optional. An object that defines how the data will be drawn. Learn more.

    label

    Optional. An object that defines how the labels will be drawn. Learn more.

    legend

    GeoJSON layers created via the SDK are temporary and session-specific - they're not permanently added to the map and won't be visible to other users.

    When creating a GeoJSON layer, you can specify different styles for each geometry type (Point, Line, Polygon) that might be found in the source. Each geometry type will create its own layer. It's important to note that GeoJSON layers added via the SDK have limited capabilities compared to regular Felt layers - they cannot be filtered, nor can statistics be fetched for them.

    hashtag
    Creating GeoJSON layers

    Use the method to add GeoJSON layers to your map. This method accepts different source types depending on where your GeoJSON data comes from.

    hashtag
    From a URL

    To create a layer from a GeoJSON file at a remote URL:

    hashtag
    From a local file

    To create a layer from a GeoJSON file on the user's device:

    hashtag
    From GeoJSON data

    To create a layer from GeoJSON data that you've generated or processed in your application. This approach is useful when you need to dynamically generate GeoJSON data based on user interactions or other app states:

    hashtag
    Styling by geometry type

    When creating GeoJSON layers, you can specify different styles for each geometry type that might be found in your data. The SDK will create separate layers for each geometry type:

    Each style should be a valid FSL (Felt Style Language) style. If you don't specify styles, Felt will apply default styles based on the geometry type.

    hashtag
    Deleting layers

    To remove a GeoJSON layer:

    Note that this only works for layers created via the SDK's createLayersFromGeoJson method, not for layers added through the Felt UI.

    hashtag
    Refreshing GeoJSON layers

    For GeoJSON layers created from URLs, you can set automatic refreshing:

    At Creation Time: By setting the refreshInterval parameter when creating the layer. The refreshInterval parameter is optional and specifies how frequently (in milliseconds) the layer should be automatically refreshed from the URL. Valid values range from 250ms to 5 minutes (300,000ms). If set to null or omitted, the layer won't refresh automatically.

    Manual Refresh: Simply replace the source property of any layer you have created, using the method to update the source data.

    { "step": [output0, Stops[]] }: Computes discrete results by evaluating a piecewise-constant function defined by stops on a given input. Returns the output value of the stop with a stop input value just less than the input one. If the input value is less than the input of the first stop, output0 is returned.

    Stops are defined as pairs of [zoom, value] where zoom is the minimum zoom level where value is returned and value can be number | string | boolean. Note that stops need to be defined by increasing zoom level.

    The following image shows the behavior of this definition:

    hashtag
    Linear

    { "linear": Stops[] }: Linearly interpolates between stop values less than or equal and greater than the input value

    The following image shows the behaviour of this definitions

    { "linear": [number, number] }: Expands to { "linear": [[minZoom, number], [maxZoom, number] }

    Color linear interpolation is done in the HCL color-space

    hashtag
    Exponential

    { "exp": [number, Stops[]] }: Exponentially interpolates between output stop values less than or equal and greater than the input value. The base parameter controls the rate at which output increases where higher values increase the output value towards the end of the range, lower values increase the output value towards the start of the range, and a base 1 interpolates linearly.

    The used value is computed as follows : (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1)

    The following images shows the behaviour of this definition

    hashtag
    Cubic Bezier

    { "cubicbezier": [number, number, number, number, Stops[]] }: Interpolates using the bezier curve defined by the curve control points.

    The following images shows the behaviour of this definition

    hashtag
    Default values

    Examples

    circle-info

    This page contains examples of different kinds of visualizations expressed in the Felt Style Language

    hashtag
    Minimal visualization

    hashtag
    Point layer example

    hashtag
    Polygon layer example

    hashtag
    Line layer example

    hashtag
    Color category

    hashtag
    Numeric visualization

    hashtag
    Heatmap visualization

    hashtag
    H3 visualization

    Building custom charts

    The Felt SDK provides powerful methods to analyze your geospatial data and transform it into informative visualizations. You can calculate statistics on entire datasets or focus on specific areas using boundaries and filters, allowing you to create custom charts that reveal insights about your spatial data.

    hashtag
    Data analysis methods

    The SDK offers three complementary approaches to analyze your map data:

    The config block

    The config block contains configuration options for a given visualization.

    These are the fields that each config block can contain:

    Field name
    Description

    Sample application

    This is a sample application showing how to use the Felt SDK to build an app with the following features:

    • listing the map's layers

    • toggling layer visibility

    • moving the viewport to center it on predefined city locations

    {
      "version": "2.1",
      "type": "simple",
      "style": {...}
    }
    const layerResult = await felt.createLayersFromGeoJson({
      source: {
        type: "geoJsonUrl",
        url: "https://example.com/data/neighborhoods.geojson",
        // Optional: Auto-refresh every 30 seconds
        refreshInterval: 30000
      },
      name: "Neighborhoods",
      caption: "Neighborhood boundaries for the city", // Optional
      description: "This layer shows the official neighborhood boundaries" // Optional
    });
    
    if (layerResult) {
      console.log("Created layer group:", layerResult.layerGroup);
      console.log("Created layers:", layerResult.layers);
    }
    // Assuming you have a File object from a file input
    const fileInput = document.getElementById('geojson-upload');
    const file = fileInput.files[0];
    
    const layerResult = await felt.createLayersFromGeoJson({
      source: {
        type: "geoJsonFile",
        file: file
      },
      name: "User Uploaded Data"
    });
    
    if (layerResult) {
      // Store the layer ID for later reference
      const layerId = layerResult.layers[0].id;
    }
    const geojsonData = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          geometry: {
            type: "Point",
            coordinates: [-122.4194, 37.7749]
          },
          properties: {
            name: "San Francisco",
            population: 874961
          }
        },
        // Additional features...
      ]
    };
    
    const layerResult = await felt.createLayersFromGeoJson({
      source: {
        type: "geoJsonData",
        data: geojsonData
      },
      name: "Dynamic Points"
    });
    const layerResult = await felt.createLayersFromGeoJson({
      name: "Styled Features",
      source: {
        type: "geoJsonUrl",
        url: "https://example.com/data/mixed-features.geojson"
      },
      geometryStyles: {
        Point: {
          paint: { 
            color: "red", 
            size: 8 
          }
        },
        Line: {
          paint: { 
            color: "blue", 
            size: 4 
          },
          config: { 
            labelAttribute: ["name"] 
          },
          label: { 
            minZoom: 0 
          }
        },
        Polygon: {
          paint: { 
            color: "green", 
            strokeColor: "darkgreen",
            fillOpacity: 0.5
          }
        }
      }
    });
    await felt.deleteLayer("layer-1");
    const layerResult = await felt.createLayersFromGeoJson({
      source: {
        type: "geoJsonUrl",
        url: "https://example.com/data/realtime-sensors.geojson",
        refreshInterval: 60000  // Refresh every minute
      },
      name: "Live Sensor Data"
    });
    { "step": ["hsl(50,5%,72%)", [[9, "hsl(10,75%,75%)"]] }
    // If zoom level is less than 9, "hsl(50,5%,72%)" will be returned
    // If zoom level is equal or higher than 9, "hsl(10,75%,75%)" will be returned
    
    { "step": [0, [[0, 0], [100, 100]]]} // Blue
    { "step": [0, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "step": [0, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    
    {
      "linear": [
        [8, 10],
        [14, 15],
        [20, 21]
      ]
    }
    // If zoom level is less than 8, 10 is returned
    // If zoom level is greater or equal than 8 but less than 14, a value linearly interpolated
    // between 10 and 15 is returned
    // If zoom level is greater or equal than 14 but less than 20, a value linearly interpolated // between 15 and 21 is returned
    // If zoom level is greater or equal than 20, 21 is returned
    
    { "linear": [[0, 0], [100, 100]]} // Blue
    { "linear": [[0, 0], [50, 50], [100, 100]]} // Red
    { "linear": [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]} // Yellow
    
    { "linear": [8, 10] }
    // If minZoom is defined as 3 and maxZoom is defined as 20:
    // If zoom level is less than 3, 8 is returned
    // If zoom level is between 3 and 20, a value linearly interpolated between 8 and 10 is
    // returned
    // If zoom level is greater or equal than 20, 10 is returned
    
    {
      "exp": [
        0.25,
        [
          [0, 25],
          [10, 100]
        ]
      ]
    }
    // If zoom level is less than 0, 25 is returned
    // If zoom level z is between 0 and 10, an interpolation factor is computed between 0 and 10
    // and then it's used to interpolate between 25 and 100
    // If zoom level is equal or higher than 10, 100 will be returned
    
    { "exp": [0.25, [[0, 0], [100, 100]]]} // Blue
    { "exp": [0.25, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "exp": [0.25, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    { "exp": [0.5, [[0, 0], [100, 100]]]} // Blue
    { "exp": [0.5, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "exp": [0.5, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    { "exp": [0.75, [[0, 0], [100, 100]]]} // Blue
    { "exp": [0.75, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "exp": [0.75, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    { "exp": [1, [[0, 0], [100, 100]]]} // Blue
    { "exp": [1, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "exp": [1, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    { "exp": [1.25, [[0, 0], [100, 100]]]} // Blue
    { "exp": [1.25, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "exp": [1.25, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    { "exp": [2, [[0, 0], [100, 100]]]} // Blue
    { "exp": [2, [[0, 0], [50, 50], [100, 100]]]} // Red
    { "exp": [2, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]]} // Yellow
    { "cubicbezier": [0.25, 0, 0.75, 1.5, [[0, 0], [100, 100]]]} // Blue
    { "cubicbezier": [0.25, 0, 0.75, 1.5, [[0, 0], [50, 50], [100, 100]]} // Red
    { "cubicbezier": [0.25, 0, 0.75, 1.5, [[0, 0], [25, 25], [50, 50], [75, 75], [100, 100]]} // Yellow
    {
      "version": "2.3",
      "type": "simple",
      "config": {},
      "paint": {},
      "label": {}
    }
    Learn more.
    Learn more.
    Learn more.
    Learn more.
    Graph showing a Step interpolator function
    Graph showing a Linear interpolator function
    hashtag
    1. Aggregates: single statistics

    Calculate individual values (count, sum, average, etc.) across your dataset or a filtered subset. If no aggregation method is provided, the count is returned.

    hashtag
    2. Categories: group by values

    Group features by unique attribute values and calculate statistics for each group.

    hashtag
    3. Histograms: group by numeric ranges

    Create bins for numeric data and calculate statistics for each range.

    hashtag
    Working with filters

    You can apply filters in two powerful ways:

    1. At the top level - Affects both which data is included and how values are calculated

    2. In the values configuration - Only affects the calculated values while keeping all categories/bins

    This two-level filtering is especially useful for creating comparative visualizations while maintaining consistent groupings.

    hashtag
    Advanced filtering examples

    Comparing building types by floor area (Categories)

    Comparing building heights across time periods (Histograms)

    Comparing neighborhood density (Aggregates)

    hashtag
    Interactive visualization example

    Here's how you might integrate these analysis methods with an interactive chart:

    This example demonstrates how a user clicking on a pie chart slice could apply a filter to the map, highlighting only the buildings of that type. It also shows how you could fetch additional statistics based on the user's selection to enrich the visualization experience.

    {
      "version": "2.3",
      "type": "simple",
      "config": { "labelAttribute": ["oper_cln", "owner_cln"] },
      "paint": {
        "color": "#8F7EBF",
        "strokeColor": "#CEC5E8"
      },
      "label": {
        "haloColor": "#E9E4F7",
        "color": "#8F7EBF"
      }
    }
    {
      "version": "2.3",
      "type": "simple",
      "config": { "labelAttribute": ["name"] },
      "label": {
        "minZoom": 4,
        "color": "#804779",
        "haloColor": "#EBD3E8",
        "haloWidth": 1,
        "fontSize": [12, 21]
      }
    }
    {
      "version": "2.3",
      "type": "simple",
      "config": { "labelAttribute": ["WSR_RIVER_"] },
      "paint": {
        "color": "hsl(217, 80%, 40%)"
      },
      "label": {
        "color": "hsl(217, 80%, 40%)",
        "fontStyle": "italic",
        "repeatDistance": 200
      }
    }
    {
      "version": "2.3",
      "type": "categorical",
      "config": {
        "categoricalAttribute": "primary_fu",
        "categories": ["Oil", "Coal", "Gas", "Hydro", "Wind", "Solar"]
      },
      "paint": {
        "color": [
          "#EB9360",
          "#AD7B68",
          "#A4B170",
          "#7AB6C2",
          "#8F99CC",
          "#E5C550"
        ],
        "strokeColor": [
          "#FFC8A8",
          "#D4D4D4",
          "#CBD79D",
          "#A3D6E0",
          "#BCC3E5",
          "#F2DB85"
        ],
        "size": [[1.5, 6]],
        "strokeWidth": [[0.25, 2]]
      },
      "label": {
        "minZoom": 12,
        "placements": ["E", "W"],
        "color": [
          "#DE7D45",
          "#946E59",
          "#7E8C46",
          "#5B99A6",
          "#6270B2",
          "#CCA929"
        ],
        "haloColor": [
          "#FAEAE1",
          "#F2E9E4",
          "#EDF2DA",
          "#D8ECF0",
          "#E4E7F7",
          "#F2E8C2"
        ],
        "lineHeight": [1.2],
        "fontSize": [
          {
            "linear": [
              [12, 10],
              [20, 20]
            ]
          }
        ]
      }
    }
    {
      "version": "2.3",
      "type": "numeric",
      "config": {
        "numericAttribute": "Renter occupied (%)",
        "steps": [5, 20, 25, 35, 45, 100]
      },
      "legend": {"displayName": "auto"},
      "paint": {
        "color": "@galaxy",
        "opacity": 0.9,
        "strokeColor": ["#9e9e9e"],
        "strokeWidth": 0.5,
        "isSandwiched": true
      }
    }
    {
      "version": "2.3",
      "type": "heatmap",
      "config": {},
      "legend": {"displayName": {"0": "Low", "1": "High"}},
      "paint": {
        "color": "@purpYlPink",
        "highlightColor": "#EA3891",
        "highlightStrokeColor": "#EA3891",
        "highlightStrokeWidth": {"linear": [[3, 0], [20, 2]]},
        "isSandwiched": false,
        "opacity": 0.9,
        "size": 10,
        "strokeColor": "#8F7EBF",
        "strokeWidth": {"linear": [[3, 0.8], [20, 2]]},
        "intensity": 0.2
      }
    }
    {
      "config": {
        "steps": {"type": "quantiles", "count": 5},
        "aggregation": "sum",
        "binMode": "fixed",
        "baseBinLevel": 3,
        "numericAttribute": "capacity_mw"
      },
      "paint": {"color": "@riverine"},
      "type": "h3",
      "version": "2.3.1",
      "label": {},
      "legend": {"displayName": "auto"}
    }
    // Count all residential buildings
    const residentialCount = await felt.getAggregates({
        layerId: "buildings",
        filters: ["type", "eq", "residential"]
    });
    // returns { count: 427 }
    
    // Calculate average home value in a specific neighborhood
    const avgHomeValue = await felt.getAggregates({
        layerId: "buildings",
        boundary: [-122.43, 47.60, -122.33, 47.62], // neighborhood boundary
        aggregation: {
            method: "avg",
            attribute: "assessed_value"
        }
    });
    // returns { avg: 652850.32 }
    // Basic grouping: Count of buildings by type
    const buildingsByType = await felt.getCategoryData({
        layerId: "buildings",
        attribute: "type"
    });
    /* returns:
    [
      { value: "residential", count: 427 },
      { value: "commercial", count: 82 },
      { value: "mixed-use", count: 38 },
      { value: "industrial", count: 15 }
    ]
    */
    // Basic histogram: Building heights in 5 natural break bins
    const buildingHeights = await felt.getHistogramData({
        layerId: "buildings",
        attribute: "height",
        steps: { type: "jenks", count: 5 }
    });
    /* returns:
    [
      { min: 0, max: 20, count: 175 },
      { min: 20, max: 50, count: 203 },
      { min: 50, max: 100, count: 142 },
      { min: 100, max: 200, count: 36 },
      { min: 200, max: 500, count: 6 }
    ]
    */
    // Advanced: Show all building types, but only sum floor area of recent buildings
    const recentBuildingAreaByType = await felt.getCategoryData({
        layerId: "buildings",
        attribute: "type",
        values: {
            filters: ["year_built", "gte", 2000],
            aggregation: {
                method: "sum",
                attribute: "floor_area"
            }
        }
    });
    /* returns:
    [
      { value: "residential", sum: 1250000 },
      { value: "commercial", sum: 750000 },
      { value: "mixed-use", sum: 350000 },
      { value: "industrial", sum: 120000 }
    ]
    */
    // Compare old vs new buildings using the same height ranges
    const oldBuildingHeights = await felt.getHistogramData({
        layerId: "buildings",
        attribute: "height",
        steps: [0, 20, 50, 100, 200, 500],
        values: {
            filters: ["year_built", "lt", 1950]
        }
    });
    /* returns:
    [
      { min: 0, max: 20, count: 96 },
      { min: 20, max: 50, count: 104 },
      { min: 50, max: 100, count: 37 },
      { min: 100, max: 200, count: 12 },
      { min: 200, max: 500, count: 1 }
    ]
    */
    
    const newBuildingHeights = await felt.getHistogramData({
        layerId: "buildings",
        attribute: "height",
        steps: [0, 20, 50, 100, 200, 500], // Same ranges as above
        values: {
            filters: ["year_built", "gte", 1950]
        }
    });
    /* returns:
    [
      { min: 0, max: 20, count: 79 },
      { min: 20, max: 50, count: 99 },
      { min: 50, max: 100, count: 105 },
      { min: 100, max: 200, count: 24 },
      { min: 200, max: 500, count: 5 }
    ]
    */
    // Find average residential density across different neighborhoods
    const downtownDensity = await felt.getAggregates({
        layerId: "buildings",
        boundary: [-122.335, 47.600, -122.330, 47.610], // downtown boundary
        filters: ["type", "eq", "residential"],
        aggregation: {
            method: "avg",
            attribute: "units_per_acre"
        }
    });
    // returns { avg: 124.7 }
    
    const suburbanDensity = await felt.getAggregates({
        layerId: "buildings",
        boundary: [-122.200, 47.650, -122.150, 47.700], // suburban boundary
        filters: ["type", "eq", "residential"],
        aggregation: {
            method: "avg", 
            attribute: "units_per_acre"
        }
    });
    // returns { avg: 8.2 }
    // Create a pie chart showing building type distribution
    async function createBuildingTypePieChart() {
        // Get data for the chart
        const data = await felt.getCategoryData({
            layerId: "buildings",
            attribute: "type"
        });
        
        // Render pie chart (using a hypothetical chart library)
        const chart = renderPieChart(data, {
            valuePath: "count",
            labelPath: "value",
            onSliceClick: handleSliceClick
        });
        
        return chart;
    }
    
    // Handle user interaction with the chart
    async function handleSliceClick(slice) {
        const buildingType = slice.label;
        
        // Apply filter to highlight this building type on the map
        await felt.setLayerFilters({
            layerId: "buildings",
            filters: ["type", "eq", buildingType],
            note: `Showing ${buildingType} buildings only`
        });
        
        // Get additional statistics for this building type
        const stats = await felt.getAggregates({
            layerId: "buildings",
            filters: ["type", "eq", buildingType],
            aggregation: {
                method: "avg",
                attribute: "year_built"
            }
        });
        
        // Update the UI with these statistics
        updateStatsPanel(`Average ${buildingType} building age: ${2025 - stats.avg}`);
    }
    
    // Initialize the chart when the page loads
    createBuildingTypePieChart();

    categories

    Mandatory for a categorical visualization. An array of the values that will be used as categories. Categories will be rendered from top to bottom following the definition order.

    labelAttribute

    Optional. Defines which dataset attribute or attributes to use for labeling. If multiple values are provided, the first available one will be used.

    method

    Optional. Used in raster algebra numeric visualizations. The type of operation and the bands used for it.

    noData

    Optional. Used in raster visualizations. Defines values that won’t be shown

    numericAttribute

    Mandatory for a numeric visualization. The attribute that contains the numeric values used.

    otherOrder

    Optional. Used in categorical visualizations. It can be set to either “below” or “above” to make features that do not match any of the defined categories render below or above the other ones. The default position is “below”.

    rasterResampling

    Optional. Used on raster data visualizations. It can be set to either “nearest” or “linear”. Defaults to “nearest”

    showOther

    Optional. Used in categorical visualizations. If this field is set to true it will show all features that do not match any of the defined categories and add an extra entry as the last item in the legend.

    steps

    Mandatory for a numeric visualization. An array of values that are either step based depending on the classification method and number of steps chosen or, for a continuous visualization, the min and max values from the numericAttribute.

    hashtag
    Default Values

    Name
    Points
    Polygons
    Lines
    Raster

    rasterResampling

    -

    -

    -

    “nearest”

    hashtag
    Examples

    band

    Optional. Used in raster numeric visualizations. The raster band that we’ll use to get the data from.

    categoricalAttribute

    Mandatory for categorical visualizations. The attribute that contains the categorical attributes that will be used.

    The sample Felt SDK Application

    The commented code in its entirety is shown below.

    Hiding and showing

    The Felt SDK provides methods to control the visibility of various entities like layers, layer groups, annotation groups, and legend items. These methods are designed to efficiently handle bulk operations.

    hashtag
    Understanding visibility requests

    All visibility methods use a consistent structure that allows both showing and hiding entities in a single call:

    hashtag
    Layers

    Control visibility of layer groups using setLayerVisibility:

    hashtag
    Layer groups

    Control visibility of layer groups using setLayerGroupVisibility:

    hashtag
    Annotation groups

    Similarly, control annotation group visibility with setElementGroupVisibility:

    hashtag
    Legend items

    Legend items require both a layer ID and an item ID to identify them. Use setLegendItemVisibility:

    hashtag
    Common use cases

    hashtag
    Focusing on a single layer

    To focus on a single layer by hiding all others, first get all layers and then use their IDs:

    hashtag
    Toggling visibility

    When implementing a toggle, you can use empty arrays for the operation you don't need:

    hashtag
    Best practices

    1. Batch operations: Use a single call with multiple IDs rather than making multiple calls:

    1. Omit unused properties: When you only need to show or hide, omit the unused property rather than including it with an empty array:

    Example of a categorical config block
    "config": [
    	{
        "labelAttribute": ["Wikipedia", "faa"],
    		"categoricalAttribute": "faa",
    		"categories": ["faa-code-1", "faa-code-2", "faa-code-3"],
    		"showOther": true,
    		"otherOrder": "above"
    	}
    ]
    Example of a vector numeric config block
    "config": [
    	{
        "labelAttribute": ["Wikipedia", "faa"],
    		"numericAttribute": "percentage",
    		"steps": [1, 25, 50, 75, 100]
    	}
    ]
    Example of a raster numeric config block
    "config": {
      "band": 1,
      "method": {"NDVI": {"NIR": 1, "R": 2}},
      "steps": [-0.5, 0.5]
    },
    <!doctype html>
    <html lang="en">
      <head>
        <title>Felt JS SDK</title>
      </head>
      <body>
        <div class="container">
          <div id="mapContainer"></div>
          <div id="sidebar">
            <div id="markers">
              <h3>Cities</h3>
            </div>
            <div id="layers">
              <h3>Layers</h3>
            </div>
          </div>
        </div>
    
        <script type="module">
          // Load the Felt SDK from the unpkg CDN
          import { Felt } from "https://esm.run/@feltmaps/js-sdk";
    
          // Get the map and sidebar elements
          const container = document.getElementById("mapContainer");
          const markerContainer = document.getElementById("markers");
          const layerContainer = document.getElementById("layers");
    
          // Embed the map
          const felt = await Felt.embed(container, "u49BWs5EtSI29CpwuwB9CzRiC", {
            uiControls: {
              showLegend: false,
              cooperativeGestures: false,
              fullScreenButton: false,
            },
          });
    
          // Add some cities to the sidebar
          const locations = [
            { name: "Oakland", lat: 37.8044, lng: -122.271 },
            { name: "New York", lat: 40.7128, lng: -74.006 },
            { name: "Los Angeles", lat: 34.0522, lng: -118.2437 },
            { name: "Chicago", lat: 41.8781, lng: -87.6298 },
            { name: "Houston", lat: 29.7604, lng: -95.3698 },
            { name: "Phoenix", lat: 33.4484, lng: -112.074 },
          ];
    
          locations.forEach((location) => {
            // create a DOM element with the city name
            const marker = document.createElement("div");
            marker.classList.add("marker");
            marker.innerText = location.name;
    
            // center the viewport on the city when the marker is clicked
            marker.addEventListener("click", () => {
              felt.setViewport({
                center: {
                  latitude: location.lat,
                  longitude: location.lng,
                },
                zoom: 10,
              });
            });
    
            // add the marker to the sidebar
            markerContainer.appendChild(marker);
          });
    
          // a helper function to toggle the visibility of a layer
          async function setLayerVisibility(previousVisibility, layer) {
            if (previousVisibility) {
              felt.setLayerVisibility({ hide: [layer.id] });
            } else {
              felt.setLayerVisibility({ show: [layer.id] });
            }
    
            // update the layer's visibility state
            layer.visible = !previousVisibility;
          }
    
          // get all the layers
          felt.getLayers().then((layers) => {
            layers.forEach((layer) => {
              // create a DOM element to represent the layer
              const layerElement = document.createElement("div");
              layerElement.classList.add("layer-toggles_toggle");
              layerElement.innerHTML = `
                <input type="checkbox" id="${layer.id}" ${
                  layer.visible ? "checked" : ""
                }>
                <label for="${layer.id}">${layer.name}</label>
              `;
    
              // add an event listener to the checkbox to toggle the layer visibility
              layerElement
                .querySelector("input")
                .addEventListener("change", () =>
                  setLayerVisibility(layer.visible, layer),
                );
    
              // add the layer element to the container
              layerContainer.appendChild(layerElement);
            });
          });
        </script>
      </body>
      <style>
        body {
          margin: 0;
          padding: 0;
          font-family: sans-serif;
          font-size: 13px;
        }
    
        .container {
          display: grid;
          grid-template-columns: 1fr 240px;
          height: 100vh;
        }
    
        iframe {
          display: block;
        }
    
        #sidebar {
          padding: 1rem;
          user-select: none;
        }
    
        #markers {
          margin-bottom: 1rem;
          padding-bottom: 1rem;
          border-bottom: 1px solid #ccc;
        }
    
        .marker {
          cursor: pointer;
          padding: 0.25rem 0;
        }
    
        .layer-toggles_toggle {
          padding: 0.25rem 0;
          margin-left: -4px;
          display: flex;
          align-items: center;
          gap: 0.25rem;
        }
    
        h3 {
          margin: 0;
          margin-bottom: 0.5rem;
        }
      </style>
    </html>
    {
      show?: string[],  // IDs of entities to show
      hide?: string[]   // IDs of entities to hide
    }

    highlightColor

    "#EA3891"

    "#EA3891"

    "#EA3891"

    -

    highlightStrokeColor

    "#EA3891"

    "#EA3891"

    "#EA3891"

    -

    dashArray

    -

    -

    -

    lineCap

    -

    -

    "round"

    -

    lineJoin

    -

    -

    "round"

    -

    opacity

    0.9

    0.8

    1

    -

    isSandwiched

    -

    false

    -

    -

    size

    4

    -

    2

    -

    strokeColor

    "#F9F8Fb"

    "#777777"

    -

    -

    strokeWidth

    1

    1

    -

    -

    felt.setLayerVisibility({
      show: ["layer-1", "layer-2"],
      hide: ["layer-3"]
    });
    felt.setLayerGroupVisibility({
      show: ["group-1", "group-2"],
      hide: ["group-3"]
    });
    felt.setElementGroupVisibility({
      show: ["points-group"],
      hide: ["lines-group", "polygons-group"]
    });
    felt.setLegendItemVisibility({
      show: [
        { layerId: "layer-1", id: "item-1" },
        { layerId: "layer-1", id: "item-2" }
      ],
      hide: [
        { layerId: "layer-1", id: "item-3" }
      ]
    });
    const layers = await felt.getLayers();
    const targetLayerId = "important-layer";
    
    felt.setLayerVisibility({
      show: [targetLayerId],
      hide: layers
        .map(layer => layer?.id)
        .filter(id => id && id !== targetLayerId)
    });
    function toggleLayer(layerId: string, visible: boolean) {
      felt.setLayerVisibility({
        show: visible ? [layerId] : [],
        hide: visible ? [] : [layerId]
      });
    }
    // Better approach
    felt.setLayerVisibility({
      show: ["layer-1", "layer-2"],
      hide: ["layer-3", "layer-4"]
    });
    
    // Less efficient approach
    felt.setLayerVisibility({ show: ["layer-1"] });
    felt.setLayerVisibility({ show: ["layer-2"] });
    felt.setLayerVisibility({ hide: ["layer-3"] });
    felt.setLayerVisibility({ hide: ["layer-4"] });
    // Do this
    felt.setLayerVisibility({
      show: ["layer-1"]
    });

    Drawing annotations

    circle-exclamation

    hashtag
    Note: Annotations were previously referred to as Elements.

    References have been updated in the app and documentation, while naming in the REST API and JS SDK remains unchanged.

    The Felt SDK provides two main approaches for creating annotations on your maps:

    1. Interactive Drawing: Configure and activate drawing tools for users to create annotations manually

    2. Programmatic Creation: Create and modify annotations directly through code

    Annotations created via the SDK are session-specific - they're not persisted to the map and won't be visible to other users.

    hashtag
    Interactive Drawing with Tools

    The methods on the enable you to programmatically activate drawing tools for your users, as well as setting various options for the tools, such as color, line width, etc.

    Use the method to activate a particular tool.

    Use the method to configure the options for a specific tool.

    Use the and to be notified of changes to the above, or read them instantaneously with the and methods.

    As the user creates annotations with the tools, you can be notified of them being created and updated using the and listeners. See for more details.

    hashtag
    Tool types

    Tool name
    Annotation Type
    Description

    hashtag
    Example

    hashtag
    Programmatic Annotation Creation

    If you want to create annotations programmatically instead of letting your users draw them interactively on the map, use the methods in the .

    To create annotations, use the method.

    To update annotations, use the method.

    To delete annotations, use the method.

    When annotations are created programatically, they also trigger notifications about the corresponding changes to annotations, via onElementCreate, onElementChange and onElementDelete.

    hashtag
    Example

    hashtag
    Retrieving Annotation geometry

    Extract the geometric representation of annotations using the method.

    The geometry is returned in GeoJSON geometry format, which can be quite different to the way the annotation is specified in Felt. For example, Circle annotations in Felt have their geometry converted into a polygon, representing the area covered by the circle.

    Note: Text, Note, and Image annotations do not return geometry as they are considered to annotations rather than true "geospatial" annotations.

    hashtag
    Listening for changes

    Every change that is made to the annotations on a map results in a call to either , or .

    hashtag
    Listening for annotation creation

    There are two different ways for listening to annotations being created, and the one you use depends on how the annotation is being created, and at what point you want to know about an annotation's creation.

    When the user is creating annotations with tools, they are often created in a number of steps, such as drawing a marker stroke or creating a polygon with many vertices.

    When you want to know when the user has finished creating the annotation (e.g. the polygon was closed or the marker stroke ended) then you should use the listener.

    When annotations are created programmatically, they do not trigger the event.

    Annotations created using Tools or will trigger the event, with an extra property stating whether the annotation is still being created.

    hashtag
    Sample application: sending annotations drawn by users to your backend

    Here is an example showing the power of the Felt SDK, where in just a few lines of code you can allow your users to draw annotations and have them sent to your own backend systems for persistence or analysis.

    Assuming you have embedded your Felt map as described in , and in your own UI you have added a polygon-tool button and a reset-tool button, all you need is the following:

    Numeric visualizations (color & size)

    Numeric visualizations use a numeric attribute to either vary colors or sizes between ranges of values and are defined in FSL with "type: numeric".

    Ranges are calculated between 3-10 discrete steps using a classification methodarrow-up-right or on a continuous scale between an attribute’s min and max values. Felt offers the following methods to symbolize numeric data:

    Method
    Description

    Jenks Natural Breaks

    hashtag
    Color

    Color numeric values in your data using the color property.

    Stepped color

    This map shows the percent of renter occupied housing units by US county. Each county is colored according to the step of ranges it falls into using a sequential color palette where light colors are assigned to low values and darker colors for high values.

    The style for this map is defined

    • with the visualization type: numeric

    • numericAttribute: "Renter occupied (%)" and the computed steps using Jenks Natural Breaks over 5 classes

    • the sequential color

    Continuous Color

    The map below shows average accumulated precipitation in the State of California between the years 1900 - 1960 and is colored along a continuous range between the min and max of the precipitation values.

    In this case, the numeric style is applied using a continuous method.

    • In the config block, the numericAttribute: PRECIP has steps that range between the min and max values of [2.5,125]

    • The color property has an array of three colors ["#fde89b", "#f37b8a", "#4d53b3"] that are interpolated to give each precipitation value a unique color

    circle-info

    Any time there are fewer colors than values in a numeric style, they are interpolated in the ().

    Felt also supports stepped and continuous color numeric visualizations on raster datasets like you can see on the map below

    which includes a raster layer with the following style

    Notice that in the config block we are using band instead of numericAttribute to define which band will be used for display

    hashtag
    Size

    Size numeric values in your point or line data using the size property.

    Stepped size

    The map below shows earthquakes over the past year sized with 5 manually defined steps.

    In this case, the numeric style is applied using a classed method.

    • In the config block, the numericAttribute: mag has manually-defined steps for 5 classes

    • The size property has an array of five sizes, one for each defined class

    Map link:

    Continuous size

    The map below shows tonnes of corn that have been exported from Ukraine since August 2022 under the . The symbol size for each country is proportionate to its value in the data.

    To do this the min and max steps from the numericAttribute: tonnes are interpolated to be proportionately sized between a min and max point size — size:[5,48]

    The label block

    circle-info

    The label block defines how feature labels are rendered.

    These are the properties available to define label rendering. Anchors can be lines or points, polygons are not supported.

    Type
    Applies to
    Description
    array where each color is applied to a distinct
    step
    range

    Finds natural groupings in attribute values to minimize differences within steps and maximize differences between them. A good option for clustered data. This is the default method in Felt.

    Equal interval

    Divides attribute values into an equal number of steps. Equal interval is a good option when data is equally spread across the range of values.

    Quantiles

    Places an equal number of values into each step. A good option for evenly distributed data.

    Mean Standard Deviation

    Steps are calculated based on an attribute values distance from the mean. A good option for data that follows a near-normal distribution.

    Manual

    Manually define which values to include in each size or color step. A good option when you know your data well.

    Continuous

    Attribute values are sized or colored based on a continuous scale between the min and max values versus discrete steps. A good option for continuous data.

    hcl color spacearrow-up-right
    Earthquakes Stepped Sizearrow-up-right
    UN’s Black Sea Grain Initiativearrow-up-right
    Map link: Percent renter occupied housing by countyarrow-up-right
    Map link: Average annual precipitationarrow-up-right
    Map link: Black Sea Grain Initiativearrow-up-right
    {
      "config": {
        "numericAttribute": "Renter occupied (%)",
        "steps": {"type": "jenks", "count": 5}
      },
      "label": {
        "color": ["#d2e2a6", "#9dc596", "#6ba888", "#3e897b", "#096b6d"],
        "fontSize": 14,
        "fontStyle": "Normal",
        "fontWeight": 400,
        "haloColor": ["#9e9e9e", "#9e9e9e", "#9e9e9e", "#9e9e9e", "#9e9e9e"],
        "haloWidth": 1.5,
        "justify": "auto",
        "letterSpacing": 0.1,
        "lineHeight": 1.3,
        "maxLineChars": 10,
        "maxZoom": 23,
        "minZoom": 1,
        "padding": 20,
        "placement": ["Center"],
        "visible": true
      },
      "legend": {"displayName": "auto"},
      "paint": {
        "color": "@galaxy",
        "highlightColor": "hsla(329,81%,64%, 0.5)",
        "highlightStrokeColor": "hsla(329,81%,64%, 0.8)",
        "highlightStrokeWidth": {"linear": [[3, 0.5], [20, 2]]},
        "isSandwiched": true,
        "opacity": 0.9,
        "showAboveBasemap": true,
        "strokeColor": ["#9e9e9e", "#9e9e9e", "#9e9e9e", "#9e9e9e", "#9e9e9e"],
        "strokeWidth": 0.5
      },
      "type": "numeric",
      "version": "2.3"
    }
    {
      "config": {
        "numericAttribute": "PRECIP",
        "steps": {"count": 1, "type": "continuous"}
      },
      "label": {
        "color": ["#fde89b", "#f37b8a", "#4d53b3"],
        "fontSize": 14,
        "fontStyle": "Normal",
        "fontWeight": 400,
        "haloColor": ["#9e9e9e", "#9e9e9e", "#9e9e9e"],
        "haloWidth": 1.5,
        "justify": "auto",
        "letterSpacing": 0.1,
        "lineHeight": 1.3,
        "maxLineChars": 10,
        "maxZoom": 23,
        "minZoom": 1,
        "padding": 20,
        "placement": ["Center"],
        "visible": true
      },
      "legend": {"displayName": "auto"},
      "paint": {
        "color": "@purpYl",
        "highlightColor": "hsla(329,81%,64%, 0.5)",
        "highlightStrokeColor": "hsla(329,81%,64%, 0.8)",
        "highlightStrokeWidth": {"linear": [[3, 0.5], [20, 2]]},
        "isClickable": false,
        "isSandwiched": true,
        "opacity": 0.9,
        "strokeColor": ["#9e9e9e", "#9e9e9e", "#9e9e9e"],
        "strokeWidth": 0
      },
      "type": "numeric",
      "version": "2.3"
    }
    {
      "version": "2.3"
      "type": "numeric",
      "config": {"band": 1, "steps": [-154.46435546875, 7987.457987843631]},
      "legend": {"displayName": {"0": "-154.46", "1": "7.99K"}},
      "paint": {
        "isSandwiched": false,
        "opacity": 1,
        "color": [
          "#454b9f",
          "#2d79a4",
          "#18a2a9",
          "#8cc187",
          "#e5d96c",
          "#eab459",
          "#ef8b45",
          "#e66250",
          "#db2d5e"
        ]
      }
    }
    {
      "version": "2.3",
      "type": "numeric",
      "config": {"numericAttribute": "mag", "steps": [4.5, 5.5, 6, 7, 7.5, 8.2]},
      "legend": {"displayName": "auto"},
      "paint": {
        "size": [5, 10, 12, 14, 16],
        "color": "hsl(0, 13%, 45%)",
        "opacity": 0.9,
        "strokeColor": "hsl(0, 13%, 88%)",
        "strokeWidth": 1.5
      }
    }
    {
      "version": "2.3",
      "type": "numeric",
      "config": {
        "steps": [33000, 2344684],
        "numericAttribute": "tonnes",
        "labelAttribute": ["category"]
      },
      "label": {
        "minZoom": 1,
        "color": "#5a5a5a",
        "fontSize": 14,
        "fontStyle": "Normal",
        "fontWeight": 500,
        "haloColor": "#d0d0d0",
        "haloWidth": 1.5,
        "offset": [8, 0]
      },
      "legend": {"displayName": {"0": "2.34M", "1": "714.65K", "2": "33K"}},
      "paint": {
        "size": [5, 48],
        "color": "hsl(22, 78%, 65%)",
        "opacity": 0.9,
        "strokeColor": "hsl(22, 78%, 88%)",
        "strokeWidth": 1.5
      }
    }

    Line

    Creates a line that follows the routing logic depending on the mode of transport selected. For instance, walking, driving and cycling routes follow applicable roads and pathways to reach the waypoints the user provides. Flying routes follow great circle paths.

    polygon

    Polygon

    Creates an enclosed area with straight edges

    circle

    Circle

    A circle is defined by its center and radius.

    marker

    Marker

    Freeform drawing with a pen-like rendering. Different sizes can be set for the pen. The geometry produced is in world-space, so as you zoom the map, the pen strokes remain in place.

    highlighter

    Highlighter

    Represents an area of interest, created by drawing with a thick pen. By default, drawing an enclosed shape fills the interior.

    text

    Text

    A label placed on the map with no background color.

    note

    Note

    A label placed on the map with a rectangular background color and either white or black text.

    pin

    Place

    Creates a single point on a map, with a symbol and optional label

    line

    Line

    Creates a sequence of straight lines through the points that the user clicks

    Getting started
    Listening for annotation creation

    route

    color

    string | auto |

    Points and lines

    Optional. The label color

    fontFamily

    string

    Points and lines

    Optional. The font family to use

    fontSize

    number |

    Points and lines

    See default values of these attributes on each label type.

    If using a categorical or numeric visualization, all the previous properties must be arrays. If there's a single value in the array, that value is used in all categories. If there are as many values as categories, the corresponding value will be used for each category. You can see an example of a categorical viz here.

    hashtag
    Default values

    Name
    Points
    Lines
    Centroids

    color

    "#333333"

    "#333333"

    "#333333"

    fontFamily

    "Atlas Grotesk LC"

    UI components

    hashtag
    Action Triggers and Custom Panels

    The Felt SDK enables you to extend Felt maps with custom UI components that integrate seamlessly with the native interface. These extensions allow you to add interactive controls and custom workflows directly within the map experience.

    hashtag
    UI Extension Points

    Felt provides two primary ways to add custom UI to your maps:

    Action Triggers appear as buttons in the left sidebar and provide quick access to custom actions. Think of them as shortcuts that users can click to trigger specific functionality in your application.

    Custom Panels appear in the right sidebar and offer a full canvas for complex UI. These panels can contain forms, controls, and interactive elements that work together to create sophisticated user experiences.

    hashtag
    Action Triggers

    Action triggers are simple button controls that execute custom functions when clicked. They're perfect for actions that don't require additional user input - like applying filters, running calculations, or enabling an interaction mode.

    hashtag
    Custom Panels

    Custom panels provide a structured way to build complex UI within Felt. Each panel consists of three main sections that serve different purposes:

    hashtag
    Panel Structure

    Header - Contains the panel title, and an optional close button.

    Body - Houses the main interactive elements like forms, selectors, and content areas. This is where users spend most of their time interacting with your custom functionality.

    Footer - Typically contains primary action buttons like "Save", "Cancel", or "Apply". This creates a consistent pattern users expect from dialog-style interfaces. The footer sticks to the bottom of the panel, with a divider separating it from the body.

    hashtag
    Getting Started with Panels

    Create a panel by first generating an ID, then specifying its contents. You can control where panels appear using the initialPlacement parameter. When onClickClose is specified, a close button will be rendered in the header.

    hashtag
    Panel Elements

    Custom panels support a variety of interactive and display elements that can be combined to create rich user experiences:

    hashtag
    Text Elements

    display formatted content and support full Markdown rendering, allowing you to include headings, lists, links, and formatting within your panels.

    hashtag
    TextInput Elements

    elements allow users to enter custom values like names, descriptions, or numeric parameters.

    hashtag
    Control Elements

    Control elements allow users to choose from predefined options:

    Available control elements include , , , and . Each element supports similar properties:

    hashtag
    Button Elements

    trigger actions and come in different styles to communicate their importance and effect. Buttons can have different variants (filled, outlined, and transparent) and tints (primary, accent, danger and default):

    Primary filled buttons highlight the most important action in a context. Use sparingly - typically one per panel section.

    hashtag
    Button Rows

    Group related buttons together to create clear action hierarchies:

    automatically handle spacing and alignment, ensuring your panels look polished and consistent.

    hashtag
    Grid Elements

    helps organize elements within panels to create complex layouts. It uses a grid property that follows the same syntax as the CSS shorthand grid property, and includes verticalAlignment and horizontalDistribution properties for precise control over layout positioning.

    hashtag
    iframe Elements

    allow you to embed external content by providing a URL to charts, dashboards, or other web applications directly within your panels.

    hashtag
    Divider Elements

    Divider elements provide visual separation between sections of content in your panels.

    hashtag
    Panel State Management

    hashtag
    Creating and Updating Panels

    A panel is identified by its ID, which must be created using . Custom IDs are not supported to prevent conflicts with other panels. Use for most panel scenarios. This declarative method lets you specify what the panel should contain, and it handles both creating new panels and updating existing ones with the same API call.

    hashtag
    Targeted Panel Element Updates

    Use for granular control when you want to modify individual elements. Elements need IDs to be targeted for updates. You can also use to add elements and to remove elements by their IDs.

    // Configure the line tool
    felt.setToolSettings({
      tool: "line",
      strokeWidth: 8,
      color: "#448C2A"
    });
    
    // Activate the line tool
    felt.setTool("line");
    
    // Later, deactivate the tool
    felt.setTool(null);
    
    // Create a polygon
    const polygonElement = await felt.createElement({
      type: "Polygon",
      coordinates: [
        [
          [-122.42, 37.78],
          [-122.41, 37.78],
          [-122.41, 37.77],
          [-122.42, 37.77],
          [-122.42, 37.78]
        ]
      ],
      color: "#FF5733",
      fillOpacity: 0.5
    });
    ​
    
    // Update its properties
    await felt.updateElement({
      id: polygonElement.id,
      
      // note that we pass the type here, too in order to get correct
      // TypeScript type-checking and autocompletion.
      type: "Polygon",
      
      color: "#ABC123",
      fillOpacity: 0.5,
      strokeWidth: 2
    });
    
    // Finally delete the element
    await felt.deleteElement(polygonElement.id)
    // Get an element's geometry in GeoJSON format
    const geometry = await felt.getElementGeometry("element-1");
    console.log(geometry?.type, geometry?.coordinates);
    // Set up a listener for changes to a polygon
    const unsubscribeChange = felt.onElementChange({
      options: { id: polygon.id },
      handler: ({element}) => {
        console.log("Polygon was updated:", element);
      }
    });
    ​
    // Set up a listener for deletion
    const unsubscribeDelete = felt.onElementDelete({
      options: { id: polygon.id },
      handler: () => {
        console.log("Polygon was deleted");
      }
    });
    ​
    // Later, clean up listeners
    unsubscribeChange();
    unsubscribeDelete();
    // Listen for any element creation
    const unsubscribe = felt.onElementCreate({
      handler: (element) => {
        console.log(`New element created with ID: ${element.id}`);
        
        // Check if the element is still being drawn
        if (element.isBeingCreated) {
          console.log("User is still creating this element");
        }
      }
    });
    
    // Or listen for when element creation is completed with a tool
    const unsubscribeEnd = felt.onElementCreateEnd({
      handler: ({element}) => {
        console.log(`Element ${element.id} creation finished`);
      }
    });
    
    // Later, clean up listeners
    unsubscribe();
    unsubscribeEnd();
    // Set your initial tool settings in a style that suits your application
    felt.setToolSettings({
      tool: "polygon",
      strokeWidth: 2,
      color: "#FF5733",
      fillOpacity: 0.3,
    });
      
    // Activate the tool when the user clicks a button in your UI
    ​document.getElementById("polygon-tool").addEventListener("click", () => {
      felt.setTool("polygon");
    });
    ​
    // Disable the tool when the user clicks a button in your UI
    document.getElementById("reset-tool").addEventListener("click", () => {
      felt.setTool(null);
    });
    ​
    // Listen for completed polygons
    felt.onElementCreateEnd({
      handler: async ({element}) => {
        // get the polygon geometry that the user just drew
        const geometry = await felt.getElementGeometry(element.id);
        
        // send the polygon to your own backend system
        sendToServer(geometry);
      }
    });

    Optional. The font size in pixels

    fontStyle

    normal | italic | oblique

    Points and lines

    Optional. The font style

    fontWeight

    number

    Points and lines

    Optional. The font weight

    haloColor

    string |

    Points and lines

    Optional. The label halo color

    haloWidth

    string |

    Points and lines

    Optional. The label halo color width

    letterSpacing

    number

    Points and lines

    Optional. Horizontal spacing behaviour between text characters

    lineHeight

    number

    Points and lines

    Optional. Sets the height of a line box

    maxLineChars

    number |

    Points and lines

    Optional. Defines the max number of characters before a line break

    maxZoom

    number

    Points and lines

    Optional. The maximum zoom level at which the label will be shown

    minZoom

    number

    Points and lines

    Optional. The minimum zoom level at which the label will be shown

    offset

    [number, number] | number

    Points and lines

    Optional. In the case of points, this value must be an array of two numeric offsets that will be applied on the positive X and Y axis defined by the label placement (i.e. an offset of [3,4] with a label placement of NE moves the label 3pixels to the right and 4 pixels above of the anchor point. An offset of [3,4] with a label placement of SW moves the label 3pixels to the left and 4 pixels below of the anchor point). In case of lines, this value is a single number that moves the label following the label position (i.e. an offset of 3 with a label position of Above will move the label 3 pixels above the line following the line normal. An offset of 3 with a label position of Below will mode the label 3 pixels under the line following the line normal)

    padding

    number

    Points and lines

    Optional. Adds invisible padding around the label that's used to compute label collisions

    placement

    TextPlacements[] | auto | LineLabelPlacement

    Points and Lines

    Optional. If defined on a points dataset, an array of label placements to test when placing the label. If all the placements collide with already existing labels, the label is not shown. If defined on a lines dataset, the label placement on a line

    renderAsLines

    boolean

    Polygons

    Optional. Renders labels along lines instead of using the centroids

    repeatDistance

    number

    Lines

    Optional. The distance in pixels between label repetitions on a line

    textTransform

    capitalize | uppercase | lowercase

    Points and lines

    Optional. Specifies how to capitalize the label

    isClickable

    boolean

    Points, Lines and Polygons

    Optional. A flag to tell if labels should be clickable

    isHoverable

    boolean

    Points, Lines and Polygons

    Optional. A flag to tell if labels should be hoverable

    "Atlas Grotesk LC"

    "Atlas Grotesk LC"

    fontSize

    13

    13

    13

    fontStyle

    "Normal"

    "Normal"

    "Normal"

    fontWeight

    500

    400

    500

    haloColor

    "#fbfcfb"

    "#fbfcfb"

    "#fbfcfb"

    haloWidth

    1

    1

    1

    justify

    “auto”

    “auto”

    “auto”

    letterSpacing

    0

    0

    0

    lineHeight

    1.2

    1.2

    1.2

    maxLineChars

    10

    -

    10

    maxAngle

    -

    30

    -

    maxZoom

    23

    23

    23

    minZoom

    23

    23

    23

    offset

    [8, 8]

    0

    -

    padding

    2

    1

    0

    placements

    “auto”

    “Above”

    “Center”

    repeatDistance

    -

    250

    -

    textTransform

    "none"

    "none"

    "none"

    Interpolator
    Interpolator
    Text elementsarrow-up-right
    TextInputarrow-up-right
    Selectarrow-up-right
    CheckboxGrouparrow-up-right
    RadioGrouparrow-up-right
    ToggleGrouparrow-up-right
    Button elementsarrow-up-right
    Button rowsarrow-up-right
    The grid elementarrow-up-right
    iframe elementsarrow-up-right
    createPanelIdarrow-up-right
    createOrUpdatePanelarrow-up-right
    updatePanelElementsarrow-up-right
    createPanelElementsarrow-up-right
    deletePanelElementsarrow-up-right
    await felt.createActionTrigger({
      actionTrigger: {
        label: "Check solar potential",
        onTrigger: async () => {
          // Enable polygon tool to allow a user to select a region
          await felt.setTool("polygon");
          // ...
        },
      }
    });
    const panelId = await felt.createPanelId();
    await felt.createOrUpdatePanel({
      panel: {
        id: panelId,
        title: "Add report",
        body: [
          { type: "Select", placeholder: "Choose a neighborhood", options: [...] },
          { type: "Select", placeholder: "Choose a severity", options: [...] },
          { type: "TextInput", placeholder: "Email", onBlur: storeEmail },
        ],
        footer: [
          {
            type: "ButtonRow",
            align: "end",
            items: [
              { type: "Button", label: "Back", variant: "transparent", tint: "default", onClick: handleBack },
              { type: "Button", label: "Done", variant: "filled", tint: "primary", onClick: handleDone }
            ]
          }
        ]
        onClickClose: async () => {
          // Clean up
          await felt.deletePanel(panelId);
        }
      },
      initialPlacement: { at: "start" } // Optional: control panel positioning
    });
    {
      type: "Text",
      content: "**Welcome!** This is a *formatted* text element with [links](https://felt.com).",
    }
    {
      type: "TextInput",
      placeholder: "First name",
      value: "",
      onChange: (args) => {
        console.log("New value:", args.value);
      },
    }
    // Select dropdown
    {
      type: "Select", // or "CheckboxGroup" | "RadioGroup" | "ToggleGroup"
      label: "Year",
      options: [
        { value: "2025", label: "2025" },
        { value: "2024", label: "2024" },
      ],
      value: "",
      onChange: (args) => {
        console.log("Selected:", args.value);
      }
    }
    {
      type: "Button",
      label: "Submit",
      variant: "filled", // "transparent" | "outlined"
      tint: "primary", // "default" | "accent" | "danger"
      onClick: async () => {
        // Handle button click
      }
    }
    {
      type: "ButtonRow",
      align: "end",
      items: [
        { type: "Button", label: "Clear", variant: "transparent", tint: "default", onClick: handleClear },
        { type: "Button", label: "Send report", variant: "filled", tint: "primary", onClick: handleSend }
      ]
    }
    {
      type: "Grid",
      grid: "auto-flow / 2fr 1fr", // CSS grid shorthand
      verticalAlignment: "start",
      horizontalDistribution: "stretch",
      items: [
        { type: "Text", content: "![image](https://example.com/image1.png)" },
        { type: "Text", content: "![image](https://example.com/image2.png) \n ![image](https://example.com/image3.png)" },
      ]
    }
    {
      type: "Iframe",
      url: "https://example.com/dashboard",
      height: 400,
    }
    {
      type: "Divider",
    }
    const panelId = await felt.createPanelId();
    const greetingElement = { id: "greeting", type: "Text", content: "Hello" };
    
    // Initial state
    await felt.createOrUpdatePanel({
      panel: {
        id: panelId,
        title: "My Panel",
        body: [greetingElement]
      }
    });
    
    // Update using destructuring
    await felt.createOrUpdatePanel({
      panel: {
        id: panelId,
        title: "My Panel",
        body: [{ ...greetingElement, content: "Hello World" }]
      }
    });
    const panelId = await felt.createPanelId();
    
    // Create panel with multiple elements
    await felt.createOrUpdatePanel({
      panel: {
        id: panelId,
        title: "Data Panel",
        body: [
          { id: "status-text", type: "Text", content: "Ready" },
          { 
            id: "layer-select", 
            type: "Select", 
            label: "Choose Layer",
            options: [
              { value: "layer1", label: "Population" },
              { value: "layer2", label: "Income" }
            ]
          }
        ]
      }
    });
    
    // Update only the text element
    await felt.updatePanelElements({
      panelId,
      elements: [{
        element: {
          id: "status-text",
          type: "Text",
          content: "Processing data..."
        }
      }]
    });
    
    // Add a new element to the panel
    await felt.createPanelElements({
      panelId,
      elements: [{
        element: { 
          id: "progress-text", 
          type: "Text", 
          content: "Progress: 50%" 
        },
        container: "body",
        placement: { at: "end" }
      }]
    });
    
    // Remove an element from the panel
    await felt.deletePanelElements({
      panelId,
      elements: ["progress-text"]
    });
    Interpolator
    Interpolator
    Interpolator

    The paint block

    circle-info

    The paint block defines how feature geometries and raster pixels are rendered.

    Properties common to all visualization types.

    Type
    Default
    Description

    hashtag
    Simple visualizations

    The following properties are available for the simple type of visualization

    Type
    Applies to
    Description

    See for the default values of these attributes on each geometry type.

    hashtag
    Categorical and numeric visualizations

    The following properties are available for the categorical and numerical type visualizations. (You can see an example of a categorical visualization )

    Type
    Applies to
    Description

    hashtag
    Label block reference

    These are the properties available to define label rendering. Anchors can be lines or points, polygons are not supported.

    Type
    Applies to
    Description

    See of these attributes on each label type.

    If using a categorical or numeric visualization, all the previous properties must be arrays. If there's a single value in the array, that value is used in all categories. If there are as many values as categories, the corresponding value will be used for each category. You can see an example of a categorical viz .

    hashtag
    Default values

    Name
    Points
    Polygons
    Lines
    setToolarrow-up-right
    ElementsControllerarrow-up-right

    maxZoom

    number

    22

    Optional. The maximum zoom level at which the visualization will be shown

    minZoom

    number

    0

    Optional. The minimum zoom level at which the visualization will be shown

    renderAsLines

    boolean

    false

    Optional. Decides if a polygon dataset should be render as lines thus making them render above the basemap. Note that using this requires that the style uses line properties instead of polygon ones.

    paintPropertyOverrides

    object

    Optional. Specify and MapLibre paint or layout properties. See for more.

    Optional. The dash line definition

    highlightColor

    string

    Points, lines and polygons

    Optional. The color to be used when a feature is selected

    highlightStrokeColor

    string

    Points, lines and polygons

    Optional. The stroke color to be used when a feature is selected

    lineCap

    "butt" | "round" | "square"|

    Lines

    Optional. The shape used to draw the end points of lines

    lineJoin

    "bevel" | "round"| "miter"|

    Lines

    Optional. The shape used to join two line segments when they meet

    opacity

    number |

    Points, lines and polygons

    Optional. The opacity to use from 0 to 1

    size

    number |

    Points and lines

    Optional. Point radius or line width in pixels

    strokeColor

    string | | auto

    Points and polygons

    Optional. Stroke color

    strokeWidth

    number |

    Points and polygons

    Optional. Stroke width in pixels

    Optional. The dash line definition

    lineCap

    "butt" | "round" | "square"|

    Lines

    Optional. The shape used to draw the end points of lines

    lineJoin

    "bevel" | "round"| "miter"|

    Lines

    Optional. The shape used to join two line segments when they meet

    opacity

    number |

    Points, lines and polygons

    Optional. The opacity to use from 0 to 1

    size

    number |

    Points and lines

    Optional. Point radius or line width in pixels

    strokeColor

    string | | auto

    Points and polygons

    Optional. Stroke color

    strokeWidth

    number |

    Points and polygons

    Optional. Stroke width in pixels

    Optional. The font family to use

    fontSize

    number |

    Points and lines

    Optional. The font size in pixels

    fontStyle

    normal | italic | oblique

    Points and lines

    Optional. The font style

    fontWeight

    number

    Points and lines

    Optional. The font weight

    haloColor

    string |

    Points and lines

    Optional. The label halo color

    haloWidth

    string |

    Points and lines

    Optional. The label halo color width

    letterSpacing

    number

    Points and lines

    Optional. Horizontal spacing behaviour between text characters

    lineHeight

    number

    Points and lines

    Optional. Sets the height of a line box

    maxLineChars

    number |

    Points and lines

    Optional. Defines the max number of characters before a line break

    maxZoom

    number

    Points and lines

    Optional. The maximum zoom level at which the label will be shown

    minZoom

    number

    Points and lines

    Optional. The minimum zoom level at which the label will be shown

    offset

    [number, number] | number

    Points and lines

    Optional. In the case of points, this value must be an array of two numeric offsets that will be applied on the positive X and Y axis defined by the label placement (i.e. an offset of [3,4] with a label placement of NE moves the label 3pixels to the right and 4 pixels above of the anchor point. An offset of [3,4] with a label placement of SW moves the label 3pixels to the left and 4 pixels below of the anchor point). In case of lines, this value is a single number that moves the label following the label position (i.e. an offset of 3 with a label position of Above will move the label 3 pixels above the line following the line normal. An offset of 3 with a label position of Below will mode the label 3 pixels under the line following the line normal)

    padding

    number

    Points and lines

    Optional. Adds invisible padding around the label that's used to compute label collisions

    placement

    TextPlacements[] | auto | LineLabelPlacement

    Points and Lines

    Optional. If defined on a points dataset, an array of label placements to test when placing the label. If all the placements collide with already existing labels, the label is not shown. If defined on a lines dataset, the label placement on a line

    renderAsLines

    boolean

    Polygons

    Optional. Renders labels along lines instead of using the centroids

    repeatDistance

    number

    Lines

    Optional. The distance in pixels between label repetitions on a line

    textTransform

    capitalize | uppercase | lowercase

    Points and lines

    Optional. Specifies how to capitalize the label

    isClickable

    boolean

    Points, Lines and Polygons

    Optional. A flag to tell if labels should be clickable

    isHoverable

    boolean

    Points, Lines and Polygons

    Optional. A flag to tell if labels should be hoverable

    "#EA3891"

    highlightStrokeColor

    "#EA3891"

    "#EA3891"

    "#EA3891"

    dashArray

    -

    -

    lineCap

    -

    -

    "round"

    lineJoin

    -

    -

    "round"

    opacity

    0.9

    0.8

    1

    isSandwiched

    -

    false

    -

    size

    4

    -

    2

    strokeColor

    "#F9F8Fb"

    "#777777"

    -

    strokeWidth

    1

    1

    -

    isClickable

    boolean

    true

    Optional. A flag to tell if features should be clickable

    isHoverable

    boolean

    false

    Optional. A flag to tell if features should be hoverable

    isSandwiched

    boolean

    true

    color

    string | Interpolator

    Points, lines and polygons

    Optional. The color to be used

    dashArray

    number[]

    color

    string | Interpolator

    Points, lines and polygons

    Optional. The color to be used

    dashArray

    number[]

    color

    string | auto | Interpolator

    Points and lines

    Optional. The label color

    fontFamily

    string

    color

    "#EE4D5A"

    "#826DBA"

    "#4CC8A3"

    highlightColor

    "#EA3891"

    default values
    here
    default values
    here

    Optional. A flag to tell if features affected by this visualization need to be rendered below the basemap road and water layers. Only applies to polygon features, point and line features are already rendered on top of the basemap

    Lines

    Lines

    Points and lines

    "#EA3891"

    herearrow-up-right
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    Interpolator
    selectFeature()
    selectFeature()
    getSelection()
    EntityNode
    clearSelection()
    onSelectionChange()
    createLayersFromGeoJson
    updateLayer
    ToolsController
    setToolSettings
    onToolChange
    onToolSettingsChange
    getTool
    getToolSettings
    onElementCreate
    onElementChange
    createElement
    updateElement
    deleteElement
    getElementGeometry
    onElementCreate
    onElementDelete
    onElementChange
    onElementCreateEnd
    onElementCreateEnd
    createElement
    onElementCreate

    hashtag
    Add layer from data source

    post

    Create a new layer from an existing data source connection (database, API, or file).

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Body
    dataset_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    fromstring · enumRequiredPossible values:
    or
    fromstring · enumRequiredPossible values:
    querystringRequired
    source_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    or
    fromstring · enumRequiredPossible values:
    source_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    stac_asset_urlstringRequired
    post
    /api/v2/maps/{map_id}/add_source_layer

    hashtag
    Refresh map layer

    post

    Trigger a data refresh for a layer from its original data source to pull in the latest updates.

    After uploading a file or URL, you may want to update the resulting layer with new data. The process is quite similar to the upload:

    • For URL uploads, simply making a single POST request to the refresh endpoint is enough

    • For file refreshes, the response of the initial POST request will include a URL and some pre-signed attributes, which will be used to upload the new file to Amazon S3.

    circle-info

    With the felt_python library, you can refresh a layer with a simple function call:

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map hosting the layer to refresh

    layer_idstringRequired

    The ID of the layer to refresh

    Responses
    chevron-right
    200

    Refresh response

    application/json
    layer_group_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    layer_idstring · felt_idOptional

    The ID of the layer created by this upload. If multiple layers are included in the upload, this is the ID of the first layer in the layer group.

    Example: luCHyMruTQ6ozGk3gPJfEB
    presigned_attributesobject · nullableOptional

    If provided, the presigned attributes to attach to the post request

    typestring · enumOptionalPossible values:
    urlstring · nullableOptional

    If provided, the URL to post the file to

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layers/{layer_id}/refresh

    hashtag
    Upload map layer

    post

    Upload a file or import data from a URL to create a new layer on the map.

    The /upload endpoint can be used for both URL and file uploads:

    • For URL uploads, simply making a single POST request to the upload endpoint is enough

    • For file uploads, the response of the initial POST request contain information you will use to upload the file to Amazon S3

    Check our docs to see what URLs are supported.

    Uploading the file to Amazon S3

    Layer files aren't uploaded directly to the Felt API. Instead, they are uploaded to an S3 bucket.

    The response to this API request will include a URL and pre-signed params for you to use to upload your file. Only a single file may be uploaded — if you wish to upload several files at once, consider wrapping them in a zip file.

    To upload the file, you must perform a multipart upload, and include the file contents in the file field.

    circle-info

    With the felt_python library, you can upload a file with a simple function call:

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to upload the layer to.

    Body
    post
    /api/v2/maps/{map_id}/upload

    hashtag
    Delete map element

    delete

    Permanently delete an element from a map.

    circle-exclamation

    This action cannot be undone. The element will be permanently removed from the map.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to delete the element from.

    element_idstringRequired

    The ID of the element to delete.

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/maps/{map_id}/elements/{element_id}

    hashtag
    List map elements

    get

    Returns a GeoJSON FeatureCollection containing all the elements in a map that are not in an element group.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to list elements from.

    Responses
    chevron-right
    200

    GeoJSON

    application/json
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/elements

    hashtag
    Create or update map elements

    post

    Create new elements or update existing ones on a map using GeoJSON data. Each element is represented by a feature in the POST'ed GeoJSON Feature Collection. For each feature, including an existing element id will result in the element being updated on the map. If no element id is provided (or a non-existent one), a new element will be created.

    circle-info

    The maximum payload size for any POST to the Felt API is 1MB. Additionally, complex element geometry may be automatically simplified. If you require large, complex geometries, consider uploading your data as a Data Layer.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to create the elements in

    Body
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    Responses
    chevron-right
    200

    GeoJSON

    application/json
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/elements

    hashtag
    Get map element group

    get

    Retrieve all elements from a specific group as GeoJSON.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map.

    group_idstringRequired

    The ID of the element group.

    Responses
    chevron-right
    200

    GeoJSON

    application/json
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/element_groups/{group_id}

    hashtag
    List map element groups

    get

    Returns a list of GeoJSON FeatureCollections, one for each element group in the map.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to list groups from.

    Responses
    chevron-right
    200

    ElementGroupList

    application/json
    colorstringRequired

    The color of the element group symbol.

    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstringRequired

    The ID of the element group.

    namestring · nullableRequired

    The name of the element group.

    symbolstring · nullableRequired

    The symbol used to represent the element group.

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/element_groups

    hashtag
    Create or update map element groups

    post

    Create new element groups or update existing ones.

    For each Element Group, including an existing Element Group id will result in the Element Group being updated. If no id is provided, a new Element Group will be created.

    circle-info

    The maximum payload size for any POST to the Felt API is 1MB. Additionally, complex element geometry may be automatically simplified. If you require large, complex geometries, consider uploading your data as a Data Layer.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to create the group in

    Bodyobject · ElementGroupParams[]
    colorstringOptionalDefault: #C93535
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequiredExample: My Element Group
    symbolstringOptionalDefault: dot
    Responses
    chevron-right
    200

    Element group list

    application/json
    colorstringRequired

    The color of the element group symbol.

    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstringRequired

    The ID of the element group.

    namestring · nullableRequired

    The name of the element group.

    symbolstring · nullableRequired

    The symbol used to represent the element group.

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/element_groups

    hashtag
    Publish map layer

    post

    Make a layer available in the workspace library for reuse by team members.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map where the layer is located

    layer_idstringRequired

    The ID of the layer to publish

    Body
    namestringOptional

    The name to publish the layer under

    Example: My Layer
    Responses
    chevron-right
    200

    Publish layer response

    application/json
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layers/{layer_id}/publish

    hashtag
    Publish map layer group

    post

    Make a layer group available in the workspace library for reuse by team members.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map where the layer group is located

    layer_group_idstringRequired

    The ID of the layer group to publish

    Body
    namestringOptional

    The name to publish the layer group under

    Example: My Layer
    Responses
    chevron-right
    200

    Publish layer group response

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layer_groups/{layer_group_id}/publish

    hashtag
    List library layers

    get

    List all layers in your workspace's library, or the felt layer library.

    You can add a layer from the library to a map by using the "Duplicate layers" API endpoint (POST /api/v2/duplicate_layers) and the layer id provided by this endpoint.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Query parameters
    sourcestring · enumOptional

    Defaults to listing library layers for your "workspace". Use "felt" to list layers from the Felt data library. Use "all" to list layers from both sources.

    Default: workspacePossible values:
    Responses
    chevron-right
    200

    LayerLibrary

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/library

    hashtag
    Export map comments

    get

    Export all comments and replies from a map in CSV, JSON, or GeoJSON format.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to export comments from.

    Query parameters
    formatstringOptional

    The format to export the comments in: 'csv', 'json' (default), or 'geojson'

    Responses
    chevron-right
    200

    Comment export response

    application/json

    Comment Thread

    itemsanyOptional

    Comment Thread

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/comments/export

    hashtag
    Resolve map comment

    post

    Mark a comment thread as resolved.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map that contains the comment.

    comment_idstringRequired

    The ID of the comment to resolve.

    Responses
    chevron-right
    200

    Comment resolved response

    application/json
    comment_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/comments/{comment_id}/resolve

    hashtag
    Delete map comment

    delete

    Permanently delete a comment or reply from the map.

    circle-exclamation

    This action cannot be undone. The comment or reply will be permanently removed from the map.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map that contains the comment.

    comment_idstringRequired

    The ID of the comment to delete.

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/maps/{map_id}/comments/{comment_id}

    hashtag
    Get current user

    get

    Retrieve profile information and settings for the authenticated user.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Responses
    chevron-right
    200

    User

    application/json
    emailstringOptional
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/user

    hashtag
    List projects

    get

    Retrieve all projects accessible to the authenticated user within the workspace.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Query parameters
    workspace_idstringOptional

    Only needed when using the API as part of a plugin

    Responses
    chevron-right
    200

    Projects

    application/json
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    selfstringOptionalExample: https://felt.com/api/v2/projects/V0dnOMOuTd9B9BOsL9C0UjmqC
    max_inherited_permissionstring · enumRequired

    The maximum permission level workspace members inherit on team-visible projects.

    Example: view_onlyPossible values:
    namestringRequired
    typestring · enumRequiredPossible values:
    visibilitystring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/projects

    hashtag
    Create project

    post

    Create a new project with specified name and visibility settings within the workspace.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Body
    max_inherited_permissionstring · enumOptional

    The maximum permission level workspace members inherit on team-visible projects. Only applicable when visibility is "workspace".

    Example: view_onlyPossible values:
    namestringRequired

    The name to be used for the Project

    visibilitystring · enumRequired

    Either viewable by all members of the workspace, or private to users who are invited.

    Possible values:
    Responses
    chevron-right
    200

    Project

    application/json
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    folder_idstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    visited_atstring · date_time · nullableRequired
    max_inherited_permissionstring · enumRequired

    The maximum permission level workspace members inherit on team-visible projects.

    Example: view_onlyPossible values:
    namestringRequired
    typestring · enumRequiredPossible values:
    visibilitystring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/projects

    hashtag
    Get project

    get

    Retrieve detailed information about a specific project including metadata, permissions, and references to the maps in the project.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    project_idstringRequired
    Responses
    chevron-right
    200

    Project

    application/json
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    folder_idstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    visited_atstring · date_time · nullableRequired
    max_inherited_permissionstring · enumRequired

    The maximum permission level workspace members inherit on team-visible projects.

    Example: view_onlyPossible values:
    namestringRequired
    typestring · enumRequiredPossible values:
    visibilitystring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/projects/{project_id}

    hashtag
    Delete project

    delete

    Permanently delete a project and all its contained maps and folders.

    triangle-exclamation

    Caution: Deleting a project deletes all of the folders and maps inside!

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    project_idstringRequired

    The ID of the Project to delete. Note: This will delete all Folders and Maps inside the project!

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/projects/{project_id}

    hashtag
    Update project

    post

    Update project properties including name and visibility settings.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    project_idstringRequired

    The ID of the project to update

    Body
    max_inherited_permissionstring · enumOptional

    The maximum permission level workspace members inherit on team-visible projects. Only applicable when visibility is "workspace".

    Example: view_onlyPossible values:
    namestringOptional

    The name to be used for the Project

    visibilitystring · enumOptional

    Either viewable by all members of the workspace, or private to users who are invited.

    Possible values:
    Responses
    chevron-right
    200

    Project

    application/json
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    folder_idstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    visited_atstring · date_time · nullableRequired
    max_inherited_permissionstring · enumRequired

    The maximum permission level workspace members inherit on team-visible projects.

    Example: view_onlyPossible values:
    namestringRequired
    typestring · enumRequiredPossible values:
    visibilitystring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/projects/{project_id}/update

    hashtag
    Get map layer group

    get

    Retrieve detailed information about a specific layer group including its layers and configuration.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    layer_group_idstringRequired
    Responses
    chevron-right
    200

    Layer Group

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/layer_groups/{layer_group_id}

    hashtag
    Update map layer group

    post

    Update layer group properties including name, visibility, and organization settings.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    layer_group_idstringRequired
    Body
    captionstringOptionalExample: A very interesting group
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    legend_visibilitystring · enumOptional

    Controls how the layer group is displayed in the legend

    Possible values:
    namestringOptionalExample: My Layer Group
    ordering_keyintegerOptional
    subtitlestringOptionalDeprecated

    Deprecated: use caption instead.

    visibility_interactionstring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    Responses
    chevron-right
    200

    LayerGroup

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layer_groups/{layer_group_id}

    hashtag
    Delete map layer group

    delete

    Permanently remove a layer group and all its contained layers from a map.

    circle-exclamation

    This action cannot be undone. The layer group and all its contained layers will be permanently removed from the map.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to delete the layer group from

    layer_group_idstringRequired

    The ID of the layer group to delete

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/maps/{map_id}/layer_groups/{layer_group_id}

    hashtag
    List map layers

    get

    Retrieve all layers from a map, including uploaded files and connected data sources.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Responses
    chevron-right
    200

    Layers list

    application/json
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/layers

    hashtag
    Update map layer

    post

    Update layer properties including styling, visibility, grouping, and other configuration options.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Bodyobject · LayerUpdateParams[]
    captionstringOptionalExample: A very interesting dataset
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    layer_group_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    legend_displaystring · enumOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enumOptional

    Controls whether or not the layer is displayed in the legend.

    Possible values:
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringOptionalExample: My Layer
    ordering_keyintegerOptional
    refresh_periodstring · enumOptionalPossible values:
    subtitlestringOptionalDeprecated

    Deprecated: use caption instead.

    Responses
    chevron-right
    200

    Layer list

    application/json
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layers

    hashtag
    List map layer groups

    get

    Retrieve all layer groups from a map to see how layers are organized.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Responses
    chevron-right
    200

    Layers Groups

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/layer_groups

    hashtag
    Update map layer groups

    post

    Update properties for multiple layer groups in a single request for efficient bulk operations.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Bodyobject · LayerGroupParams[]
    captionstringOptionalExample: A very interesting group
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    legend_visibilitystring · enumOptional

    Controls how the layer group is displayed in the legend

    Possible values:
    namestringRequiredExample: My Layer Group
    ordering_keyintegerOptional
    subtitlestringOptionalDeprecated

    Deprecated: use caption instead.

    visibility_interactionstring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    Responses
    chevron-right
    200

    LayerGroup list

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layer_groups

    hashtag
    Update layer style

    post

    Update the visual styling properties of a layer including colors, symbols, and rendering options.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map where the layer is located

    layer_idstringRequired

    The ID of the layer to update the style of

    Body
    styleobjectRequired

    The new layer style, specified in Felt Style Language format

    Responses
    chevron-right
    200

    Layer

    application/json
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/layers/{layer_id}/update_style

    hashtag
    Get map layer

    get

    Retrieve detailed information about a specific layer including data source, styling, and configuration.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    layer_idstringRequired
    Responses
    chevron-right
    200

    Layer

    application/json
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/layers/{layer_id}

    hashtag
    Delete map layer

    delete

    Permanently remove a layer from a map.

    circle-exclamation

    This action cannot be undone. The layer and all its data will be permanently removed from the map.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to delete the layer from

    layer_idstringRequired

    The ID of the layer to delete

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/maps/{map_id}/layers/{layer_id}

    hashtag
    Duplicate map layers

    post

    Copy layers or layer groups to other maps, preserving styling and configuration.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Bodyone of[]
    destination_map_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    source_layer_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    or
    destination_map_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    source_layer_group_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    Responses
    chevron-right
    200

    Duplicate Layers Response

    application/json
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/duplicate_layers

    hashtag
    Move map

    post

    Move a map to a different project or folder within the same workspace. Project IDs and Folder IDs can be found inside map settings.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Body
    project_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    or
    folder_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    Responses
    chevron-right
    200

    Map

    application/json
    basemapstringOptional
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestring · nullableOptional
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    folder_idstring · nullableOptional
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    default_table_layer_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    viewers_can_open_tablebooleanOptional

    Whether viewers can open the data table

    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    can_duplicate_mapbooleanOptional

    Whether viewers can duplicate the map and data

    can_export_databooleanOptional

    Whether viewers can export map data

    can_see_map_presencebooleanOptional

    Whether viewers can see who else is viewing the map

    visited_atstring · date_time · nullableRequired
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/move

    hashtag
    Duplicate map

    post

    Create a copy of a map with all its layers, elements, and configuration.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to duplicate

    Body
    destinationone ofOptional
    project_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    or
    folder_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    titlestringOptional

    Title for the duplicated map. If not provided, will default to '[Original Title] (copy)'

    Responses
    chevron-right
    200

    Duplicated Map

    application/json
    basemapstringOptional
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestring · nullableOptional
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    folder_idstring · nullableOptional
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    default_table_layer_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    viewers_can_open_tablebooleanOptional

    Whether viewers can open the data table

    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    can_duplicate_mapbooleanOptional

    Whether viewers can duplicate the map and data

    can_export_databooleanOptional

    Whether viewers can export map data

    can_see_map_presencebooleanOptional

    Whether viewers can see who else is viewing the map

    visited_atstring · date_time · nullableRequired
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/duplicate

    hashtag
    Create map

    post

    Create a new map with optional customization options.

    Several aspects can be customized when creating a new map, including:

    • Title

    • Initial location (latitude, longitude and zoom level)

    • Sharing permissions (defaults to viewing and commenting for users with the map URL)

    • An array of URLs to import on map creation

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Body
    post
    /api/v2/maps

    hashtag
    Update map

    post

    Update map properties including title, description, and access permissions.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to update

    Body
    basemapstringOptional

    The basemap to use for the map. Defaults to "default". Valid values are "default", "light", "dark", "satellite", a valid raster tile URL with {x}, {y}, and {z} parameters, or a hex color string like #ff0000.

    descriptionstringOptional

    A description to display in the map legend

    public_accessstring · enumOptional

    The level of access to grant to the map. Defaults to "view_only".

    Possible values:
    default_table_layer_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    viewers_can_open_tablebooleanOptional

    Whether viewers can open the data table

    titlestringOptional

    The new title for the map

    can_duplicate_mapbooleanOptional

    Whether viewers can duplicate the map and data

    can_export_databooleanOptional

    Whether viewers can export map data

    can_see_map_presencebooleanOptional

    Whether viewers can see who else is viewing the map

    Responses
    chevron-right
    200

    Map

    application/json
    basemapstringOptional
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestring · nullableOptional
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    folder_idstring · nullableOptional
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    default_table_layer_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    viewers_can_open_tablebooleanOptional

    Whether viewers can open the data table

    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    can_duplicate_mapbooleanOptional

    Whether viewers can duplicate the map and data

    can_export_databooleanOptional

    Whether viewers can export map data

    can_see_map_presencebooleanOptional

    Whether viewers can see who else is viewing the map

    visited_atstring · date_time · nullableRequired
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/update

    hashtag
    Get map

    get

    Retrieve a map with its metadata including title, URL, thumbnail, and timestamps.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Responses
    chevron-right
    200

    Map

    application/json
    basemapstringOptional
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestring · nullableOptional
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    folder_idstring · nullableOptional
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    default_table_layer_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    viewers_can_open_tablebooleanOptional

    Whether viewers can open the data table

    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    can_duplicate_mapbooleanOptional

    Whether viewers can duplicate the map and data

    can_export_databooleanOptional

    Whether viewers can export map data

    can_see_map_presencebooleanOptional

    Whether viewers can see who else is viewing the map

    visited_atstring · date_time · nullableRequired
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}

    hashtag
    Delete map

    delete

    Permanently delete a map and all its associated data.

    circle-exclamation

    This action cannot be undone. The map and all its layers, elements, and comments will be permanently removed.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map to delete

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/maps/{map_id}

    hashtag
    Create an Embed Token

    post

    Creates a short-lived (15 minutes) token for authenticating a visitor to view a private embedded map view without being logged into Felt. You must provide a user_email to associate the token with the end user that will be viewing the map. Each end user should be a member of your Felt workspace with a viewer, editor, or admin role assigned.

    hashtag
    Usage

    • Generate a token by making a call to this API from your server

    • Securely pass the token to your frontend client

    • Include the token as a query parameter on the Embed URL in an iframe

    Enabling Layer Export

    You can allow EmbedToken based page views to export layer data.

    • Turn on "Viewer permissions: Export data" in Map settings

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired
    Query parameters
    user_emailstringRequired

    Each token must be associated with the email address of the user who will use it.

    Responses
    chevron-right
    200

    EmbedToken

    application/json
    expires_atstring · date_timeOptionalExample: 2024-05-25T15:51:34
    tokenstringOptional
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/maps/{map_id}/embed_token

    hashtag
    Create layer export link

    get

    Generate a direct download link for layer data export.

    Get a link to export a layer as a GeoPackage (vector layers) or GeoTIFF (raster layers).

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map where the layer is located

    layer_idstringRequired

    The ID of the layer to export

    Responses
    chevron-right
    200

    Export link

    application/json
    export_linkstringRequired
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    503

    ServiceUnavailableError

    application/json
    get
    /api/v2/maps/{map_id}/layers/{layer_id}/get_export_link

    hashtag
    Check custom export status

    get

    Check the processing status and download availability of a custom export request.

    If the export is successful, the response will include a download_url for accessing the exported data.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map where the layer is located

    layer_idstringRequired

    The ID of the layer to export

    export_idstringRequired

    The ID of the export

    Responses
    chevron-right
    200

    Custom export request status

    application/json
    download_urlstring · nullableRequiredExample: https://us1.data-pipeline.felt.com/fcdfd96c-06fa-40b9-9ae9-ad034b5a66df/Felt-Export.zip
    export_idstringRequiredExample: FZWQjWZJSZWvW3yn9BeV9AyA
    itemsanyOptional
    statusstring · enumRequiredExample: completedPossible values:
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/maps/{map_id}/layers/{layer_id}/custom_exports/{export_id}

    hashtag
    Create custom layer export

    post

    Start a custom export with specific format and filter options for layer data.

    Export requests are asynchronous. A successful response will return a poll_endpoint to check the status of the export using the poll custom export endpoint.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    map_idstringRequired

    The ID of the map where the layer is located

    layer_idstringRequired

    The ID of the layer to export

    Body
    email_on_completionbooleanOptional

    Send an email to the requesting user when the export completes. Defaults to true

    itemsanyOptional
    output_formatstring · enumRequiredExample: csvPossible values:
    post
    /api/v2/maps/{map_id}/layers/{layer_id}/custom_export

    hashtag
    Update source

    post

    Update data source connection settings, access permissions, or configuration details.

    Connecting the Source and inspecting its datasets will happen asynchronously after the API response is returned. To determine when the inspection process has completed, poll the Show Source endpoint and check for sync_status: completed.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source to update

    Body
    post
    /api/v2/sources/{source_id}/update

    hashtag
    List sources

    get

    Retrieve all data sources accessible to the authenticated user within the workspace.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Query parameters
    workspace_idstringOptional

    Only needed when using the API as part of a plugin

    Responses
    chevron-right
    200

    Source references

    application/json
    automatic_syncstring · enumOptionalPossible values:
    connection_typestring · enumOptionalPossible values:
    created_atinteger · nullableOptional
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    last_synced_atinteger · nullableOptional
    selfstringOptionalExample: https://felt.com/api/v2/sources/V0dnOMOuTd9B9BOsL9C0UjmqC
    namestringOptional
    owner_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    permissionsone ofOptional
    typestring · enumRequiredPossible values:
    or
    typestring · enumRequiredPossible values:
    or
    project_idsstring · felt_id[]RequiredExample: luCHyMruTQ6ozGk3gPJfEB
    typestring · enumRequiredPossible values:
    sync_statusstring · enumOptionalPossible values:
    typestring · enumOptionalPossible values:
    updated_atinteger · nullableOptional
    workspace_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/sources

    hashtag
    Create source

    post

    Create a new data source connection with authentication credentials and access permissions.

    Connecting the Source and inspecting its datasets will happen asynchronously after the API response is returned. To determine when the inspection process has completed, poll the Show Source endpoint and check for sync_status: completed.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Body
    post
    /api/v2/sources

    hashtag
    Sync source

    post

    Trigger a full data synchronization from the source to update all connected layers with latest data.

    Syncing will happen asynchronously after the API response is returned. To determine when the inspection process has completed, poll the Show Source endpoint and check for sync_status: completed.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source to sync

    Responses
    chevron-right
    202

    Source reference

    application/json
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    post
    /api/v2/sources/{source_id}/sync

    hashtag
    Get source

    get

    Retrieve detailed configuration and connection information for a specific data source.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source to show

    Responses
    chevron-right
    200

    Source

    application/json
    automatic_syncstring · enumOptionalPossible values:
    connectionone of · nullableOptional
    blob_storage_urlstringOptional
    created_atinteger · nullableOptional
    credentialone ofOptional
    connection_stringstringRequired
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    source_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    updated_atinteger · nullableOptional
    use_casestring · enumOptionalPossible values:
    typestring · enumOptionalPossible values:
    or
    datasetstring · nullableOptional

    BigQuery dataset to index. If omitted all datasets will be indexed

    projectstringOptional

    BigQuery project to index

    typestring · enumOptionalPossible values:
    or
    catalogstring · nullableOptional
    created_atinteger · nullableOptional
    credentialone ofOptional
    client_idstringRequired
    client_secretstringRequired
    typestring · enumRequiredPossible values:
    or
    tokenstringRequired
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    source_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    updated_atinteger · nullableOptional
    use_casestring · enumOptionalPossible values:
    http_pathstringOptional
    schemastring · nullableOptional
    server_hostnamestringOptional
    typestring · enumOptionalPossible values:
    or
    typestring · enumOptionalPossible values:
    urlstringOptional
    or
    created_atinteger · nullableOptional
    credentialone ofOptional
    service_account_filenamestringRequired
    service_account_jsonone ofRequired
    objectOptional
    or
    stringOptional
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    source_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    updated_atinteger · nullableOptional
    use_casestring · enumOptionalPossible values:
    gs_uristringOptional
    typestring · enumOptionalPossible values:
    or
    databasestringOptional
    hoststringOptional
    portinteger · nullableOptional
    typestring · enumOptionalPossible values:
    userstringOptional
    or
    databasestringOptional
    hoststringOptional
    portinteger · nullableOptional
    schemastring · nullableOptional
    typestring · enumOptionalPossible values:
    userstringOptional
    or
    databasestringOptional
    hoststringOptional
    portinteger · nullableOptional
    typestring · enumOptionalPossible values:
    userstringOptional
    or
    created_atinteger · nullableOptional
    credentialone ofOptional
    role_arnstringRequired
    role_session_namestringRequired
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    source_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    updated_atinteger · nullableOptional
    use_casestring · enumOptionalPossible values:
    s3_uristringOptional
    typestring · enumOptionalPossible values:
    or
    account_idstringOptional
    created_atinteger · nullableOptional
    credentialone ofOptional
    tokenstringRequired
    typestring · enumRequiredPossible values:
    or
    private_keystringRequired
    private_key_namestringRequired
    private_key_passphrasestringOptional
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    source_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    updated_atinteger · nullableOptional
    use_casestring · enumOptionalPossible values:
    databasestringOptional
    rolestring · nullableOptional
    schemastring · nullableOptional
    typestring · enumOptionalPossible values:
    userstringOptional
    warehousestring · nullableOptional
    or
    created_atinteger · nullableOptional
    credentialone ofOptional
    service_account_filenamestringRequired
    service_account_jsonone ofRequired
    objectOptional
    or
    stringOptional
    typestring · enumRequiredPossible values:
    or
    connection_stringstringRequired
    typestring · enumRequiredPossible values:
    or
    role_arnstringRequired
    role_session_namestringRequired
    typestring · enumRequiredPossible values:
    or
    namestringRequired

    The header name

    sensitivebooleanRequired

    Whether or not the header is sensitive. If it is marked as sensitive, then felt:redacted will be returned when viewing this header

    valuestringRequired

    The header value

    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestringOptional
    source_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    updated_atinteger · nullableOptional
    use_casestring · enumOptionalPossible values:
    typestring · enumOptionalPossible values:
    urlstringOptional
    or
    typestring · enumOptionalPossible values:
    urlstringOptional
    or
    typestring · enumOptionalPossible values:
    urlstringOptional
    created_atinteger · nullableOptional
    created_atintegerOptional
    descriptionstring · nullableOptional
    geometry_typestring · enumOptionalPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    inspection_statusstring · enumOptionalPossible values:
    namestringOptional
    typestring · enumOptionalPossible values:
    updated_atintegerOptional
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    last_synced_atinteger · nullableOptional
    namestringOptional
    owner_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    permissionsone ofOptional
    typestring · enumRequiredPossible values:
    or
    typestring · enumRequiredPossible values:
    or
    project_idsstring · felt_id[]RequiredExample: luCHyMruTQ6ozGk3gPJfEB
    typestring · enumRequiredPossible values:
    sync_statusstring · enumOptionalPossible values:
    typestring · enumOptionalPossible values:
    updated_atinteger · nullableOptional
    workspace_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    get
    /api/v2/sources/{source_id}

    hashtag
    Delete source

    delete

    Permanently delete a data source connection and all its associated layers and data.

    circle-exclamation

    Any layers created from the Source will remain after it is deleted, but they will no longer be refreshed.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source to delete

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/sources/{source_id}

    hashtag
    Create source credential

    post

    Add authentication credentials to an existing data source for secure access.

    Some sources may need to be configured with additional credentials to work with Felt. Access to S3 Buckets, for example, may be protected by IAM policies. Adding a SourceCredential-AwsAssumeRole credential to your S3 Bucket source allows Felt to connect to a private source.

    Sensitive fields in credentials, like SourceCredential-KeyPair.private_key, will be returned as felt:redacted.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source to attach the credential

    Body
    post
    /api/v2/sources/{source_id}/credentials

    hashtag
    Update source credential

    post

    Update existing authentication credentials for a data source connection.

    Sensitive fields in credentials, like SourceCredential-KeyPair.private_key, will be returned as felt:redacted.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source that the credential belongs to

    credential_idstringRequired

    The ID of the credential

    Body
    post
    /api/v2/sources/{source_id}/credentials/{credential_id}/update

    hashtag
    Delete source credential

    delete

    Remove authentication credentials from a data source connection.

    Authorizations
    AuthorizationstringRequired
    Bearer authentication header of the form Bearer <token>.
    Path parameters
    source_idstringRequired

    The ID of the source that the credential belongs to

    credential_idstringRequired

    The ID of the credential to delete

    Responses
    chevron-right
    204

    No Content

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    delete
    /api/v2/sources/{source_id}/credentials/{credential_id}

    No content

    No content

    No content

    No content

    No content

    basemapstringOptional

    The basemap to use for the new map. Defaults to "default". Valid values are "default", "light", "dark", "satellite", a valid raster tile URL with {x}, {y}, and {z} parameters, or a hex color string like #ff0000.

    descriptionstringOptional

    A description to display in the map legend

    latnumberOptional

    If no data has been uploaded to the map, the initial latitude to center the map display on.

    layer_urlsstring[]Optional

    An array of urls to use to create layers in the map. Only tile URLs for raster layers are supported at the moment.

    lonnumberOptional

    If no data has been uploaded to the map, the initial longitude to center the map display on.

    public_accessstring · enumOptional

    The level of access to grant to the map. Defaults to "view_only".

    Possible values:
    titlestringOptional

    The title to be used for the map. Defaults to "Untitled Map"

    workspace_idstringOptional

    The workspace to create the map in. Defaults to the latest used workspace

    zoomnumberOptional

    If no data has been uploaded to the map, the initial zoom level for the map to display.

    Responses
    chevron-right
    200

    Map

    application/json
    basemapstringOptional
    created_atstring · date_timeRequiredExample: 2024-05-25T15:51:34
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    namestring · nullableOptional
    felt:idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    felt:parentIdstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    propertiesobjectOptional
    typestring · enumOptionalPossible values:
    typestring · enumRequiredPossible values:
    folder_idstring · nullableOptional
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    captionstring · nullableRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    legend_visibilitystring · enum · nullableOptional

    Controls how the layer group is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D
    namestringRequired
    ordering_keyintegerOptional

    A sort order key used for ordering layers and layer groups in the legend

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    typestring · enumRequiredPossible values:
    visibility_interactionstring · enumRequired

    Controls how the layer group is displayed in the legend. Defaults to "default".

    Possible values:
    namestringRequired

    The name of the attribute

    typestring · enumOptional

    The type of the attribute

    Possible values:
    captionstring · nullableRequired
    geometry_typestring · enum · nullableRequiredPossible values:
    hide_from_legendbooleanRequired
    idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    is_spreadsheetboolean · nullableOptional
    legend_displaystring · enum · nullableOptional

    Controls how the layer is displayed in the legend.

    Possible values:
    legend_visibilitystring · enum · nullableOptional

    Controls whether or not the layer is displayed in the legend. Defaults to "show".

    Possible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA
    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired
    ordering_keyinteger · nullableOptional

    A sort order key used for ordering layers and layer groups in the legend

    progressnumber · floatRequired
    refresh_periodstring · enumOptionalPossible values:
    statusstring · enumRequiredPossible values:
    styleobjectRequired

    The Felt Style Language style for the layer

    subtitlestring · nullableOptionalDeprecated

    Deprecated: use caption instead.

    tile_urlstring · nullableOptional

    The tile URL for this layer

    typestring · enumRequiredPossible values:
    selfstringOptionalExample: https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC
    project_idstringRequired
    public_accessstring · enumRequiredPossible values:
    default_table_layer_idstring · felt_id · nullableOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    viewers_can_open_tablebooleanOptional

    Whether viewers can open the data table

    thumbnail_urlstring · nullableRequired

    A static thumbnail image of the map

    titlestringRequired
    typestring · enumRequiredPossible values:
    urlstringRequired
    can_duplicate_mapbooleanOptional

    Whether viewers can duplicate the map and data

    can_export_databooleanOptional

    Whether viewers can export map data

    can_see_map_presencebooleanOptional

    Whether viewers can see who else is viewing the map

    visited_atstring · date_time · nullableRequired
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional

    No content

    Responses
    chevron-right
    200

    Custom export response

    application/json
    export_request_idstring · felt_idRequiredExample: luCHyMruTQ6ozGk3gPJfEB
    poll_endpointstringRequiredExample: http://felt.com/api/v2/maps/vAbZ5eKqRoGe4sCH8nHW8D/layers/7kF9Cfz45TUWIiuuWV8uZ7A/custom_exports/auFxn9BO4RrGGiKrGfaS7ZB
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    503

    ServiceUnavailableError

    application/json
    Responses
    chevron-right
    202

    AddSourceLayerAccepted

    application/json
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    latstringRequired
    lngstringRequired
    or
    lat_lngstringRequired
    or
    full_addressstringRequired
    or
    countrystringOptional

    ex: USA

    localitystringOptional

    ex: Oakland

    postal_codestringOptional

    ex: 94612

    regionstringOptional

    ex: California

    street_addressstringRequired

    ex: 1904 Franklin St

    or
    countrystringOptional

    ex: USA

    localitystringRequired

    ex: Oakland

    regionstringOptional

    ex: California

    or
    wkt_wkb_literalstringRequired
    or
    us_census_tract_2020stringRequired
    or
    us_cbsa_2020stringRequired
    or
    us_state_2020stringRequired
    or
    us_county_2020stringRequired
    or
    us_zip_code_2022stringRequired
    or
    eu_lau_2021stringRequired
    or
    eu_nuts_1_2021stringRequired
    or
    eu_nuts_2_2021stringRequired
    or
    eu_nuts_3_2021stringRequired
    or
    aus_postal_area_2021stringRequired
    or
    admin_0stringRequired
    or
    admin_1stringRequired
    or
    timezonestringRequired
    or
    h3stringRequired
    import_urlstringOptional

    A public URL containing geodata to import, in place of uploading a file.

    latnumberOptional

    (Image uploads only) The latitude of the image center.

    lngnumberOptional

    (Image uploads only) The longitude of the image center.

    attribution_textstring · nullableOptional
    attribution_urlstring · nullableOptional
    descriptionstring · nullableOptional
    licensestring · nullableOptional
    source_abbreviationstring · nullableOptional
    source_namestring · nullableOptional
    source_urlstring · nullableOptional
    updated_atstring · date · nullableOptionalExample: 2025-03-24
    namestringRequired

    The display name for the new layer.

    zoomnumberOptional

    (Image uploads only) The zoom level of the image.

    Responses
    chevron-right
    200

    Upload layer response

    application/json
    layer_group_idstring · felt_idOptionalExample: luCHyMruTQ6ozGk3gPJfEB
    layer_idstring · felt_idOptional

    The ID of the layer created by this upload. If multiple layers are included in the upload, this is the ID of the first layer in the layer group.

    Example: luCHyMruTQ6ozGk3gPJfEB
    presigned_attributesobject · nullableOptional

    If provided, the presigned attributes to attach to the post request

    typestring · enumOptionalPossible values:
    urlstring · nullableOptional

    If provided, the URL to post the file to

    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    Upload Anythingarrow-up-right
    from felt_python import (refresh_file_layer, refresh_url_layer)
    
    refresh_file_layer(map_id, layer_id, file_name="features.geojson")
    refresh_url_layer(map_id, layer_id)
    from felt_python import upload_file
    
    upload_file(map_id, file_name="features.geojson", layer_name="My new layer")
    <iframe src="https://felt.com/embed/map/{mapId}?token={token}"></iframe>
    connectionone ofOptional
    blob_storage_urlstringOptional

    ABS blob storage URL

    typestring · enumRequiredPossible values:
    or
    base64_encoded_service_accountstring · nullableOptional

    BigQuery credentials - Base 64 encoded Service account JSON

    datasetstring · nullableOptional

    BigQuery dataset

    projectstringOptional

    BigQuery project

    typestring · enumRequiredPossible values:
    or
    catalogstring · nullableOptional

    Databricks catalog

    http_pathstringOptional

    Databricks server HTTP path

    schemastring · nullableOptional

    Databricks schema

    server_hostnamestringOptional

    Databricks server hostname

    typestring · enumRequiredPossible values:
    or
    tokenstring · nullableOptional

    Feature Server token

    typestring · enumRequiredPossible values:
    urlstringOptional

    Feature Server URL

    or
    gs_uristringOptional

    GCS URI

    typestring · enumRequiredPossible values:
    or
    databasestringOptional

    MSSQL database name

    hoststringOptional

    MSSQL host

    passwordstringOptional

    MSSQL password

    portinteger · nullableOptional

    MSSQL port

    typestring · enumRequiredPossible values:
    userstringOptional

    MSSQL user name

    or
    databasestringOptional

    Postgres database name

    hoststringOptional

    Postgres host

    passwordstringOptional

    Postgres password

    portinteger · nullableOptional

    Postgres port

    schemastringOptional

    Postgres schema

    typestring · enumRequiredPossible values:
    userstringOptional

    Postgres user name

    or
    databasestringOptional

    Redshift database name

    hoststringOptional

    Redshift host

    passwordstringOptional

    Redshift password

    portinteger · nullableOptional

    Redshift port

    typestring · enumRequiredPossible values:
    userstringOptional

    Redshift user name

    or
    s3_uristringOptional

    S3 URI

    typestring · enumRequiredPossible values:
    or
    account_idstringOptional

    Snowflake account ID

    databasestringOptional

    Snowflake database name

    passwordstringOptional

    Snowflake password

    rolestring · nullableOptional

    Snowflake role

    schemastring · nullableOptional

    Snowflake database schema

    typestring · enumRequiredPossible values:
    userstringOptional

    Snowflake user name

    warehousestring · nullableOptional

    Snowflake warehouse

    or
    tokenstring · nullableOptional

    STAC token

    typestring · enumRequiredPossible values:
    urlstringOptional

    STAC server / asset URL

    or
    typestring · enumRequiredPossible values:
    urlstringOptional

    WFS URL

    or
    typestring · enumRequiredPossible values:
    urlstringOptional

    WMS/WMTS URL

    namestringOptional
    permissionsone ofOptional
    typestring · enumRequiredPossible values:
    or
    typestring · enumRequiredPossible values:
    or
    project_idsstring · felt_id[]RequiredExample: luCHyMruTQ6ozGk3gPJfEB
    typestring · enumRequiredPossible values:
    Responses
    chevron-right
    202

    Source reference

    application/json
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    connectionone ofRequired
    blob_storage_urlstringRequired

    ABS blob storage URL

    connection_stringstringRequired
    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    typestring · enumRequiredPossible values:
    or
    base64_encoded_service_accountstring · nullableOptional

    BigQuery credentials - Base 64 encoded Service account JSON

    datasetstring · nullableOptional

    BigQuery dataset

    projectstringRequired

    BigQuery project

    typestring · enumRequiredPossible values:
    or
    catalogstring · nullableOptional

    Databricks catalog

    credentialone ofRequired
    tokenstringRequired
    typestring · enumRequiredPossible values:
    or
    client_idstringRequired
    client_secretstringRequired
    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    http_pathstringRequired

    Databricks server HTTP path

    schemastring · nullableOptional

    Databricks schema

    server_hostnamestringRequired

    Databricks server hostname

    typestring · enumRequiredPossible values:
    or
    tokenstring · nullableOptional

    Feature Server token

    typestring · enumRequiredPossible values:
    urlstringRequired

    Feature Server URL

    or
    service_account_filenamestringRequired
    service_account_jsonone ofRequired
    objectOptional
    or
    stringOptional
    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    gs_uristringRequired

    GCS URI

    typestring · enumRequiredPossible values:
    or
    databasestringRequired

    MSSQL database name

    hoststringRequired

    MSSQL host

    passwordstringRequired

    MSSQL password

    portinteger · nullableOptional

    MSSQL port

    typestring · enumRequiredPossible values:
    userstringRequired

    MSSQL user name

    or
    databasestringRequired

    Postgres database name

    hoststringRequired

    Postgres host

    passwordstringRequired

    Postgres password

    portinteger · nullableOptional

    Postgres port

    schemastringOptional

    Postgres schema

    typestring · enumRequiredPossible values:
    userstringRequired

    Postgres user name

    or
    databasestringRequired

    Redshift database name

    hoststringRequired

    Redshift host

    passwordstringRequired

    Redshift password

    portinteger · nullableOptional

    Redshift port

    typestring · enumRequiredPossible values:
    userstringRequired

    Redshift user name

    or
    role_arnstringRequired
    role_session_namestringRequired
    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    s3_uristringRequired

    S3 URI

    typestring · enumRequiredPossible values:
    or
    account_idstringRequired

    Snowflake account ID

    credentialone ofRequired
    private_keystringRequired
    private_key_namestringRequired
    private_key_passphrasestringOptional
    typestring · enumRequiredPossible values:
    or
    tokenstringRequired
    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    databasestringRequired

    Snowflake database name

    passwordstringOptional

    Snowflake password

    rolestring · nullableOptional

    Snowflake role

    schemastring · nullableOptional

    Snowflake database schema

    typestring · enumRequiredPossible values:
    userstringRequired

    Snowflake user name

    warehousestring · nullableOptional

    Snowflake warehouse

    or
    credentialone ofRequired
    role_arnstringRequired
    role_session_namestringRequired
    typestring · enumRequiredPossible values:
    or
    connection_stringstringRequired
    typestring · enumRequiredPossible values:
    or
    service_account_filenamestringRequired
    service_account_jsonone ofRequired
    objectOptional
    or
    stringOptional
    typestring · enumRequiredPossible values:
    or
    namestringRequired

    The header name

    sensitivebooleanRequired

    Whether or not the header is sensitive. If it is marked as sensitive, then felt:redacted will be returned when viewing this header

    valuestringRequired

    The header value

    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    tokenstring · nullableOptional

    STAC token

    typestring · enumRequiredPossible values:
    urlstringRequired

    STAC server / asset URL

    or
    typestring · enumRequiredPossible values:
    urlstringRequired

    WFS URL

    or
    typestring · enumRequiredPossible values:
    urlstringRequired

    WMS/WMTS URL

    namestringRequired
    permissionsone ofOptional
    typestring · enumRequiredPossible values:
    or
    typestring · enumRequiredPossible values:
    or
    project_idsstring · felt_id[]RequiredExample: luCHyMruTQ6ozGk3gPJfEB
    typestring · enumRequiredPossible values:
    Responses
    chevron-right
    202

    Source reference

    application/json
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional

    No content

    credentialone ofRequired
    role_arnstringRequired
    role_session_namestringRequired
    typestring · enumRequiredPossible values:
    or
    connection_stringstringRequired
    typestring · enumRequiredPossible values:
    or
    namestringRequired

    The header name

    sensitivebooleanRequired

    Whether or not the header is sensitive. If it is marked as sensitive, then felt:redacted will be returned when viewing this header

    valuestringRequired

    The header value

    typestring · enumRequiredPossible values:
    or
    service_account_filenamestringRequired
    service_account_jsonone ofRequired
    objectOptional
    or
    stringOptional
    typestring · enumRequiredPossible values:
    or
    private_keystringRequired
    private_key_namestringRequired
    private_key_passphrasestringOptional
    typestring · enumRequiredPossible values:
    or
    tokenstringRequired
    typestring · enumRequiredPossible values:
    namestringRequired
    use_casestring · enumRequiredPossible values:
    Responses
    chevron-right
    202

    Source credential created

    application/json
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    credentialone ofOptional
    role_arnstringOptional
    role_session_namestringOptional
    typestring · enumRequiredPossible values:
    or
    connection_stringstringOptional
    typestring · enumRequiredPossible values:
    or
    namestringRequired

    The header name

    sensitivebooleanRequired

    Whether or not the header is sensitive. If it is marked as sensitive, then felt:redacted will be returned when viewing this header

    valuestringRequired

    The header value

    typestring · enumRequiredPossible values:
    or
    service_account_filenamestringOptional
    service_account_jsonone ofOptional
    objectOptional
    or
    stringOptional
    typestring · enumRequiredPossible values:
    or
    private_keystringOptional
    private_key_namestringOptional
    private_key_passphrasestringOptional
    typestring · enumRequiredPossible values:
    or
    tokenstringOptional
    typestring · enumRequiredPossible values:
    namestringOptional
    use_casestring · enumOptionalPossible values:
    Responses
    chevron-right
    202

    Source credential updated

    application/json
    chevron-right
    401

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    403

    UnauthorizedError

    application/json
    detailstringOptional
    headerstring · enumOptionalPossible values:
    titlestringOptional
    chevron-right
    404

    NotFoundError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional
    chevron-right
    422

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    429

    Unprocessable Entity

    application/json
    detailstringRequiredExample: null value where string expected
    pointerstringRequiredExample: /data/attributes/petName
    titlestringRequiredExample: Invalid value
    chevron-right
    500

    InternalServerError

    application/json
    detailstringOptional
    parameterstringOptional
    titlestringOptional

    No content

    POST /api/v2/maps/{map_id}/elements HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 165
    
    {
      "features": [
        {
          "geometry": {
            "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
            "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
          },
          "properties": {},
          "type": "Feature"
        }
      ],
      "type": "FeatureCollection"
    }
    {
      "features": [
        {
          "geometry": {
            "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
            "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
          },
          "properties": {},
          "type": "Feature"
        }
      ],
      "type": "FeatureCollection"
    }
    [
      {
        "color": "text",
        "elements": {
          "features": [
            {
              "geometry": {
                "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
              },
              "properties": {},
              "type": "Feature"
            }
          ],
          "type": "FeatureCollection"
        },
        "id": "text",
        "name": "text",
        "symbol": "text"
      }
    ]
    DELETE /api/v2/maps/{map_id}/elements/{element_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    GET /api/v2/maps/{map_id}/elements HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "features": [
        {
          "geometry": {
            "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
            "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
          },
          "properties": {},
          "type": "Feature"
        }
      ],
      "type": "FeatureCollection"
    }
    GET /api/v2/maps/{map_id}/element_groups/{group_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "features": [
        {
          "geometry": {
            "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
            "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
          },
          "properties": {},
          "type": "Feature"
        }
      ],
      "type": "FeatureCollection"
    }
    GET /api/v2/maps/{map_id}/element_groups HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    [
      {
        "color": "text",
        "elements": {
          "features": [
            {
              "geometry": {
                "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
              },
              "properties": {},
              "type": "Feature"
            }
          ],
          "type": "FeatureCollection"
        },
        "id": "text",
        "name": "text",
        "symbol": "text"
      }
    ]
    POST /api/v2/maps/{map_id}/element_groups HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 92
    
    [
      {
        "color": "#C93535",
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "name": "My Element Group",
        "symbol": "dot"
      }
    ]
    {
      "attributes": [
        {
          "name": "text",
          "type": "INTEGER"
        }
      ],
      "caption": "text",
      "geometry_type": "Line",
      "hide_from_legend": true,
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "is_spreadsheet": true,
      "legend_display": "default",
      "legend_visibility": "hide",
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
      },
      "metadata": {
        "attribution_text": "text",
        "attribution_url": "text",
        "description": "text",
        "license": "text",
        "source_abbreviation": "text",
        "source_name": "text",
        "source_url": "text",
        "updated_at": "2025-03-24"
      },
      "name": "text",
      "ordering_key": 1,
      "progress": 1,
      "refresh_period": "15 min",
      "status": "uploading",
      "style": {},
      "tile_url": "text",
      "type": "layer"
    }
    {
      "caption": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "legend_visibility": "hide",
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
      },
      "name": "text",
      "ordering_key": 1,
      "type": "layer_group",
      "visibility_interaction": "default"
    }
    {
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "type": "layer_library"
    }
    POST /api/v2/maps/{map_id}/layers/{layer_id}/publish HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 19
    
    {
      "name": "My Layer"
    }
    POST /api/v2/maps/{map_id}/layer_groups/{layer_group_id}/publish HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 19
    
    {
      "name": "My Layer"
    }
    GET /api/v2/library HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    []
    GET /api/v2/maps/{map_id}/comments/export HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    POST /api/v2/maps/{map_id}/comments/{comment_id}/resolve HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "comment_id": "luCHyMruTQ6ozGk3gPJfEB"
    }
    DELETE /api/v2/maps/{map_id}/comments/{comment_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    GET /api/v2/user HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "email": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "name": "text"
    }
    {
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "maps": [
        {
          "created_at": "2024-05-25T15:51:34",
          "folder_id": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
          },
          "project_id": "text",
          "public_access": "private",
          "thumbnail_url": "text",
          "title": "text",
          "type": "map_reference",
          "url": "text",
          "visited_at": "text"
        }
      ],
      "max_inherited_permission": "view_only",
      "name": "text",
      "type": "project",
      "visibility": "workspace"
    }
    {
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "maps": [
        {
          "created_at": "2024-05-25T15:51:34",
          "folder_id": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
          },
          "project_id": "text",
          "public_access": "private",
          "thumbnail_url": "text",
          "title": "text",
          "type": "map_reference",
          "url": "text",
          "visited_at": "text"
        }
      ],
      "max_inherited_permission": "view_only",
      "name": "text",
      "type": "project",
      "visibility": "workspace"
    }
    GET /api/v2/projects HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    [
      {
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "links": {
          "self": "https://felt.com/api/v2/projects/V0dnOMOuTd9B9BOsL9C0UjmqC"
        },
        "max_inherited_permission": "view_only",
        "name": "text",
        "type": "project_reference",
        "visibility": "workspace"
      }
    ]
    POST /api/v2/projects HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 79
    
    {
      "max_inherited_permission": "view_only",
      "name": "text",
      "visibility": "workspace"
    }
    GET /api/v2/projects/{project_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "maps": [
        {
          "created_at": "2024-05-25T15:51:34",
          "folder_id": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
          },
          "project_id": "text",
          "public_access": "private",
          "thumbnail_url": "text",
          "title": "text",
          "type": "map_reference",
          "url": "text",
          "visited_at": "text"
        }
      ],
      "max_inherited_permission": "view_only",
      "name": "text",
      "type": "project",
      "visibility": "workspace"
    }
    DELETE /api/v2/projects/{project_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    POST /api/v2/projects/{project_id}/update HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 79
    
    {
      "max_inherited_permission": "view_only",
      "name": "text",
      "visibility": "workspace"
    }
    {
      "caption": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "legend_visibility": "hide",
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
      },
      "name": "text",
      "ordering_key": 1,
      "type": "layer_group",
      "visibility_interaction": "default"
    }
    [
      {
        "attributes": [
          {
            "name": "text",
            "type": "INTEGER"
          }
        ],
        "caption": "text",
        "geometry_type": "Line",
        "hide_from_legend": true,
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "is_spreadsheet": true,
        "legend_display": "default",
        "legend_visibility": "hide",
        "links": {
          "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
        },
        "metadata": {
          "attribution_text": "text",
          "attribution_url": "text",
          "description": "text",
          "license": "text",
          "source_abbreviation": "text",
          "source_name": "text",
          "source_url": "text",
          "updated_at": "2025-03-24"
        },
        "name": "text",
        "ordering_key": 1,
        "progress": 1,
        "refresh_period": "15 min",
        "status": "uploading",
        "style": {},
        "tile_url": "text",
        "type": "layer"
      }
    ]
    [
      {
        "caption": "text",
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "layers": [
          {
            "attributes": [
              {
                "name": "text",
                "type": "INTEGER"
              }
            ],
            "caption": "text",
            "geometry_type": "Line",
            "hide_from_legend": true,
            "id": "luCHyMruTQ6ozGk3gPJfEB",
            "is_spreadsheet": true,
            "legend_display": "default",
            "legend_visibility": "hide",
            "links": {
              "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
            },
            "metadata": {
              "attribution_text": "text",
              "attribution_url": "text",
              "description": "text",
              "license": "text",
              "source_abbreviation": "text",
              "source_name": "text",
              "source_url": "text",
              "updated_at": "2025-03-24"
            },
            "name": "text",
            "ordering_key": 1,
            "progress": 1,
            "refresh_period": "15 min",
            "status": "uploading",
            "style": {},
            "tile_url": "text",
            "type": "layer"
          }
        ],
        "legend_visibility": "hide",
        "links": {
          "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
        },
        "name": "text",
        "ordering_key": 1,
        "type": "layer_group",
        "visibility_interaction": "default"
      }
    ]
    {
      "attributes": [
        {
          "name": "text",
          "type": "INTEGER"
        }
      ],
      "caption": "text",
      "geometry_type": "Line",
      "hide_from_legend": true,
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "is_spreadsheet": true,
      "legend_display": "default",
      "legend_visibility": "hide",
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
      },
      "metadata": {
        "attribution_text": "text",
        "attribution_url": "text",
        "description": "text",
        "license": "text",
        "source_abbreviation": "text",
        "source_name": "text",
        "source_url": "text",
        "updated_at": "2025-03-24"
      },
      "name": "text",
      "ordering_key": 1,
      "progress": 1,
      "refresh_period": "15 min",
      "status": "uploading",
      "style": {},
      "tile_url": "text",
      "type": "layer"
    }
    {
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ]
    }
    GET /api/v2/maps/{map_id}/layer_groups/{layer_group_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "caption": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "legend_visibility": "hide",
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
      },
      "name": "text",
      "ordering_key": 1,
      "type": "layer_group",
      "visibility_interaction": "default"
    }
    POST /api/v2/maps/{map_id}/layer_groups/{layer_group_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 171
    
    {
      "caption": "A very interesting group",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "legend_visibility": "hide",
      "name": "My Layer Group",
      "ordering_key": 1,
      "visibility_interaction": "default"
    }
    DELETE /api/v2/maps/{map_id}/layer_groups/{layer_group_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    GET /api/v2/maps/{map_id}/layers HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    [
      {
        "attributes": [
          {
            "name": "text",
            "type": "INTEGER"
          }
        ],
        "caption": "text",
        "geometry_type": "Line",
        "hide_from_legend": true,
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "is_spreadsheet": true,
        "legend_display": "default",
        "legend_visibility": "hide",
        "links": {
          "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
        },
        "metadata": {
          "attribution_text": "text",
          "attribution_url": "text",
          "description": "text",
          "license": "text",
          "source_abbreviation": "text",
          "source_name": "text",
          "source_url": "text",
          "updated_at": "2025-03-24"
        },
        "name": "text",
        "ordering_key": 1,
        "progress": 1,
        "refresh_period": "15 min",
        "status": "uploading",
        "style": {},
        "tile_url": "text",
        "type": "layer"
      }
    ]
    POST /api/v2/maps/{map_id}/layers HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 427
    
    [
      {
        "caption": "A very interesting dataset",
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "layer_group_id": "luCHyMruTQ6ozGk3gPJfEB",
        "legend_display": "default",
        "legend_visibility": "hide",
        "metadata": {
          "attribution_text": "text",
          "attribution_url": "text",
          "description": "text",
          "license": "text",
          "source_abbreviation": "text",
          "source_name": "text",
          "source_url": "text",
          "updated_at": "2025-03-24"
        },
        "name": "My Layer",
        "ordering_key": 1,
        "refresh_period": "15 min"
      }
    ]
    GET /api/v2/maps/{map_id}/layer_groups HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    [
      {
        "caption": "text",
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "layers": [
          {
            "attributes": [
              {
                "name": "text",
                "type": "INTEGER"
              }
            ],
            "caption": "text",
            "geometry_type": "Line",
            "hide_from_legend": true,
            "id": "luCHyMruTQ6ozGk3gPJfEB",
            "is_spreadsheet": true,
            "legend_display": "default",
            "legend_visibility": "hide",
            "links": {
              "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
            },
            "metadata": {
              "attribution_text": "text",
              "attribution_url": "text",
              "description": "text",
              "license": "text",
              "source_abbreviation": "text",
              "source_name": "text",
              "source_url": "text",
              "updated_at": "2025-03-24"
            },
            "name": "text",
            "ordering_key": 1,
            "progress": 1,
            "refresh_period": "15 min",
            "status": "uploading",
            "style": {},
            "tile_url": "text",
            "type": "layer"
          }
        ],
        "legend_visibility": "hide",
        "links": {
          "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
        },
        "name": "text",
        "ordering_key": 1,
        "type": "layer_group",
        "visibility_interaction": "default"
      }
    ]
    POST /api/v2/maps/{map_id}/layer_groups HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 173
    
    [
      {
        "caption": "A very interesting group",
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "legend_visibility": "hide",
        "name": "My Layer Group",
        "ordering_key": 1,
        "visibility_interaction": "default"
      }
    ]
    POST /api/v2/maps/{map_id}/layers/{layer_id}/update_style HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 12
    
    {
      "style": {}
    }
    GET /api/v2/maps/{map_id}/layers/{layer_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "attributes": [
        {
          "name": "text",
          "type": "INTEGER"
        }
      ],
      "caption": "text",
      "geometry_type": "Line",
      "hide_from_legend": true,
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "is_spreadsheet": true,
      "legend_display": "default",
      "legend_visibility": "hide",
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
      },
      "metadata": {
        "attribution_text": "text",
        "attribution_url": "text",
        "description": "text",
        "license": "text",
        "source_abbreviation": "text",
        "source_name": "text",
        "source_url": "text",
        "updated_at": "2025-03-24"
      },
      "name": "text",
      "ordering_key": 1,
      "progress": 1,
      "refresh_period": "15 min",
      "status": "uploading",
      "style": {},
      "tile_url": "text",
      "type": "layer"
    }
    DELETE /api/v2/maps/{map_id}/layers/{layer_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    POST /api/v2/duplicate_layers HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 92
    
    [
      {
        "destination_map_id": "luCHyMruTQ6ozGk3gPJfEB",
        "source_layer_id": "luCHyMruTQ6ozGk3gPJfEB"
      }
    ]
    {
      "basemap": "text",
      "created_at": "2024-05-25T15:51:34",
      "element_groups": [
        {
          "elements": {
            "features": [
              {
                "geometry": {
                  "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                  "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
                },
                "properties": {},
                "type": "Feature"
              }
            ],
            "type": "FeatureCollection"
          },
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "name": "text"
        }
      ],
      "elements": {
        "features": [
          {
            "geometry": {
              "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
              "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
            },
            "properties": {},
            "type": "Feature"
          }
        ],
        "type": "FeatureCollection"
      },
      "folder_id": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "project_id": "text",
      "public_access": "private",
      "table_settings": {
        "default_table_layer_id": "luCHyMruTQ6ozGk3gPJfEB",
        "viewers_can_open_table": true
      },
      "thumbnail_url": "text",
      "title": "text",
      "type": "map",
      "url": "text",
      "viewer_permissions": {
        "can_duplicate_map": true,
        "can_export_data": true,
        "can_see_map_presence": true
      },
      "visited_at": "text"
    }
    {
      "basemap": "text",
      "created_at": "2024-05-25T15:51:34",
      "element_groups": [
        {
          "elements": {
            "features": [
              {
                "geometry": {
                  "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                  "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
                },
                "properties": {},
                "type": "Feature"
              }
            ],
            "type": "FeatureCollection"
          },
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "name": "text"
        }
      ],
      "elements": {
        "features": [
          {
            "geometry": {
              "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
              "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
            },
            "properties": {},
            "type": "Feature"
          }
        ],
        "type": "FeatureCollection"
      },
      "folder_id": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "project_id": "text",
      "public_access": "private",
      "table_settings": {
        "default_table_layer_id": "luCHyMruTQ6ozGk3gPJfEB",
        "viewers_can_open_table": true
      },
      "thumbnail_url": "text",
      "title": "text",
      "type": "map",
      "url": "text",
      "viewer_permissions": {
        "can_duplicate_map": true,
        "can_export_data": true,
        "can_see_map_presence": true
      },
      "visited_at": "text"
    }
    POST /api/v2/maps HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 149
    
    {
      "basemap": "text",
      "description": "text",
      "lat": 1,
      "layer_urls": [
        "text"
      ],
      "lon": 1,
      "public_access": "private",
      "title": "text",
      "workspace_id": "text",
      "zoom": 1
    }
    {
      "basemap": "text",
      "created_at": "2024-05-25T15:51:34",
      "element_groups": [
        {
          "elements": {
            "features": [
              {
                "geometry": {
                  "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                  "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
                },
                "properties": {},
                "type": "Feature"
              }
            ],
            "type": "FeatureCollection"
          },
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "name": "text"
        }
      ],
      "elements": {
        "features": [
          {
            "geometry": {
              "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
              "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
            },
            "properties": {},
            "type": "Feature"
          }
        ],
        "type": "FeatureCollection"
      },
      "folder_id": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "project_id": "text",
      "public_access": "private",
      "table_settings": {
        "default_table_layer_id": "luCHyMruTQ6ozGk3gPJfEB",
        "viewers_can_open_table": true
      },
      "thumbnail_url": "text",
      "title": "text",
      "type": "map",
      "url": "text",
      "viewer_permissions": {
        "can_duplicate_map": true,
        "can_export_data": true,
        "can_see_map_presence": true
      },
      "visited_at": "text"
    }
    {
      "basemap": "text",
      "created_at": "2024-05-25T15:51:34",
      "element_groups": [
        {
          "elements": {
            "features": [
              {
                "geometry": {
                  "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                  "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
                },
                "properties": {},
                "type": "Feature"
              }
            ],
            "type": "FeatureCollection"
          },
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "name": "text"
        }
      ],
      "elements": {
        "features": [
          {
            "geometry": {
              "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
              "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
            },
            "properties": {},
            "type": "Feature"
          }
        ],
        "type": "FeatureCollection"
      },
      "folder_id": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "project_id": "text",
      "public_access": "private",
      "table_settings": {
        "default_table_layer_id": "luCHyMruTQ6ozGk3gPJfEB",
        "viewers_can_open_table": true
      },
      "thumbnail_url": "text",
      "title": "text",
      "type": "map",
      "url": "text",
      "viewer_permissions": {
        "can_duplicate_map": true,
        "can_export_data": true,
        "can_see_map_presence": true
      },
      "visited_at": "text"
    }
    POST /api/v2/maps/{map_id}/move HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 39
    
    {
      "project_id": "luCHyMruTQ6ozGk3gPJfEB"
    }
    POST /api/v2/maps/{map_id}/duplicate HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 70
    
    {
      "destination": {
        "project_id": "luCHyMruTQ6ozGk3gPJfEB"
      },
      "title": "text"
    }
    POST /api/v2/maps/{map_id}/update HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 278
    
    {
      "basemap": "text",
      "description": "text",
      "public_access": "private",
      "table_settings": {
        "default_table_layer_id": "luCHyMruTQ6ozGk3gPJfEB",
        "viewers_can_open_table": true
      },
      "title": "text",
      "viewer_permissions": {
        "can_duplicate_map": true,
        "can_export_data": true,
        "can_see_map_presence": true
      }
    }
    GET /api/v2/maps/{map_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "basemap": "text",
      "created_at": "2024-05-25T15:51:34",
      "element_groups": [
        {
          "elements": {
            "features": [
              {
                "geometry": {
                  "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
                  "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
                },
                "properties": {},
                "type": "Feature"
              }
            ],
            "type": "FeatureCollection"
          },
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "name": "text"
        }
      ],
      "elements": {
        "features": [
          {
            "geometry": {
              "felt:id": "luCHyMruTQ6ozGk3gPJfEB",
              "felt:parentId": "luCHyMruTQ6ozGk3gPJfEB"
            },
            "properties": {},
            "type": "Feature"
          }
        ],
        "type": "FeatureCollection"
      },
      "folder_id": "text",
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_groups": [
        {
          "caption": "text",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "layers": [
            {
              "attributes": [
                {
                  "name": "text",
                  "type": "INTEGER"
                }
              ],
              "caption": "text",
              "geometry_type": "Line",
              "hide_from_legend": true,
              "id": "luCHyMruTQ6ozGk3gPJfEB",
              "is_spreadsheet": true,
              "legend_display": "default",
              "legend_visibility": "hide",
              "links": {
                "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
              },
              "metadata": {
                "attribution_text": "text",
                "attribution_url": "text",
                "description": "text",
                "license": "text",
                "source_abbreviation": "text",
                "source_name": "text",
                "source_url": "text",
                "updated_at": "2025-03-24"
              },
              "name": "text",
              "ordering_key": 1,
              "progress": 1,
              "refresh_period": "15 min",
              "status": "uploading",
              "style": {},
              "tile_url": "text",
              "type": "layer"
            }
          ],
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/v13k4Ae9BRjCHHdPP5Fcm6D"
          },
          "name": "text",
          "ordering_key": 1,
          "type": "layer_group",
          "visibility_interaction": "default"
        }
      ],
      "layers": [
        {
          "attributes": [
            {
              "name": "text",
              "type": "INTEGER"
            }
          ],
          "caption": "text",
          "geometry_type": "Line",
          "hide_from_legend": true,
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "is_spreadsheet": true,
          "legend_display": "default",
          "legend_visibility": "hide",
          "links": {
            "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layers/k441enUxQUOnZqc1ZvNsDA"
          },
          "metadata": {
            "attribution_text": "text",
            "attribution_url": "text",
            "description": "text",
            "license": "text",
            "source_abbreviation": "text",
            "source_name": "text",
            "source_url": "text",
            "updated_at": "2025-03-24"
          },
          "name": "text",
          "ordering_key": 1,
          "progress": 1,
          "refresh_period": "15 min",
          "status": "uploading",
          "style": {},
          "tile_url": "text",
          "type": "layer"
        }
      ],
      "links": {
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "project_id": "text",
      "public_access": "private",
      "table_settings": {
        "default_table_layer_id": "luCHyMruTQ6ozGk3gPJfEB",
        "viewers_can_open_table": true
      },
      "thumbnail_url": "text",
      "title": "text",
      "type": "map",
      "url": "text",
      "viewer_permissions": {
        "can_duplicate_map": true,
        "can_export_data": true,
        "can_see_map_presence": true
      },
      "visited_at": "text"
    }
    DELETE /api/v2/maps/{map_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "export_link": "text"
    }
    {
      "download_url": "https://us1.data-pipeline.felt.com/fcdfd96c-06fa-40b9-9ae9-ad034b5a66df/Felt-Export.zip",
      "export_id": "FZWQjWZJSZWvW3yn9BeV9AyA",
      "filters": [],
      "status": "completed"
    }
    POST /api/v2/maps/{map_id}/layers/{layer_id}/custom_export HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 63
    
    {
      "email_on_completion": true,
      "filters": [],
      "output_format": "csv"
    }
    {
      "export_request_id": "luCHyMruTQ6ozGk3gPJfEB",
      "poll_endpoint": "http://felt.com/api/v2/maps/vAbZ5eKqRoGe4sCH8nHW8D/layers/7kF9Cfz45TUWIiuuWV8uZ7A/custom_exports/auFxn9BO4RrGGiKrGfaS7ZB"
    }
    GET /api/v2/maps/{map_id}/layers/{layer_id}/get_export_link HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    GET /api/v2/maps/{map_id}/layers/{layer_id}/custom_exports/{export_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "links": {
        "layer_group": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC/layer_groups/KFFhKAbvS4anD3wxtwNEpD",
        "self": "https://felt.com/api/v2/maps/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "status": "accepted"
    }
    {
      "layer_group_id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_id": "luCHyMruTQ6ozGk3gPJfEB",
      "presigned_attributes": {},
      "type": "upload_response",
      "url": "text"
    }
    POST /api/v2/maps/{map_id}/upload HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 311
    
    {
      "hints": [
        {
          "attributes": {
            "lat": "text",
            "lng": "text"
          }
        }
      ],
      "import_url": "text",
      "lat": 1,
      "lng": 1,
      "metadata": {
        "attribution_text": "text",
        "attribution_url": "text",
        "description": "text",
        "license": "text",
        "source_abbreviation": "text",
        "source_name": "text",
        "source_url": "text",
        "updated_at": "2025-03-24"
      },
      "name": "text",
      "zoom": 1
    }
    {
      "layer_group_id": "luCHyMruTQ6ozGk3gPJfEB",
      "layer_id": "luCHyMruTQ6ozGk3gPJfEB",
      "presigned_attributes": {},
      "type": "upload_response",
      "url": "text"
    }
    POST /api/v2/maps/{map_id}/add_source_layer HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 56
    
    {
      "dataset_id": "luCHyMruTQ6ozGk3gPJfEB",
      "from": "dataset"
    }
    POST /api/v2/maps/{map_id}/layers/{layer_id}/refresh HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "expires_at": "2024-05-25T15:51:34",
      "token": "text"
    }
    POST /api/v2/maps/{map_id}/embed_token?user_email=text HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    POST /api/v2/sources/{source_id}/update HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 119
    
    {
      "connection": {
        "blob_storage_url": "text",
        "type": "abs_bucket"
      },
      "name": "text",
      "permissions": {
        "type": "workspace_editors"
      }
    }
    {
      "automatic_sync": "enabled",
      "connection_type": "abs_bucket",
      "created_at": 1,
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "last_synced_at": 1,
      "links": {
        "self": "https://felt.com/api/v2/sources/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "name": "text",
      "owner_id": "luCHyMruTQ6ozGk3gPJfEB",
      "permissions": {
        "type": "workspace_editors"
      },
      "sync_status": "syncing",
      "type": "source_reference",
      "updated_at": 1,
      "workspace_id": "luCHyMruTQ6ozGk3gPJfEB"
    }
    {
      "automatic_sync": "enabled",
      "connection_type": "abs_bucket",
      "created_at": 1,
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "last_synced_at": 1,
      "links": {
        "self": "https://felt.com/api/v2/sources/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "name": "text",
      "owner_id": "luCHyMruTQ6ozGk3gPJfEB",
      "permissions": {
        "type": "workspace_editors"
      },
      "sync_status": "syncing",
      "type": "source_reference",
      "updated_at": 1,
      "workspace_id": "luCHyMruTQ6ozGk3gPJfEB"
    }
    {
      "automatic_sync": "enabled",
      "connection_type": "abs_bucket",
      "created_at": 1,
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "last_synced_at": 1,
      "links": {
        "self": "https://felt.com/api/v2/sources/V0dnOMOuTd9B9BOsL9C0UjmqC"
      },
      "name": "text",
      "owner_id": "luCHyMruTQ6ozGk3gPJfEB",
      "permissions": {
        "type": "workspace_editors"
      },
      "sync_status": "syncing",
      "type": "source_reference",
      "updated_at": 1,
      "workspace_id": "luCHyMruTQ6ozGk3gPJfEB"
    }
    POST /api/v2/sources/{source_id}/credentials HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 137
    
    {
      "credential": {
        "role_arn": "text",
        "role_session_name": "text",
        "type": "aws_assume_role"
      },
      "name": "text",
      "use_case": "stac_api_authentication"
    }
    {
      "created_at": 1,
      "credential": {
        "role_arn": "text",
        "role_session_name": "text",
        "type": "aws_assume_role"
      },
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "name": "text",
      "source_id": "luCHyMruTQ6ozGk3gPJfEB",
      "updated_at": 1,
      "use_case": "stac_api_authentication"
    }
    {
      "created_at": 1,
      "credential": {
        "role_arn": "text",
        "role_session_name": "text",
        "type": "aws_assume_role"
      },
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "name": "text",
      "source_id": "luCHyMruTQ6ozGk3gPJfEB",
      "updated_at": 1,
      "use_case": "stac_api_authentication"
    }
    GET /api/v2/sources HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    [
      {
        "automatic_sync": "enabled",
        "connection_type": "abs_bucket",
        "created_at": 1,
        "id": "luCHyMruTQ6ozGk3gPJfEB",
        "last_synced_at": 1,
        "links": {
          "self": "https://felt.com/api/v2/sources/V0dnOMOuTd9B9BOsL9C0UjmqC"
        },
        "name": "text",
        "owner_id": "luCHyMruTQ6ozGk3gPJfEB",
        "permissions": {
          "type": "workspace_editors"
        },
        "sync_status": "syncing",
        "type": "source_reference",
        "updated_at": 1,
        "workspace_id": "luCHyMruTQ6ozGk3gPJfEB"
      }
    ]
    POST /api/v2/sources/{source_id}/sync HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    GET /api/v2/sources/{source_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    {
      "automatic_sync": "enabled",
      "connection": {
        "blob_storage_url": "text",
        "credentials": [
          {
            "created_at": 1,
            "credential": {
              "connection_string": "text",
              "type": "azure_storage_connection_string"
            },
            "id": "luCHyMruTQ6ozGk3gPJfEB",
            "name": "text",
            "source_id": "luCHyMruTQ6ozGk3gPJfEB",
            "updated_at": 1,
            "use_case": "source_authentication"
          }
        ],
        "type": "abs_bucket"
      },
      "created_at": 1,
      "datasets": [
        {
          "created_at": 1,
          "description": "text",
          "geometry_type": "polygon",
          "id": "luCHyMruTQ6ozGk3gPJfEB",
          "inspection_status": "completed",
          "name": "text",
          "type": "dataset",
          "updated_at": 1
        }
      ],
      "id": "luCHyMruTQ6ozGk3gPJfEB",
      "last_synced_at": 1,
      "name": "text",
      "owner_id": "luCHyMruTQ6ozGk3gPJfEB",
      "permissions": {
        "type": "workspace_editors"
      },
      "sync_status": "syncing",
      "type": "source",
      "updated_at": 1,
      "workspace_id": "luCHyMruTQ6ozGk3gPJfEB"
    }
    DELETE /api/v2/sources/{source_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    DELETE /api/v2/sources/{source_id}/credentials/{credential_id} HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Accept: */*
    
    POST /api/v2/sources HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 269
    
    {
      "connection": {
        "blob_storage_url": "text",
        "credentials": [
          {
            "credential": {
              "connection_string": "text",
              "type": "azure_storage_connection_string"
            },
            "name": "text",
            "use_case": "source_authentication"
          }
        ],
        "type": "abs_bucket"
      },
      "name": "text",
      "permissions": {
        "type": "workspace_editors"
      }
    }
    POST /api/v2/sources/{source_id}/credentials/{credential_id}/update HTTP/1.1
    Host: felt.com
    Authorization: Bearer YOUR_SECRET_TOKEN
    Content-Type: application/json
    Accept: */*
    Content-Length: 137
    
    {
      "credential": {
        "role_arn": "text",
        "role_session_name": "text",
        "type": "aws_assume_role"
      },
      "name": "text",
      "use_case": "stac_api_authentication"
    }