Skip to content
squidmapsBetaDocs
Request an invite
Map specspec v1
View as Markdown

Features

Each feature is a GeoJSON Feature with a string id. Its properties hold its details, what visitors get from it, and how it's drawn.

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 [email protected].

On this page

Geometry

Points, lines and polygons, their Multi- forms, and geometry collections, as in GeoJSON. Coordinates are [longitude, latitude], with at most six decimal places. A Point can also be text, and a Polygon of four corners an image. A Polygon can also be a circle or a rectangle, made from its center and radius, or its center, size and rotation.

Order

A map’s features are listed top first, as in the editor’s list. Points and text are drawn above lines, areas and images, whatever their place. Among points and text, and among lines, areas and images, features earlier in the list are drawn on top. One exception keeps outlines readable: between two images, areas’ fills are drawn under the lines and outlines listed with them.

Properties

Everything about a feature is in its GeoJSON properties: its own data, like name, and how it looks and behaves, under keys starting with @, so styling travels with the feature.

Every property is optional: a feature without one gets its default, so a plain GeoJSON point is drawn as the default circle. A value that doesn’t match its property makes the feature, and its map, invalid. Properties squidmaps doesn’t use are kept as they are.

Common properties

What a feature is, and what visitors get from it on the published map.

Details

All features. What the feature is. Other properties without an "@" are the feature's own data, kept as they are.

PropertyTypeDefaultDescription
namestringNoneShown in its tooltip, popup and label, and suggested for its legend row. Text's name is its words, drawn on the map.
descriptionstringNoneMarkdown, shown in its popup. HTML is escaped, and links open in a new tab.
@folderstring
1 to 100 characters
NoneThe folder it's in, by name. Folders are one level deep, and exist while a feature names them.
@imagesarray of FeatureImage
at most 24 items
NoneIts images, cover first: at most 24, uploaded in the editor.
@lockedbooleanfalseLocked in the editor: it can be selected, but not moved, reshaped, restyled or deleted until it's unlocked. Visitors' maps ignore it.

Tooltip

Points, lines and areas. A small box following the pointer while visitors hover over the feature.

PropertyTypeDefaultDescription
@tooltipbooleanfalseWhether hovering over the feature shows a tooltip.
@tooltip-namebooleantrueShow the feature's name.
@tooltip-thumbnailbooleanfalseShow a thumbnail of its first image, if it has one.
@tooltip-backgroundColor"#000000"The tooltip's color.
@tooltip-colorColor"#FFFFFF"The text's color.
json
{
  "type": "Feature",
  "id": "area-1",
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [-73.9564, 40.773816],
        [-73.9546, 40.773816],
        [-73.9546, 40.775184],
        [-73.9564, 40.775184],
        [-73.9564, 40.773816]
      ]
    ]
  },
  "properties": {
    "name": "Carl Schurz Park",
    "@tooltip": true,
    "@tooltip-background": "#2F8A4E",
    "@line-color": "#2F8A4E",
    "@fill-color": "#2F8A4E"
  }
}

Popup

Points, lines and areas. What visitors get when they click the feature.

PropertyTypeDefaultDescription
@popup"card" | "panel" | "none""card"What clicking the feature opens: a card above it with its images, name and description; the same in a panel beside the map; or nothing.
@directionsbooleanfalseFor points: offer directions to it, in Google Maps, from its popup.
json
{
  "type": "Feature",
  "id": "cafe",
  "geometry": {
    "type": "Point",
    "coordinates": [-73.9555, 40.7745]
  },
  "properties": {
    "name": "Café on the corner",
    "description": "Get the **cardamom bun**, and a seat by the window.",
    "@popup": "card",
    "@fill": "#D9664E",
    "@radius": 11,
    "@icon": "solid/mug-hot"
  }
}

Points

Points are drawn as 3 types (circle, emoji and marker), chosen by @point-type. Each type has its own properties, so a point keeps every type’s style and changing its type back restores it.

Point type

Points. How a point is drawn. Each type keeps its own style properties, so changing a point's type and back restores its style.

