Contents
On this page

Create Map - Plugixa Image Map

POST /plugixa-image-map/v1/maps

Create a map, empty or with its picture and hotspots.

Any signed-in user with the plugixa_image_map_create capability. Administrators have every Plugixa Image Map capability; see Roles and permissions.

Note. The cleaning is lenient on purpose: a hotspot with an unknown type, or a polygon with fewer than 3 points, is dropped and the request still succeeds. Check meta.warnings after every write.

Request

POST https://your-site.example/wp-json/plugixa-image-map/v1/maps

Request body

Content type: application/json

Field Type Required Description
title string No Plain text, at most 255 characters. Omitted or empty gives Untitled map.
status string No draft (the default) or published. Anything else is refused.
doc object No The map document, described below. Omitted gives an empty map with no picture.
{
  "title": "Ground floor",
  "status": "draft",
  "doc": {
    "image": {
      "attachment_id": 58
    },
    "objects": [
      {
        "type": "spot",
        "name": "Reception",
        "geometry": {
          "x": 42.5,
          "y": 61.25
        },
        "tooltip": {
          "content": "<p>Reception desk, open 8:00 to 18:00.</p>"
        }
      }
    ]
  }
}

The map document

doc is the whole map. Every part of it is optional: what you leave out takes its default, so the example above is a complete request.

Key Type Description
schema integer The document format, 1. A higher number is refused.
image.attachment_id integer The Media Library image the map is drawn on. Width, height and the default alt text are read from the attachment; values you send for them are ignored. Send image.alt to set your own alt text.
settings object Map-wide behaviour in five groups: general (responsive), tooltips (enabled, trigger: hover or click, sticky, constrain, animation: none, fade or grow), effects (pageload: none, fade or grow), zoom (enabled, max from 1.5 to 10, buttons, wheel: ctrl or always, fullscreen) and list (enabled, position: right, left or below, search, title). See Map settings.
objects array The hotspots, drawn in order: the last one is on top. At most 2,000.
groups array Layer groups, { "id", "name" }. A group no hotspot uses is dropped. See Layers and groups.
ext object Data that Pro modules keep for the whole map, such as floors. Dropped on the free build.

Each hotspot in objects:

Key Type Description
id string Letters, digits, _ and -, up to 40 characters, unique in the map. A missing, malformed or repeated id is replaced with a new one, so send your own to keep it stable.
type string spot, rect, oval, poly or text. A hotspot of any other type is dropped.
name string Plain text, up to 100 characters.
geometry object In percent of the picture, from its top-left corner, between -100 and 200. A spot has x, y (its centre) and w (its diameter, 0.5 to 25). rect, oval and text have x, y (the top-left corner), w, h and rotation. A poly has points, a list of [x, y] pairs: at least 3, at most 1,000.
style object default and hover, each with fill, fill_opacity, stroke, stroke_opacity, stroke_width, radius, opacity, icon, icon_color and shadow. Colours are #rgb or #rrggbb. hover holds only what differs. See Styling hotspots.
action object What a click does: type is none, link (with url and new_tab) or event (with event, a name your own script listens for). Links accept http, https, mailto, tel and #anchor. See Links and actions.
tooltip object enabled, position (auto, top, right, bottom, left), width (80 to 800 pixels), offset_x, offset_y and content, HTML up to 20,000 characters. See Tooltips.
a11y object label (up to 100 characters) and description (up to 300), read by screen readers.
text object For text hotspots: content, font (sans, serif, mono), size, weight, color and align.
visible, locked boolean Shown on the page; fixed in the editor.
group string The id of a group in groups, or empty.
ext object Data that Pro modules keep per hotspot, such as conditions and linked content.

The document is cleaned the same way the editor’s save is: unknown keys are dropped, numbers are clamped into their range, a value of the wrong kind takes its default, a link with a scheme that is not allowed turns the action into none, and tooltip HTML is filtered. None of that fails the request. Each change is reported in meta.warnings instead. An empty hover, or an empty ext, comes back as [].

Responses

201 Created. data is the new map, document included.

