Measure MapHelp
Open Measure Map

REST API

Work with your projects, folders, products and members from your own software, try requests from the Developer page, and receive webhooks when things happen.

The REST API lets your own software read and change what is in your Measure Map Online account: projects and their measurements, folders, the product catalogue and, on Enterprise, the members of your organisation. It answers in JSON. The full reference, with every field and example, is the API documentation; this page is the overview.

To open the documentation from the app, go to Developer > REST API and press View documentation.

The REST API section of the Developer page

Base URL#

Every request goes to:

https://api.measuremaponline.com/api/v2

Authentication#

Send your API key, as it is, in the Authorization header of every request. Create the key on the Developer page: see API keys.

curl https://api.measuremaponline.com/api/v2/projects/YOUR_PROJECT_ID \
  -H "Authorization: YOUR_API_KEY"

Each request is checked against the key's access (for example, Projects Read), your subscription and, for a request sent from a web page, the key's website restrictions. Keep keys that can change data on your server: see keep your key safe.

Live and sandbox#

There is one base URL for both. The key decides: a sandbox key reads and writes sandbox projects, folders and products, which live keys never see. Members are the same in both, but signing in as a member needs a live key. Guest projects made with a sandbox key are never billed, and sandbox projects cannot be embedded on your website. Tokens report the environment they belong to.

What the API covers#

Group Endpoints Key access needed
Sign-in tokens POST /auth/token, POST /auth/iframe/token Embedded maps
Projects and folders List a person's projects (all, or page by page, up to 200 a page) and folders; get a project, its measurements (/projects/{pid}/data), its comments, or its .mmp file (/projects/{pid}/mmp); get a folder; create, update and delete projects and folders Projects: Read to read, Read & change to change
Products GET /products, GET /products/{id}, create, update, and archive with DELETE /products/{id} Products: Read or Read & change
Members (Enterprise) GET /users, GET /users/{uid}, POST /users/new, PUT /users/{uid}, DELETE /users/{uid} Users: Read or Read & change
Signing in as a member (Enterprise) POST /auth/{uid}/login gives a sign-in token for a member of your organisation Users: Read & change

A few things to know:

  • A key reaches the projects of its own account and, on Enterprise, those of the organisation's members.
  • Deleting a project or a folder through the API is permanent: nothing goes to the Trash. A folder takes with it the folders and projects inside that belong to your account or your members.
  • In a project's measurements, a shape lists its products in productIds, in order; productId is the first of them.
  • /projects/{pid}/mmp gives the same .mmp file the app exports. Its schema is published at github.com/blueblinkone/mmp-validator. New elements are only ever added as optional ones, so a reader written for an older file keeps working.
  • On Open Guest, a project created through the API with the Open Guest access level counts towards your Open Guest usage and budget, like one started from your guest link.
  • On Open Guest, the Guest link section has the Open Guest API guide, with code for your server and your page: your server gets a token from POST /auth/token with your live key and sends the visitor to a new project of their own, their details filled in.
  • Creating a member with POST /users/new uses a seat, as an invitation does, and gives them your organisation's default role.
  • A token from POST /auth/{uid}/login opens that member's account, so it needs a key that may change members, never the key in your embeds. It is not given for an Admin or a Manager, nor with a sandbox key.
  • Products are never deleted through the API, only archived, and a product's cost price is never returned.
  • Cadastral parcels are not part of the API.

Responses and errors#

A successful request answers with status 200 and JSON (the .mmp export answers with XML). A failed one answers with an error status and a body such as:

{"errorCode": "insufficient_scope", "errorMessage": "This API key does not have the scope required for this endpoint"}
Status errorCode What to check
400 invalid_body, invalid_uid, invalid_project_id, pagination_invalid_page_number, pagination_invalid_page_limit A value in the request is missing or not accepted, such as the page and limit of a paged list.
401 unauthorized_action The request was sent from a web page on a website the key does not allow, or the item is not on your account or your members'.
402 budget_limit_reached Open Guest: your budget limit is reached, so no more guest projects this period.
403 invalid_api_key No key was sent in the Authorization header, or the key is unknown, revoked, or past its 24 hours after being replaced.
403 api_key_suspended API access on your account has been suspended. Contact support.
403 subscription_expired, invalid_subscription The subscription is not active, or its plan has no API.
403 insufficient_scope The key does not have the access this endpoint needs.
403 scope_not_in_plan Your plan does not include this endpoint, for example members on Open Guest.
404 not_found, project_not_found, user_not_found The item does not exist, or the person is not a member of your organisation.
409 enterprise_add_users_limit Creating a member: every seat is taken.
429 too_many_requests More than 600 tokens in an hour. Wait a little and try again.
500 server_error The request could not be completed. Check the IDs you sent, try again, and contact support if it persists.