PropertyTypeDefaultDescription
@point-type"circle" | "emoji" | "marker""circle"Which of the point styles below it's drawn with.
json
[
  {
    "type": "Feature",
    "id": "point-1",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9579, 40.7745]
    },
    "properties": {
      "name": "A circle"
    }
  },
  {
    "type": "Feature",
    "id": "point-2",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9555, 40.7745]
    },
    "properties": {
      "name": "A marker pin",
      "@point-type": "marker"
    }
  },
  {
    "type": "Feature",
    "id": "point-3",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9531, 40.7745]
    },
    "properties": {
      "name": "An emoji",
      "@point-type": "emoji",
      "@emoji": "🌳"
    }
  }
]

Circles

Points. A colored circle, optionally with an icon in it. For points with "@point-type": "circle".

PropertyTypeDefaultDescription
@fillColor"#3F80C4"The circle's color.
@radiusnumber
2 to 40
8In pixels, not counting the stroke.
@strokeColor"#FFFFFF"The ring around the circle.
@stroke-widthnumber
0 to 10
2The ring's width in pixels, outside the radius.
@iconIconNoneA Font Awesome icon in the circle.
@icon-colorColorNoneThe icon's color. Without one, white or dark ink, whichever contrasts the fill.
json
[
  {
    "type": "Feature",
    "id": "circle-1",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9591, 40.7745]
    },
    "properties": {}
  },
  {
    "type": "Feature",
    "id": "circle-2",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9567, 40.7745]
    },
    "properties": {
      "@fill": "#D9664E",
      "@radius": 13,
      "@icon": "solid/mug-hot"
    }
  },
  {
    "type": "Feature",
    "id": "circle-3",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9543, 40.7745]
    },
    "properties": {
      "@fill": "#12312C",
      "@radius": 5,
      "@stroke": "#F2C14E",
      "@stroke-width": 4
    }
  },
  {
    "type": "Feature",
    "id": "circle-4",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9519, 40.7745]
    },
    "properties": {
      "@fill": "#F2C14E",
      "@radius": 18,
      "@stroke-width": 0,
      "@icon": "solid/star",
      "@icon-color": "#8A3B12"
    }
  }
]

Emoji

Points. An emoji, drawn as its Twemoji image. For points with "@point-type": "emoji".

PropertyTypeDefaultDescription
@emojiEmoji"📍"One emoji, drawn as its Twemoji image.
@sizenumber
12 to 64
28The emoji's width and height in pixels.
json
[
  {
    "type": "Feature",
    "id": "emoji-1",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9579, 40.7745]
    },
    "properties": {
      "@point-type": "emoji",
      "@emoji": "🍕",
      "@size": 20
    }
  },
  {
    "type": "Feature",
    "id": "emoji-2",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9555, 40.7745]
    },
    "properties": {
      "@point-type": "emoji",
      "@emoji": "🚲",
      "@size": 32
    }
  },
  {
    "type": "Feature",
    "id": "emoji-3",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9531, 40.7745]
    },
    "properties": {
      "@point-type": "emoji",
      "@emoji": "🏛️",
      "@size": 48
    }
  }
]

Marker pins

Points. A map pin standing on the point, with an optional icon in its head. For points with "@point-type": "marker".

PropertyTypeDefaultDescription
@marker-shellColor"#FFFFFF"The pin's outer color.
@marker-discColor"#0E9384"The disc in the pin's head.
@marker-iconIconNoneA Font Awesome icon on the disc. Without one, it's empty.
@marker-icon-colorColorNoneThe icon's color. Without one, white or dark ink, whichever contrasts the disc.
json
[
  {
    "type": "Feature",
    "id": "marker-1",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9579, 40.7745]
    },
    "properties": {
      "@point-type": "marker"
    }
  },
  {
    "type": "Feature",
    "id": "marker-2",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9555, 40.7745]
    },
    "properties": {
      "@point-type": "marker",
      "@marker-shell": "#C2473A",
      "@marker-disc": "#FFFFFF",
      "@marker-icon": "solid/utensils"
    }
  },
  {
    "type": "Feature",
    "id": "marker-3",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9531, 40.7745]
    },
    "properties": {
      "@point-type": "marker",
      "@marker-shell": "#12312C",
      "@marker-disc": "#F2C14E",
      "@marker-icon": "solid/star",
      "@marker-icon-color": "#12312C"
    }
  }
]

Labels

Points. A point's name, drawn beside it. Labels belong to the point, not its type.