{
  "success": true,
  "data": {
    "id": 12,
    "uid": "9b2f6c1e-4d7a-4f3b-9a51-2c8e7d0f6a13",
    "title": "Ground floor",
    "status": "draft",
    "image_id": 58,
    "doc": {
      "schema": 1,
      "image": {
        "attachment_id": 58,
        "width": 1600,
        "height": 1000,
        "alt": "Ground floor plan"
      },
      "settings": {
        "general": {
          "responsive": true
        },
        "tooltips": {
          "enabled": true,
          "trigger": "hover",
          "sticky": false,
          "constrain": true,
          "animation": "fade"
        },
        "effects": {
          "pageload": "none"
        },
        "zoom": {
          "enabled": false,
          "max": 4.0,
          "buttons": true,
          "wheel": "ctrl",
          "fullscreen": false
        },
        "list": {
          "enabled": false,
          "position": "right",
          "search": true,
          "title": ""
        }
      },
      "objects": [
        {
          "id": "o_3f9a1c2e",
          "type": "spot",
          "name": "Reception",
          "geometry": {
            "x": 42.5,
            "y": 61.25,
            "w": 3.0
          },
          "style": {
            "default": {
              "fill": "#1976d2",
              "fill_opacity": 0.4,
              "stroke": "#ffffff",
              "stroke_opacity": 1.0,
              "stroke_width": 0.0,
              "radius": 4.0,
              "opacity": 1.0,
              "icon": "",
              "icon_color": "#ffffff",
              "shadow": false
            },
            "hover": []
          },
          "action": {
            "type": "none",
            "new_tab": false,
            "url": "",
            "event": ""
          },
          "tooltip": {
            "enabled": true,
            "position": "auto",
            "width": 260,
            "offset_x": 0.0,
            "offset_y": 0.0,
            "content": "<p>Reception desk, open 8:00 to 18:00.</p>"
          },
          "a11y": {
            "label": "",
            "description": ""
          },
          "visible": true,
          "locked": false,
          "group": "",
          "ext": []
        }
      ],
      "groups": [],
      "ext": []
    },
    "doc_version": 1,
    "trusted_html": true,
    "object_count": 1,
    "rev": 1,
    "created_by": 1,
    "modified_by": 1,
    "created_at": "2026-11-12 09:30:00",
    "modified_at": "2026-11-12 09:30:00",
    "deleted_at": null,
    "doc_error": false,
    "image_url": "https://your-site.example/wp-content/uploads/2026/11/ground-floor.png",
    "shortcode": "[plugixa_image_map id=\"12\"]",
    "thumbnail_url": "https://your-site.example/wp-content/uploads/2026/11/ground-floor-150x150.png"
  },
  "meta": {
    "warnings": [
      {
        "path": "objects.0.id",
        "code": "id_replaced"
      }
    ]
  }
}
Field Type Meaning
data.id integer The map’s id
data.uid string A stable identity that survives export and import; the numeric id does not
data.title string The title, at most 255 characters
data.status string draft or published
data.image_id integer The Media Library attachment the map is drawn on, 0 for none
data.doc object The map document: picture, settings, hotspots and groups. See The map document
data.doc_version integer The document format, 1 in this version
data.trusted_html boolean Whether the last person to save could post unfiltered HTML, which decides how tooltips were cleaned
data.object_count integer Number of hotspots
data.rev integer The version number, up by one on every save. Send it back with an update
data.created_at string UTC datetime
data.modified_at string UTC datetime of the last save
data.deleted_at string|null null unless the map is in the trash
data.doc_error boolean true when the stored document could not be read and an empty map is shown in its place
data.image_url string|null Full-size URL of the picture
data.shortcode string The shortcode that embeds the map
data.thumbnail_url string|null Thumbnail URL of the picture
meta.warnings array What the cleaning changed or dropped, one { "path", "code" } per change. Empty when the document was taken as sent

The example hotspot was sent without an id, so it was given one and the change is reported.

Errors

Status Code When
422 plugixa_image_map_title_required title is not text, or holds nothing once markup is removed.
422 plugixa_image_map_invalid_status status is not draft or published.
422 plugixa_image_map_invalid_document doc is not a JSON object.
413 plugixa_image_map_too_large doc is over 2 MB as JSON.
422 plugixa_image_map_too_deep doc nests more than 12 levels.
422 plugixa_image_map_newer_document doc.schema is newer than this version of the plugin reads.
422 plugixa_image_map_too_many_objects More than 2,000 hotspots.
422 plugixa_image_map_too_many_points A polygon with more than 1,000 points.
422 plugixa_image_map_too_many_groups More than 500 groups.
422 plugixa_image_map_too_long A value is longer than its column holds (the title: 255 characters). data.field and data.max say which and how long.
500 plugixa_image_map_save_failed The database refused the write.

Plus the errors every endpoint can return.

Examples

curl -s -X POST "https://your-site.example/wp-json/plugixa-image-map/v1/maps" \
  -u "admin:$WP_APP_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{"title":"Ground floor","status":"draft","doc":{"image":{"attachment_id":58},"objects":[{"type":"spot","name":"Reception","geometry":{"x":42.5,"y":61.25},"tooltip":{"content":"<p>Reception desk, open 8:00 to 18:00.</p>"}}]}}'
<?php
$ch = curl_init('https://your-site.example/wp-json/plugixa-image-map/v1/maps');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'admin:' . getenv('WP_APP_PASSWORD'),
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'title'  => 'Ground floor',
        'status' => 'draft',
        'doc'    => [
            'image'   => [
                'attachment_id' => 58,
            ],
            'objects' => [
                [
                    'type'     => 'spot',
                    'name'     => 'Reception',
                    'geometry' => [
                        'x' => 42.5,
                        'y' => 61.25,
                    ],
                    'tooltip'  => [
                        'content' => '<p>Reception desk, open 8:00 to 18:00.</p>',
                    ],
                ],
            ],
        ],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.example/wp-json/plugixa-image-map/v1/maps', {
  method: 'POST',
  headers: {
    'Authorization': 'Basic ' + btoa(`admin:${process.env.WP_APP_PASSWORD}`),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Ground floor',
    status: 'draft',
    doc: {
      image: {
        attachment_id: 58,
      },
      objects: [
        {
          type: 'spot',
          name: 'Reception',
          geometry: {
            x: 42.5,
            y: 61.25,
          },
          tooltip: {
            content: '<p>Reception desk, open 8:00 to 18:00.</p>',
          },
        },
      ],
    },
  }),
});
const { data } = await response.json();

Quick Links

Share