{"openapi":"3.1.0","info":{"title":"Draw on a Map API","version":"1.2.0","description":"Public map link creation needs no account. Place lookup and account-owned maps require access. Read before saved-map updates. Saved-map writes require an idempotency key. No paid operations."},"servers":[{"url":"https://drawonamap.com"}],"security":[{"agentToken":[]}],"components":{"securitySchemes":{"agentToken":{"type":"http","scheme":"bearer","description":"Revocable account token created through /api/agent-tokens in a signed-in browser."}}},"paths":{"/api/v1/map-links":{"post":{"operationId":"create_map_link","summary":"Create an independent map link without an account","security":[],"description":"Processes GeoJSON on the server without saving map content. Anyone with the link can read it and edit their own copy. The link is not encrypted. Supply verified WGS84 coordinates. No place lookup, account storage, or private link is provided. Public HTTP and MCP requests share a 60-request-per-minute limit per client address.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"features":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","pattern":"^drawing:\\d+$"},"geometry":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"Point"},"coordinates":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"maxItems":2000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"Polygon"},"coordinates":{"minItems":1,"maxItems":1,"type":"array","items":{"minItems":4,"maxItems":2001,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}}},"required":["type","coordinates"],"additionalProperties":false}]},"properties":{"default":{"color":"#5b4bff","width":4,"fillOpacity":0.25},"type":"object","properties":{"label":{"type":"string","maxLength":120},"color":{"default":"#5b4bff","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"width":{"default":4,"type":"integer","minimum":1,"maximum":50},"fillColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"fillOpacity":{"default":0.25,"type":"number","minimum":0,"maximum":1}},"additionalProperties":false}},"required":["type","geometry"],"additionalProperties":false}}},"required":["type","features"],"additionalProperties":false,"description":"A GeoJSON FeatureCollection with verified WGS84 coordinates, in longitude/latitude order."},"settings":{"type":"object","properties":{"center":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2},"zoom":{"type":"number","minimum":0,"maximum":22},"basemap":{"type":"string","enum":["carto","osm","opentopo"]}},"additionalProperties":false}},"required":["features"],"additionalProperties":false},"examples":{"point":{"value":{"features":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[2.2945,48.8584]},"properties":{"label":"Meeting point","color":"#5b4bff","width":4,"fillOpacity":0.25}}]}}},"line":{"value":{"features":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2.293,48.858],[2.2945,48.8584],[2.296,48.859]]},"properties":{"color":"#2563eb","width":6,"fillOpacity":0.25}}]}}},"polygon":{"value":{"features":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2.292,48.857],[2.297,48.857],[2.297,48.86],[2.292,48.86],[2.292,48.857]]]},"properties":{"color":"#15803d","width":3,"fillColor":"#22c55e","fillOpacity":0.3}}]}}},"event":{"value":{"features":{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[2.2945,48.8584]},"properties":{"label":"Meeting point","color":"#5b4bff","width":4,"fillOpacity":0.25}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2.293,48.858],[2.2945,48.8584],[2.296,48.859]]},"properties":{"color":"#2563eb","width":6,"fillOpacity":0.25}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2.292,48.857],[2.297,48.857],[2.297,48.86],[2.292,48.86],[2.292,48.857]]]},"properties":{"color":"#15803d","width":3,"fillColor":"#22c55e","fillOpacity":0.3}}]}}}}}}},"responses":{"200":{"description":"Independent url and embed_url, feature_count, url_length, encoded settings, and warnings. Coordinates use five decimal places. The url opens directly for editing and export in the browser."},"400":{"description":"Invalid JSON or missing idempotency key."},"413":{"description":"Request or map exceeds its size limit."},"415":{"description":"Content type must be application/json."},"422":{"description":"Invalid fields, feature geometry, or map state. No changes applied."},"429":{"description":"Anonymous request limit reached. Retry after the Retry-After interval."}}}},"/api/v1/places":{"get":{"security":[],"operationId":"lookupPlace","summary":"Find candidate coordinates for one named place or address","parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200}},{"name":"latitude","in":"query","description":"Optional search bias; supply longitude too.","schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","description":"Optional search bias; supply latitude too.","schema":{"type":"number","minimum":-180,"maximum":180}}],"responses":{"200":{"description":"Up to five candidates with names, addresses, longitude/latitude coordinates, source links, and attribution. An empty list means no matches. No map is saved."},"400":{"description":"Invalid JSON or missing idempotency key."},"401":{"description":"Missing, expired, or revoked token."},"403":{"description":"Insufficient scope, wrong map restriction, or Pro required."},"404":{"description":"Owned map not found."},"409":{"description":"Revision conflict or idempotency key reused for another request."},"410":{"description":"Original map was deleted after a successful create."},"413":{"description":"Request or map exceeds its size limit."},"415":{"description":"Content type must be application/json."},"422":{"description":"Invalid fields, feature geometry, or map state. No changes applied."},"428":{"description":"If-Match revision is required."},"429":{"description":"Anonymous place lookup limit reached. Retry after the Retry-After interval."},"502":{"description":"Place provider unavailable or returned invalid data."},"503":{"description":"Storage unavailable."}}}},"/api/v1/maps":{"post":{"operationId":"createMap","summary":"Create an editable saved map","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","maxLength":120},"visibility":{"default":"private","type":"string","enum":["public","private"]},"features":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","pattern":"^drawing:\\d+$"},"geometry":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"Point"},"coordinates":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"maxItems":2000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"Polygon"},"coordinates":{"minItems":1,"maxItems":1,"type":"array","items":{"minItems":4,"maxItems":2001,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}}},"required":["type","coordinates"],"additionalProperties":false}]},"properties":{"default":{"color":"#5b4bff","width":4,"fillOpacity":0.25},"type":"object","properties":{"label":{"type":"string","maxLength":120},"color":{"default":"#5b4bff","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"width":{"default":4,"type":"integer","minimum":1,"maximum":50},"fillColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"fillOpacity":{"default":0.25,"type":"number","minimum":0,"maximum":1}},"additionalProperties":false}},"required":["type","geometry"],"additionalProperties":false}}},"required":["type","features"],"additionalProperties":false},"settings":{"type":"object","properties":{"center":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2},"zoom":{"type":"number","minimum":0,"maximum":22},"basemap":{"type":"string","enum":["carto","osm","opentopo"]}},"additionalProperties":false}},"required":["title","features"],"additionalProperties":false}}}},"responses":{"201":{"description":"Saved map with revision, view/edit links, GeoJSON features, warnings, and per-feature write results.","content":{"application/json":{"schema":{"type":"object","required":["id","revision","view_url","edit_url","features","warnings"],"properties":{"id":{"type":"string"},"title":{"type":["string","null"]},"revision":{"type":"string"},"view_url":{"type":"string","format":"uri"},"edit_url":{"type":"string","format":"uri"},"features":{"type":"object"},"settings":{"type":"object"},"warnings":{"type":"array","items":{"type":"object"}},"feature_results":{"type":"array","items":{"type":"object"}},"cost_cents":{"const":0}}}}}},"400":{"description":"Invalid JSON or missing idempotency key."},"401":{"description":"Missing, expired, or revoked token."},"403":{"description":"Insufficient scope, wrong map restriction, or Pro required."},"404":{"description":"Owned map not found."},"409":{"description":"Revision conflict or idempotency key reused for another request."},"410":{"description":"Original map was deleted after a successful create."},"413":{"description":"Request or map exceeds its size limit."},"415":{"description":"Content type must be application/json."},"422":{"description":"Invalid fields, feature geometry, or map state. No changes applied."},"428":{"description":"If-Match revision is required."},"429":{"description":"Token write limit reached."},"503":{"description":"Storage unavailable."}}}},"/api/v1/maps/{id}":{"get":{"operationId":"getMap","summary":"Read the current saved map","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"}}],"responses":{"200":{"description":"Saved map with revision, view/edit links, GeoJSON features, warnings, and per-feature write results.","content":{"application/json":{"schema":{"type":"object","required":["id","revision","view_url","edit_url","features","warnings"],"properties":{"id":{"type":"string"},"title":{"type":["string","null"]},"revision":{"type":"string"},"view_url":{"type":"string","format":"uri"},"edit_url":{"type":"string","format":"uri"},"features":{"type":"object"},"settings":{"type":"object"},"warnings":{"type":"array","items":{"type":"object"}},"feature_results":{"type":"array","items":{"type":"object"}},"cost_cents":{"const":0}}}}}},"400":{"description":"Invalid JSON or missing idempotency key."},"401":{"description":"Missing, expired, or revoked token."},"403":{"description":"Insufficient scope, wrong map restriction, or Pro required."},"404":{"description":"Owned map not found."},"409":{"description":"Revision conflict or idempotency key reused for another request."},"410":{"description":"Original map was deleted after a successful create."},"413":{"description":"Request or map exceeds its size limit."},"415":{"description":"Content type must be application/json."},"422":{"description":"Invalid fields, feature geometry, or map state. No changes applied."},"428":{"description":"If-Match revision is required."},"429":{"description":"Token write limit reached."},"503":{"description":"Storage unavailable."}}},"patch":{"operationId":"updateMap","summary":"Update specified drawings, title, or view","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$"}},{"name":"If-Match","in":"header","required":true,"description":"The revision returned by the most recent read.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","maxLength":120},"add_features":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","pattern":"^drawing:\\d+$"},"geometry":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"Point"},"coordinates":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"maxItems":2000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"Polygon"},"coordinates":{"minItems":1,"maxItems":1,"type":"array","items":{"minItems":4,"maxItems":2001,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}}},"required":["type","coordinates"],"additionalProperties":false}]},"properties":{"default":{"color":"#5b4bff","width":4,"fillOpacity":0.25},"type":"object","properties":{"label":{"type":"string","maxLength":120},"color":{"default":"#5b4bff","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"width":{"default":4,"type":"integer","minimum":1,"maximum":50},"fillColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"fillOpacity":{"default":0.25,"type":"number","minimum":0,"maximum":1}},"additionalProperties":false}},"required":["type","geometry"],"additionalProperties":false}}},"required":["type","features"],"additionalProperties":false},"replace_features":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","pattern":"^drawing:\\d+$"},"geometry":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"Point"},"coordinates":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"LineString"},"coordinates":{"minItems":2,"maxItems":2000,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}},"required":["type","coordinates"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"Polygon"},"coordinates":{"minItems":1,"maxItems":1,"type":"array","items":{"minItems":4,"maxItems":2001,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2}}}},"required":["type","coordinates"],"additionalProperties":false}]},"properties":{"default":{"color":"#5b4bff","width":4,"fillOpacity":0.25},"type":"object","properties":{"label":{"type":"string","maxLength":120},"color":{"default":"#5b4bff","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"width":{"default":4,"type":"integer","minimum":1,"maximum":50},"fillColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"fillOpacity":{"default":0.25,"type":"number","minimum":0,"maximum":1}},"additionalProperties":false}},"required":["type","geometry"],"additionalProperties":false}}},"required":["type","features"],"additionalProperties":false},"settings":{"type":"object","properties":{"center":{"type":"array","prefixItems":[{"type":"number","minimum":-180,"maximum":180},{"type":"number","minimum":-90,"maximum":90}],"items":false,"minItems":2,"maxItems":2},"zoom":{"type":"number","minimum":0,"maximum":22},"basemap":{"type":"string","enum":["carto","osm","opentopo"]}},"additionalProperties":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"Saved map with revision, view/edit links, GeoJSON features, warnings, and per-feature write results.","content":{"application/json":{"schema":{"type":"object","required":["id","revision","view_url","edit_url","features","warnings"],"properties":{"id":{"type":"string"},"title":{"type":["string","null"]},"revision":{"type":"string"},"view_url":{"type":"string","format":"uri"},"edit_url":{"type":"string","format":"uri"},"features":{"type":"object"},"settings":{"type":"object"},"warnings":{"type":"array","items":{"type":"object"}},"feature_results":{"type":"array","items":{"type":"object"}},"cost_cents":{"const":0}}}}}},"400":{"description":"Invalid JSON or missing idempotency key."},"401":{"description":"Missing, expired, or revoked token."},"403":{"description":"Insufficient scope, wrong map restriction, or Pro required."},"404":{"description":"Owned map not found."},"409":{"description":"Revision conflict or idempotency key reused for another request."},"410":{"description":"Original map was deleted after a successful create."},"413":{"description":"Request or map exceeds its size limit."},"415":{"description":"Content type must be application/json."},"422":{"description":"Invalid fields, feature geometry, or map state. No changes applied."},"428":{"description":"If-Match revision is required."},"429":{"description":"Token write limit reached."},"503":{"description":"Storage unavailable."}}}}}}