PropertyTypeDefaultDescription
@show-labelbooleanfalseWhether the point's name is drawn beside it. Labels that would overlap are hidden until there's room, unless they ignore conflicts.
@label-sizenumber
10 to 24
13The text's size in pixels.
@label-colorColor"#12312C"The text's color. Its halo is white or dark ink, to contrast.
@label-placement"top" | "right""top"Centered above the point, or to its right.
@label-ignore-conflictsbooleanfalseWhether the label always shows, even where it overlaps other labels or points.
json
[
  {
    "type": "Feature",
    "id": "label-1",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9579, 40.7745]
    },
    "properties": {
      "name": "Above",
      "@show-label": true
    }
  },
  {
    "type": "Feature",
    "id": "label-2",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9555, 40.7745]
    },
    "properties": {
      "name": "To the right",
      "@show-label": true,
      "@label-placement": "right"
    }
  },
  {
    "type": "Feature",
    "id": "label-3",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9531, 40.7745]
    },
    "properties": {
      "name": "Bigger, in color",
      "@show-label": true,
      "@label-size": 17,
      "@label-color": "#C2473A",
      "@fill": "#C2473A"
    }
  }
]

Lines

Lines. How a line is drawn. When a property is missing, its simplestyle-spec equivalent is read instead, so GeoJSON styled for other tools keeps its look.

PropertyTypeDefaultDescription
@line-colorColor"#3F80C4"The line's color. Falls back to stroke.
@line-widthnumber
0.5 to 20
3In pixels. Falls back to stroke-width.
@line-opacitynumber
0 to 1
1From 0 (invisible) to 1 (opaque). Falls back to stroke-opacity.
@line-dasharrayarray of number
at most 8 items, each 0 to 100
[]Dash and gap lengths in turn, in line widths, like [4, 2]. Empty is solid.
@line-cap"butt" | "round" | "square""round"How the line's ends are drawn.
json
[
  {
    "type": "Feature",
    "id": "line-1",
    "geometry": {
      "type": "LineString",
      "coordinates": [
        [-73.96, 40.77565],
        [-73.957, 40.77605],
        [-73.954, 40.77565],
        [-73.951, 40.77605]
      ]
    },
    "properties": {
      "@line-color": "#3F80C4",
      "@line-width": 6
    }
  },
  {
    "type": "Feature",
    "id": "line-2",
    "geometry": {
      "type": "LineString",
      "coordinates": [
        [-73.96, 40.77475],
        [-73.957, 40.77515],
        [-73.954, 40.77475],
        [-73.951, 40.77515]
      ]
    },
    "properties": {
      "@line-color": "#C2473A",
      "@line-width": 3,
      "@line-dasharray": [4, 2],
      "@line-cap": "butt"
    }
  },
  {
    "type": "Feature",
    "id": "line-3",
    "geometry": {
      "type": "LineString",
      "coordinates": [
        [-73.96, 40.77385],
        [-73.957, 40.77425],
        [-73.954, 40.77385],
        [-73.951, 40.77425]
      ]
    },
    "properties": {
      "@line-color": "#12312C",
      "@line-width": 4,
      "@line-dasharray": [0, 2]
    }
  },
  {
    "type": "Feature",
    "id": "line-4",
    "geometry": {
      "type": "LineString",
      "coordinates": [
        [-73.96, 40.77295],
        [-73.957, 40.77335],
        [-73.954, 40.77295],
        [-73.951, 40.77335]
      ]
    },
    "properties": {
      "@line-color": "#2F8A4E",
      "@line-width": 10,
      "@line-opacity": 0.5
    }
  }
]

Areas

Areas. How an area is drawn: its outline, like a line's, and its fill. Missing properties fall back to simplestyle-spec too.

