# Ephemeral maps

_Last updated October 26, 2026_

> Send a map without an account or API key, and get back a link. Whoever opens it sees the map, and can add it to their account to keep editing. Until then, you can change it.

> **Beta:** squidmaps is in beta. Features, the map spec and these docs may change without notice, and things may occasionally break. Export a copy of any map that matters to you, and tell us when something isn't right: use Beta feedback, or email support@squidmaps.io.

An ephemeral map is temporary: it lasts an hour after it's made or last
changed, and a day at most, unless someone adds it to their account, where
it becomes an ordinary map that stays. It's how an AI agent, an automated
workflow or an app turns data into a map it can hand someone: see
[From an AI assistant](#from-an-ai-assistant).

## Create an ephemeral map

```text
POST https://squidmaps.io/api/ephemeral-maps
```

The request body is a [map](https://squidmaps.io/docs/spec/map): the whole map in one document,
with its features, their styles and popups, and its legend, basemap and view.
Only `features` is required:

| Field | Default when missing |
| --- | --- |
| `name` | `"Untitled map"` |
| `description` | `""` |
| `basemap` | The default basemap |
| `extent` | Every zoom level, with no bounds |
| `view` | `null`: the map fits its features when first opened |
| `legend` | `null`: no legend |

Features without an `id` get one, and coordinates are rounded to six decimal
places.

```bash
curl -X POST https://squidmaps.io/api/ephemeral-maps \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Coffee in the East Village",
    "features": [
      {
        "type": "Feature",
        "geometry": { "type": "Point", "coordinates": [-73.9845, 40.7265] },
        "properties": {
          "name": "Abraço",
          "description": "Tiny espresso bar. Get the olive oil cake.",
          "@point-type": "emoji",
          "@emoji": "☕"
        }
      }
    ]
  }'
```

## Response

A `201` with the map's link:

```json
{
  "id": "x4LqT0b9cE2mVd7nRk1sPw",
  "url": "https://squidmaps.io/claim/x4LqT0b9cE2mVd7nRk1sPw",
  "editToken": "Hq0tWb3c9Lr1ZkVx7Nf2Ys5aGd8EmPjU",
  "expiresAt": "2026-10-16T18:00:00.000Z"
}
```

| Field | What it is |
| --- | --- |
| `id` | The ephemeral map's id. |
| `url` | The link to hand to a person. |
| `editToken` | The secret to [change the map](#change-the-map) with. Keep it, and don't share it. |
| `expiresAt` | When the link stops working: an hour after it was made. |

## Change the map

Until someone adds the map to their account, you can replace it with a
changed map, using the `editToken` from when you made it:

```text
PUT https://squidmaps.io/api/ephemeral-maps/{id}
Authorization: Bearer {editToken}
```

The request body is the whole map, as when you made it, not just what
changed. The response is the map's `id`, `url` and new `expiresAt`. The link
stays the same, and anyone who has it open sees the change within a few
seconds, so a person can watch the map while you work on it with them.

Each change keeps the map for another hour, up to a day after it was made.

| Status | Why |
| --- | --- |
| `401` | No edit token was sent. |
| `403` | The edit token isn't this map's. |
| `404` | The map has expired, or never existed. |
| `409` | Someone has added the map to their account. They change it in squidmaps now. |

## Preview the map

```text
GET https://squidmaps.io/api/ephemeral-maps/{id}/preview.jpg
```

A JPEG picture of the map as its link shows it, with its panel and legend.
An assistant can look at it to check its work: whether the map shows what it
should, and how it looks. It takes a few seconds to draw, and is drawn again
only after the map changes.

It's 1200×630 pixels unless you ask for another size:

| Parameter | What it is | Default | Range |
| --- | --- | --- | --- |
| `width` | The width of the screen it's drawn on, in pixels. | `1200` | 320 to 2000 |
| `height` | Its height, in pixels. | `630` | 240 to 2000 |
| `scale` | Image pixels per screen pixel: `2` for a sharper picture of the same view, twice as wide and tall. | `1` | 1 or 2 |

A larger screen shows more of the map, so match the size to the map's shape:
taller for a map that runs north to south, wider for one that runs east to
west. In all, a picture can be at most 4,000,000 pixels (width × height ×
scale²).

```text
GET https://squidmaps.io/api/ephemeral-maps/{id}/preview.jpg?width=800&height=1000
```

| Status | Why |
| --- | --- |
| `400` | A size is out of range, isn't a whole number, or makes too many pixels in all. The `message` says which. |
| `404` | The map has expired, or never existed. |
| `429` | Too many previews from your address. Wait as long as the `Retry-After` header says. |

## Opening the link

Anyone with the link sees the map. The first signed-in person to add it to
their account gets it as their own draft map, and can edit and publish it
like any other. After that, the link tells everyone else the map has been
added, and leads the person who added it to their copy.

Adding the map counts toward that account's limits: during the beta, 15
maps, and up to 500 features and 1 MB of features on one map.

## From GeoJSON

A pipeline that already makes GeoJSON can send its FeatureCollection's
features as they are. Features without style properties get the default
look, so add them as needed, with [`jq`](https://jqlang.org) or your own code:

```bash
jq '{name: "Inspections, week 42", features: .features}' inspections.geojson \
  | curl -X POST https://squidmaps.io/api/ephemeral-maps \
      -H "Content-Type: application/json" -d @-
```

## From an AI assistant

The endpoint needs no account or key, so an assistant that can make web
requests, through a tool, a function call or code it runs, can use it
directly:

1. The person asks for a map, like "the best taco spots in East Austin".
2. The assistant writes the map in the [map spec](https://squidmaps.io/docs/spec).
3. It posts the map here, and gives the person the `url` from the response.
4. As they ask for changes, the assistant [changes the map](#change-the-map)
   rather than making another. The link stays the same.
5. Once they like it, the person adds the map to their account from the
   link, to keep editing and publish it.

To write valid maps, point the model at the spec: every docs page is
available as Markdown, listed in [/llms.txt](https://squidmaps.io/llms.txt), and the spec is
published as [JSON Schema](https://squidmaps.io/docs/map.schema.json). A `400` names what's
wrong and where, so the assistant can fix the map and try again.

Assistants that support MCP, like Claude and ChatGPT, can add the
[squidmaps MCP server](https://squidmaps.io/docs/mcp) instead. Its tools use this API, and in
many apps they show the map in the conversation.

- [Use squidmaps with AI](https://squidmaps.io/docs/ai): Ask an AI assistant for a map you can keep editing.
- [squidmaps MCP server](https://squidmaps.io/docs/mcp): Add squidmaps to Claude, ChatGPT and other assistants.

## Limits

- The request body can be up to 5 MB.
- Features can't have images: add them after the map is in an account.
- Feature ids must be unique.
- Each IP address can create 30 ephemeral maps, change them 120 times and
  preview them 30 times every 10 minutes.
- Previews are drawn at most 2000 pixels on a side (twice that in the image,
  at `scale` 2), and can be at most 4,000,000 pixels in all.
- However often it's changed, a map expires a day after it was made.

## Errors

A map that doesn't match the [spec](https://squidmaps.io/docs/spec) gets a `400`, with a
`message` saying what's wrong and where. See [Errors](https://squidmaps.io/docs/api#errors).

> **Tip:** Validate maps against the published [JSON Schema](https://squidmaps.io/docs/map.schema.json) before sending them.
