Build maps into your product, at a price that scales with you

Today, alongside our new plans, we’re introducing new pricing for developers building on Felt, designed to make it easy to try and predictable to scale.
It starts with Platform, the add-on for the JavaScript SDK and authenticated embeds. Platform is free for your first three months on any paid plan, so you can run a real pilot with your own data and customers before it costs anything. After that, it’s $1,000 a month on annual billing. Your end users don’t need seats, and you never pay per user, even for private maps behind your own login. As your product grows, your customers never add to the bill; only usage does, at published rates.
Teams use Platform for things like a client portal where each client sees maps from their own tables in Postgres or Snowflake, or a risk-analytics product that maps each customer’s sites against flood and wildfire layers. You sell your product, and Felt runs the maps inside it.
The map is the easy part
Most map features start the same way. Someone adds MapLibre to the app, points it at a GeoJSON file, and has a working map by the afternoon. It looks like the hard part is done.
Then the real requirements show up. The dataset is too big to load as GeoJSON, so you need a tiling pipeline, and it has to rebuild whenever the data changes. Users want a legend that matches the styling, and the analyst who owns the data wants to change a color without filing a ticket. Every layer needs a popup. Each client should see only their own data, which means scoping every map and tile request to the logged-in client, alongside the permissions you already have. Then someone asks for editing, then field capture, then a dashboard that stays in sync with the map.
None of these is hard on its own. Together, they turn an afternoon’s map into months of work, and once it ships, someone has to own it. That cost almost never makes it into the original estimate.
What Felt runs for you
Felt handles everything under the map and keeps it running. We render maps with MapLibre and maintain Tippecanoe, the open-source tiler, so we know this stack well.
Here’s how that list of requirements compares:
| Layer | If you build it | On Felt |
|---|---|---|
| Tiling | Tippecanoe or ST_AsMVT, a tile server, a CDN, and a rebuild every time the data changes | Upload a file or connect a table. Felt tiles it, and re-tiles on every refresh |
| Data refresh | A job per source with retries, credentials, and schema drift | Connect a source once. It refreshes daily, hourly, or every 15 minutes, depending on plan |
| Styling and legends | A style spec, a legend component, and a way for someone who isn’t you to change a color | Style in the editor or in code. Legends come with the map |
| Auth and permissions | Scoping every map and tile request to the logged-in client, and a second user model next to yours | Authenticated embeds use your login. Your customers need no Felt account and no seat |
| Interaction | Hit-testing, hover and selection state, and a popup for every layer | Configurable or custom HTML popups, and selection events in the SDK |
| Editing and field capture | Geometry editing, validation, photo uploads, offline queues, and conflict handling | Edit features and attributes. Field forms with photos, offline on Business and up |
| Dashboards and SQL | Charts, filters, and time sliders wired to the map’s data and kept in sync | Dashboards and SQL on the data already on the map, on Business and up |
| Upkeep | Uptime, upgrades, basemaps, browser quirks, and the one engineer who knows how it works | Ours. SOC 2 Type II, with an SLA on Enterprise |
Upload files up to 100 GB, or connect the data where it already lives: Google Sheets, Airtable, and ArcGIS on any paid plan, and Postgres, Snowflake, BigQuery, Databricks, SQL Server, or a cloud bucket on Business and Enterprise plans.
Connecting a warehouse takes two calls to the REST API: create the source once, wait for Felt to read it, then put a query on a map. The query runs in your warehouse, so it can be anything from a simple SELECT to a full analysis that uses everything your database can do. This one is a spatial join: it finds the California projects within 5 km of a 230 kV substation and labels each with the nearest one.
# Connect Snowflake once, then map a spatial query from it
import os, time, requests
felt = requests.Session()
felt.headers["Authorization"] = f"Bearer {os.environ['FELT_API_TOKEN']}"
api = "https://felt.com/api/v2"
map_id = "YOUR_MAP_ID" # the map that shows the query
source = felt.post(f"{api}/sources", json={
"name": "Interconnection queue",
"connection": {
"type": "snowflake",
"account_id": "acme-xy12345",
"database": "SITING",
"warehouse": "ANALYTICS_WH",
"user": "FELT_READER",
"credentials": [{
"name": "Felt reader",
"use_case": "source_authentication",
"credential": {"type": "snowflake_pat", "token": os.environ["SNOWFLAKE_PAT"]},
}],
},
}).json()
# Felt connects and reads the schema in the background
while felt.get(f"{api}/sources/{source['id']}").json()["sync_status"] == "syncing":
time.sleep(5)
felt.post(f"{api}/maps/{map_id}/add_source_layer", json={
"from": "sql",
"source_id": source["id"],
"query": """
SELECT q.project_id, q.status, q.capacity_mw, q.geom,
s.name AS nearest_substation,
ROUND(ST_DISTANCE(q.geom, s.geom) / 1000, 1) AS km_to_substation
FROM queue q
JOIN substations s ON ST_DWITHIN(q.geom, s.geom, 5000)
WHERE q.state = 'CA' AND s.voltage_kv >= 230
QUALIFY ROW_NUMBER() OVER (
PARTITION BY q.project_id ORDER BY ST_DISTANCE(q.geom, s.geom)
) = 1
""",
})
Authenticated embeds put a private map behind your own login. Your backend generates a token and the map loads in an iframe, so customers only ever log in to your app. You don’t need to provision Felt accounts, sync your users table with ours, or maintain a second set of permissions. Public embeds come with Team and above, and Platform covers the authenticated ones.
On your page it’s one call. Your server mints the token for the logged-in user, as the authenticated embeds guide shows, and the map loads with your styling, legend, and popups.
// page.ts: embed the map for the logged-in user
import { Felt } from "@feltmaps/js-sdk";
const { mapId, token } = await fetch("/api/felt-token").then((r) => r.json());
const felt = await Felt.embed(document.getElementById("map"), mapId, { token });
// The full SDK is available: listen to events and control the map.
felt.onSelectionChange({
handler: ({ selection }) => showDetailsInMyApp(selection),
});
Once the map is in your product, analysts can restyle layers, edit popups, and update data in Felt, and those changes show up without a deploy.
A natural fit for coding agents
More and more software gets written alongside a coding agent like Claude Code or Codex, and Felt fits that way of working. Business and Enterprise include an MCP server, so your agent can read and work with your Felt maps and data directly, in the same session where it’s writing your app.
In Claude Code, connecting is one line, and the MCP guide covers Claude, Cursor, and VS Code:
claude mcp add --transport http felt https://felt.com/mcp
The pairing is fast because of what the agent doesn’t have to write. There’s no tiling pipeline, sync job, or permissions layer to generate, since Felt already runs those. What’s left is the part that’s specific to your product: the page around the map, the endpoint that mints tokens for authenticated embeds, and the handlers for map events. That’s a small, well-defined amount of code, which is where coding agents do their best work. A team can have a working embedded map within a day, then spend the rest of its time on what makes the product different.
It works inside Felt, too. Describe a tool you need, and Felt AI writes it as an extension. The SDK, the REST API, and the felt-python library are all documented publicly, so your agent can read the same docs you would.
Start with a three-month pilot
A seven-day trial, free with a business email and no credit card, will tell you whether Felt fits. But a week isn’t long enough to ship something to customers and learn from it, so when you move to a paid plan, Platform is free for the first three months.
On monthly billing, a pilot on Business costs $749 a month for those three months. Business includes the REST API, webhooks, a database connection, and five seats. If you can do without those, Team is $249 a month. Monthly plans can be canceled anytime, so you don’t have to commit to a year until you’ve seen how customers use what you built.
Yes, the pricing really is that simple
If you’ve priced maps before, you’ve probably learned to read the fine print. Some platforms meter map loads, tile requests, geocoding, and monthly active users separately. Uploading one dataset can mean a charge for the upload, a processing charge you can’t know until the job runs, and a monthly fee to keep the tiles hosted. Some business uses, like analytics or internal tools, need a separate commercial license whose price isn’t on the pricing page. Enterprise GIS vendors sell OEM contracts that get renegotiated at renewal, and charge every month just to store your data.
In production, most teams run on Business and Platform, at $1,599 a month on annual billing. The rest of the bill consists of configurable add-ons: any extra seats, $5 per GB of processing, and $5 per 1,000 map views beyond what your plan includes. Storage and geocoding are included in every plan. Your customers are free, however many you add. Commercial rights to build and sell your product come with Platform, so there’s no separate license.
We never charge for extra usage automatically. You get a warning at 80% and 100% of each limit, and you decide whether to add capacity.
The best way to know is to try it

We could keep making the case, but your engineers can tell whether Felt saves them time better than we can. Connect your real data, put an embed in a branch of your app, and show it to a few customers. If it doesn’t save you the work, you’ll know before Platform costs you anything.