PropertyTypeDefaultDescription
@line-colorColor"#3F80C4"The line's color. Falls back to stroke.
@line-widthnumber
0.5 to 20
2In pixels. Falls back to stroke-width.
@line-opacitynumber
0 to 1
1From 0 (invisible) to 1 (opaque). Falls back to stroke-opacity.
@line-dasharrayarray of number
at most 8 items, each 0 to 100
[]Dash and gap lengths in turn, in line widths, like [4, 2]. Empty is solid.
@line-cap"butt" | "round" | "square""round"How the line's ends are drawn.
@fill-colorColor"#3F80C4"The area's inside color. Falls back to fill.
@fill-opacitynumber
0 to 1
0.3From 0 (no fill) to 1 (opaque). Falls back to fill-opacity.
json
[
  {
    "type": "Feature",
    "id": "area-1",
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [-73.9592, 40.773816],
          [-73.9574, 40.773816],
          [-73.9574, 40.775184],
          [-73.9592, 40.775184],
          [-73.9592, 40.773816]
        ]
      ]
    },
    "properties": {}
  },
  {
    "type": "Feature",
    "id": "area-2",
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [-73.9564, 40.773816],
          [-73.9546, 40.773816],
          [-73.9546, 40.775184],
          [-73.9564, 40.775184],
          [-73.9564, 40.773816]
        ]
      ]
    },
    "properties": {
      "@line-color": "#2F8A4E",
      "@line-width": 1,
      "@fill-color": "#2F8A4E",
      "@fill-opacity": 0.6
    }
  },
  {
    "type": "Feature",
    "id": "area-3",
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [
          [-73.9536, 40.773816],
          [-73.9518, 40.773816],
          [-73.9518, 40.775184],
          [-73.9536, 40.775184],
          [-73.9536, 40.773816]
        ]
      ]
    },
    "properties": {
      "@line-color": "#C2473A",
      "@line-width": 3,
      "@line-dasharray": [2, 2],
      "@fill-opacity": 0
    }
  }
]

Text

Text. Words on the map, centered on a point: a Point with "@feature-type": "text", whose name is drawn with the properties below. New lines in the name start new lines. Text isn't a kind of point, so it has no point type, label, tooltip or popup.

PropertyTypeDefaultDescription
@feature-type"text"NoneMakes a Point text, drawn with the properties below.
@text-sizenumber
8 to 120
24The text's size in pixels; with "@text-scale": "map", its size at "@text-scale-zoom".
@text-colorColor"#12312C"The text's color.
@text-halo-colorColor"#FFFFFF"The outline around the letters, to keep them readable.
@text-halo-widthnumber
0 to 8
2The outline's width in pixels. 0 has none.
@text-backgroundColorNoneA rounded rectangle behind the text, in this color. Without one, there's no background.
@text-background-radiusnumber
0 to 32
6The background's corner radius in pixels.
@text-scale"pixels" | "map""pixels""pixels" stays the same size at every zoom; "map" grows and shrinks with the map.
@text-scale-zoomnumber
0 to 24
12With "@text-scale": "map", the zoom at which the text is "@text-size" pixels: twice that one zoom in, half one out.
@text-rotatenumber
-180 to 180
0How far the text is turned about its point, in degrees clockwise, from -180 to 180. 0 is level.
json
[
  {
    "type": "Feature",
    "id": "text-1",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9589, 40.7745]
    },
    "properties": {
      "@feature-type": "text",
      "name": "Plain"
    }
  },
  {
    "type": "Feature",
    "id": "text-2",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9555, 40.7745]
    },
    "properties": {
      "@feature-type": "text",
      "name": "With a\nbackground",
      "@text-size": 16,
      "@text-color": "#FFFFFF",
      "@text-halo-width": 0,
      "@text-background": "#1E7A6C"
    }
  },
  {
    "type": "Feature",
    "id": "text-3",
    "geometry": {
      "type": "Point",
      "coordinates": [-73.9521, 40.7745]
    },
    "properties": {
      "@feature-type": "text",
      "name": "Turned",
      "@text-size": 20,
      "@text-color": "#C2473A",
      "@text-rotate": -20,
      "@text-scale": "map",
      "@text-scale-zoom": 16
    }
  }
]

Circle areas

Areas. An area that stays a circle: a Polygon with "@feature-type": "circle" and its center and radius. The polygon is made from them, round on the map, so send null (or any Polygon) as its geometry and the API fills it in. It's styled as an area. Without the two properties below it's a plain area, whose vertices can be edited.

