LSD

Geogrid Map

Draw a finished geogrid scan on a street map and get it back as a PNG or WebP: one circle per grid point, numbered with its rank and coloured by it, with the business, keyword and headline numbers on top, ready to drop into a report or show in a chat.

When to use this

A grid of numbers is hard to read and harder to send to a client. This turns a scan you have already run into the picture everyone expects: the whole service area on a map, green where the business ranks in the top 3, red where it falls behind, grey where it is not found. Run the same scan again later and the map shows how far each point moved since the last one. Ask for it after the scan completes; the scan itself is not charged again.

POST/v1/geogrid/map
Cost: 2 credits ($0.01) per map. Refunded if the map cannot be drawn
Rate Limit: Varies by plan
Response: A few seconds, longer when the renderer starts cold. The scan must already be complete.

Parameters

ParameterTypeRequiredDescription
job_idstringYesThe job_id of a completed geogrid scan, from the scan submit or from geogrid status. It must belong to your account.
sizeintegerNo600, 800 or 1000. Default: 800
scaleintegerNoPixel density: 2 (default) draws twice size in pixels for sharing and print; 1 draws size in pixels for chat and email
formatstringNo"png" (default) or "webp", about a fifth of the size. With no format, Accept: image/webp picks webp
stylestringNo"light" or "dark". Default: "light"
comparebooleanNoShow the change since your previous scan of the same keyword, business, grid, zoom, radius and centre, when there is one. Default: true
compare_tostringNojob_id of a specific earlier scan to compare against instead, e.g. the first scan of an engagement; it applies even with compare false. Must be your own completed, older scan of the same keyword, business, grid size, zoom, radius and centre (409 otherwise, nothing charged)

Example Request

curl -X POST https://api.localseodata.com/v1/geogrid/map \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "geo_a1b2c3d4e5",
    "size": 800,
    "style": "light"
  }'

Example Response

JSON
{
  "status": "success",
  "credits_used": 2,
  "data": {
    "job_id": "geo_a1b2c3d4e5",
    "image_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
    "mime_type": "image/png",
    "width": 1600,
    "height": 1600,
    "style": "light",
    "format": "png",
    "business_name": "Joe's Plumbing",
    "keyword": "plumber",
    "atrp": 10.1,
    "found": 24,
    "points": 25,
    "compared_to": { "job_id": "geo_9z8y7x6w5v", "date": "2026-10-01T12:04:00.000Z", "atrp": 12.4 },
    "attribution": "© OpenMapTiles © OpenStreetMap contributors"
  }
}

Response Fields

FieldTypeDescription
job_idstringThe scan the map shows
image_base64stringThe image, base64 encoded
mime_typestring"image/png" or "image/webp"
widthintegerImage width in pixels: size times scale
heightintegerImage height in pixels: size times scale
stylestring"light" or "dark"
formatstring"png" or "webp"
business_namestringThe business the scan tracked
keywordstringThe scan's keyword
atrpnumberThe average rank on the map, with points where the business was not found counted as 21. The scan endpoints' average_rank counts found points only, so the two differ
foundintegerPoints where the business was found
pointsintegerGrid points drawn
compared_toobject | nullThe earlier scan the changes are against (job_id, date, atrp), or null when there was none or compare was false
attributionstringMap credit. Keep it with the image wherever it is shown

Notes

  • Each circle is numbered with the rank at that point and coloured: green for 1-3, lime for 4-7, orange for 8-10, red for 11 and below. Grey circles are points where the business was not found (–) or that could not be checked (?). The average rank in the header is the average over every answered point, with not found counted as 21.
  • When you have scanned the same keyword, business, grid size, zoom, radius and centre before, a small badge on each point shows how many places it moved since your most recent earlier scan (green up arrow improved, red down arrow slipped), and the header shows the average rank change. Pass compare: false to leave it out.
  • Send Accept: image/png (or image/webp) to get the image itself instead of JSON, with X-Request-Id, X-Credits-Used and X-Credits-Remaining headers. Useful for no-code tools that can't decode base64. Sandbox keys get the placeholder the same way.
  • A scan that is still running returns a 409 job_not_complete, and a failed scan a 409 job_failed; neither costs anything. Collect a running scan with geogrid status first.
  • A compare_to scan that hasn't completed, isn't older, or isn't the same scan returns a 409 (baseline_not_complete, baseline_not_earlier or baseline_mismatch) and costs nothing. The automatic comparison looks at your 20 most recent earlier scans of the same keyword, grid and business.
  • If the map can't be drawn the call is refunded: 502 or 504 when drawing failed or timed out, 503 when the renderer is busy (try again shortly), and 500 map_render_failed when this scan can't be drawn at all (send support the request_id).
  • A job_id that does not exist or belongs to another account returns job_not_found.
  • The map is drawn for each request and not stored, so ask again whenever you need it. Each request is charged.
  • Returns 503 not_configured, with nothing charged, on a deployment where maps are not turned on. Sandbox keys (sk_test_) get a 1x1 placeholder image, free.