Proximitii Book a Demo

Crime Riskmap API Documentation

Request PNG crime risk tiles for an overlay on your existing web map. Read the installation details, parameters and examples.

The Proximitii Crime Riskmap API adds a crime risk overlay to an existing web map. It returns one PNG tile per request. Your map library selects the visible tiles as visitors pan and zoom; your server requests each tile with your Proximitii API keys and sends the PNG to the browser. Keep the private key on your server.

Show Crime data: CrimeoMeter in the map attribution, retain your basemap provider's attribution, and place the Powered by Proximitii attribution directly below the map.

Example Calls

Step 1: Serve tiles from your server (Node.js / Express)

Add this route to your existing Express application. Replace requireAuthenticatedUser with access control appropriate for your site. The route belongs on the same origin as your map page.

app.get('/your-backend/crime-riskmap/:z/:x/:y.png', requireAuthenticatedUser, async (req, res) => {
  const { z, x, y } = req.params;
  const params = new URLSearchParams({ z, x, y });

  try {
    const response = await fetch(
      `https://api.proximitii.com/v1/crime-riskmap/?${params}`,
      {
        method: 'GET',
        headers: {
          'Public-Key': process.env.PROXIMITII_PUBLIC_KEY,
          'Private-Key': process.env.PROXIMITII_PRIVATE_KEY
        }
      }
    );

    res.set('Cache-Control', 'no-store');

    if (!response.ok) {
      const body = await response.json().catch(() => null);
      const retryAfter = response.headers.get('Retry-After');
      if (retryAfter) res.set('Retry-After', retryAfter);
      return res.status(response.status).json(
        body || { status: { code: String(response.status), message: 'Riskmap tile failed' } }
      );
    }

    res.type('png').send(Buffer.from(await response.arrayBuffer()));
  } catch (error) {
    res.status(502).json({ status: { code: '502', message: 'Riskmap tile request failed' } });
  }
});

Step 2: Add the overlay to an existing Leaflet map (browser)

Use your backend route from Step 1 as the tile URL. Leaflet fills in {z}, {x}, and {y} for each visible tile.

map.setView([40.7788, -73.9810], 14); // [latitude, longitude]

const crimeOverlay = L.tileLayer('/your-backend/crime-riskmap/{z}/{x}/{y}.png', {
  maxZoom: 19,
  opacity: 0.82,
  attribution: 'Crime data: CrimeoMeter'
}).addTo(map);

The browser requests tiles from your backend route. Apply your normal access control and rate limiting there; never put the Proximitii private key in browser code.

Keys

Use your existing active Proximitii public and private API keys. Send Public-Key and Private-Key headers with each server-side tile request. No separate CrimeoMeter key is required. This endpoint does not issue a browser tile session.

Values

For a map overlay, request tiles with z, x, and y:

NameDescriptionDefault ValueAccepted ValuesVariable
Tile endpointReturns one PNG tile.N/AGET /v1/crime-riskmap/?z={z}&x={x}&y={y}N/A
ZoomMap zoom level.Required for tile requestsInteger from 0 to 22z
Tile columnHorizontal tile coordinate at the selected zoom.RequiredInteger from 0 to 2z - 1x
Tile rowVertical tile coordinate at the selected zoom.RequiredInteger from 0 to 2z - 1y

To request only the tile containing one point, send lat and lon instead of x and y:

NameDescriptionDefault ValueAccepted ValuesVariable
LatitudePoint within the requested tile.Required in point modeDecimal from -85.05112878 to 85.05112878lat
LongitudePoint within the requested tile.Required in point modeDecimal from -180 to 180lon
ZoomZoom level for the point's tile.14Integer from 0 to 22z

Example single-point request: GET /v1/crime-riskmap/?lat=40.7788&lon=-73.9810&z=14. This returns one tile, so use z/x/y requests for a full map. Send a complete x/y pair or a complete lat/lon pair. The endpoint also accepts POST with these values in a JSON body.

Sample Output

A successful response contains PNG image bytes, not a JSON document:

HTTP/1.1 200 OK
Content-Type: image/png
X-Cache: MISS

[PNG image bytes]

X-Cache is HIT or MISS. Errors return JSON; for example, an invalid coordinate returns:

{
  "status": { "code": "400", "message": "Bad Request" }
}

Other possible errors include 401 for invalid keys, 403 for an inactive account or unauthorized domain, 429 when the rate limit is reached, and 503 when the service is unavailable. A 429 response includes Retry-After. After authentication, the API also sends X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.