Try the API from the Developer page#

Developer > Try the API sends real requests with your key and shows exactly what comes back.

  1. Choose Live or Sandbox.
  2. Pick an Endpoint, such as "List all projects" or "Get measurements".
  3. Fill in its parameters. A project or a product is picked by name from those the key can read; where a person is needed, your own account is filled in for you.
  4. Press Send request. The status and the response appear below.

Only requests that read are offered, so nothing is changed by trying, and these requests are not counted in your usage. If your key does not have the access an endpoint needs, the page warns you that it will answer 403.

Try the API with a request sent and its JSON response

Webhooks#

A webhook tells your server when something happens, as the notification emails tell you. Webhooks are part of the Enterprise and Open Guest plans.

Set up a webhook#

In Developer > Webhooks:

  1. Type your Endpoint URL: an https:// address on the internet. Addresses on private networks are refused, and this is checked again before every delivery.
  2. Tick the Events you want (see events). A new endpoint starts with the events your plan sends, and at least one must be ticked.
  3. Press Save. The first time, the page shows your Signing secret in full. Copy it then: afterwards only its last characters are shown.
  4. Press Send test event and pick an event.

A test sends a sample of that event, with made-up values and "test": true in its data, to your saved endpoint, even when the event is not ticked or the endpoint is switched off. To stop all deliveries, press Remove: the endpoint and its secret are deleted.

Below the settings, the Webhook reference has what you need to write the receiving end: the headers and the body, code that checks the signature in Node.js, Python and PHP, and example data for every event.

Webhooks with an endpoint and the events it receives

What your server receives#

Each event is one POST to your endpoint, with a JSON body:

{"id": "evt_3f9a1c2b7d4e5f60718293a4", "type": "project.created", "created": 1790000000000, "data": { ... }}

id is unique for each event, created is when it happened in milliseconds since 1 January 1970 (UTC), and what data holds depends on the event. The request also has these headers:

Header Value
X-MMO-Event The event name, as type in the body.
X-MMO-Delivery The event's id.
X-MMO-Signature t=<milliseconds>,v1=<hex>: when the delivery was signed, and its signature.
User-Agent MeasureMapOnline-Webhooks/1
  • Answer with a 2xx status within 8 seconds, before any slow work. Any other status, a redirect or a timeout counts as a failure.
  • Each event is sent once and never retried. The section shows the Last delivery and the Consecutive failures.
  • After 10 failures in a row, the endpoint is switched off and the owner gets an email. Fix your server and press Save to switch it back on.
  • Now and then an event arrives twice or out of order. Use id to ignore repeats and created to put events in order.

Check the signature#

Anyone who knows your address can post to it, so check every delivery before you trust it:

  1. Split the X-MMO-Signature header at the comma into t and v1.
  2. Compute an HMAC-SHA256 of t, a full stop and the raw request body, with your signing secret as the key, written as hexadecimal.
  3. Compare the result with v1 using a constant-time comparison.
  4. Reject the delivery if t is more than 5 minutes from the current time. t is in milliseconds.

Use the body exactly as it arrived: parsing the JSON and writing it out again changes it, and the signature no longer matches.

Rotate secret replaces the secret at once and shows the new one in full, once. Update your server as soon as you rotate.

Events#

Event Sent when
project.created A project is created on your account. In the app, through the API or from an embed.
project.deleted A project is permanently deleted (moving one to the trash does not count).
project.comment.added Someone comments on a project — usually your client replying.
guest.project.created (Open Guest) A guest starts a project from your link or through the API. Only when the guest's email address is known.
guest.measurement.completed (Open Guest) A guest finishes a measurement and leaves their contact details.
budget.warning_reached (Open Guest) Metered spend crosses your warning threshold.
budget.limit_reached (Open Guest) Metered spend hits your limit — further guest projects are refused.
enterprise.user.created (Enterprise) A seat is added to your organization, including through single sign-on.

Still need help?

Write to our support team and tell us what you were trying to do. Screenshots help.

Email support