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. Checkmeta.warningsafter 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