PropertyTypeDefaultDescription
@feature-type"circle"NoneMakes an area a circle, made from the property below.
@circleobjectNoneA circle's center and radius. It's drawn round on the map (Web Mercator), so its radius is exact at its center.
@circle.center[number, number]
items in turn: -180 to 180; -85.051129 to 85.051129
NoneIts center, as [longitude, latitude].
@circle.radiusnumber
0.1 to 5000000
NoneIn meters, at its center.
json
{
  "type": "Feature",
  "id": "circle-area",
  "geometry": null,
  "properties": {
    "name": "A 150 m walk",
    "@feature-type": "circle",
    "@circle": {
      "center": [-73.9555, 40.7745],
      "radius": 150
    },
    "@fill-color": "#F2C14E"
  }
}

Rectangles

Areas. An area that stays a rectangle, at any angle: a Polygon with "@feature-type": "rectangle" and its center, size and rotation. The polygon is made from them, a rectangle on the map, so send null (or any Polygon) as its geometry and the API fills it in. It's styled as an area. Without the two properties below it's a plain area, whose vertices can be edited.

PropertyTypeDefaultDescription
@feature-type"rectangle"NoneMakes an area a rectangle, made from the property below.
@rectangleobjectNoneA rectangle's center, size and turn. It's drawn as a rectangle on the map (Web Mercator), so its size is exact at its center.
@rectangle.center[number, number]
items in turn: -180 to 180; -85.051129 to 85.051129
NoneIts center, as [longitude, latitude].
@rectangle.widthnumber
0.1 to 10000000
NoneIn meters, at its center: its top and bottom edges.
@rectangle.heightnumber
0.1 to 10000000
NoneIn meters, at its center: its left and right edges.
@rectangle.rotationnumber
-180 to 180
NoneHow far it's turned clockwise, in degrees: 0 is upright, with its top edge running east–west.
json
{
  "type": "Feature",
  "id": "rectangle",
  "geometry": null,
  "properties": {
    "name": "A lot",
    "@feature-type": "rectangle",
    "@rectangle": {
      "center": [-73.9555, 40.7745],
      "width": 320,
      "height": 140,
      "rotation": 29
    }
  }
}

The API makes a circle’s or rectangle’s polygon when it saves the map, so send its geometry as null (or any Polygon). The editor resizes them by their parameters, so they stay circles and rectangles; removing @feature-type and the parameter makes either a plain area, whose vertices can be edited.

Images

Images. A picture fixed to the map, drawn among lines and areas in the features' order: a Polygon of its four corners (top left, top right, bottom right, bottom left, then the first again) with "@feature-type": "image". The corners place, size and turn the picture.

PropertyTypeDefaultDescription
@feature-type"image"NoneMakes a Polygon an image, placed by its corners.
@imageFeatureImageNoneThe picture, uploaded in the editor.

The editor moves an image’s corners together, keeping the picture in proportion. Images are drawn under every point and text, and aren’t interactive on published maps.

Types

Objects inside feature properties.

FeatureImage

An image uploaded to squidmaps, kept as uploaded and scaled down.

FieldTypeRequiredDescription
idstring
a UUID
Yes
urlstring
a URL
YesThe folder its scaled-down WebP versions are in, each at {url}/{size}.webp: thumb (256px), small (640px), medium (1280px), large (2560px).
originalstring
a URL
YesThe file as uploaded.
widthinteger
above 0
YesThe original's width in pixels, upright.
heightinteger
above 0
YesThe original's height in pixels, upright.
bytesinteger
at least 0
YesBytes in storage: the original and its scaled versions together.
altstring
at most 1000 characters
NoAlt text: what the image shows, for people who can't see it, read out by screen readers. Missing for an image without one.

Value types

Kinds of values that appear in several places.

Bounds

An area as [west, south, east, north], in degrees. West is below east and south below north; it doesn't cross the antimeridian. Coordinates have at most six decimal places.

[number, number, number, number]: items in turn: -180 to 180; -85.051129 to 85.051129; -180 to 180; -85.051129 to 85.051129

Color

A color in hex, as "#rrggbb", like "#3F80C4".

string: matches /^#[0-9a-fA-F]{6}$/

Icon

A Font Awesome 6 Free icon as "style/name": "solid/mug-hot", "regular/heart" or "brands/github". The style is solid, regular or brands.

string: matches /^(solid|regular|brands)\/[a-z0-9]+(-[a-z0-9]+)*$/

Emoji

One emoji, like "📍", "🇯🇵" or "👩‍🚒", including flags and sequences joined with zero-width joiners.

string

Need a hand? Email [email protected]. Attribution. Privacy. . © 2026 squidmaps