DocsJavaScript / Node.js

Server Integration — Node.js / Express

A minimal Express server that exposes PickPoint to your frontend via @pickpoint/sdk. The API key lives in an environment variable and never reaches the client.

1

Install dependencies

npm install express ws @pickpoint/sdk dotenv
2

Environment variables

# .env
PICKPOINT_KEY=your_key_here
PORT=3000

Load with dotenv/config in development. In production set the variable in your hosting environment - never commit .env to git.

3

SDK client

// server.js
import express from 'express';
import { PickPoint } from '@pickpoint/sdk';
import 'dotenv/config';

const app = express();
app.use(express.json());

const pp = new PickPoint({ apiKey: process.env.PICKPOINT_KEY });
4

Geocoding endpoints

Query parameters from the client are passed straight to the SDK:

// ── Geocoding ──────────────────────────────────────────────────────────────

// Forward:  GET /geo/forward?q=Eiffel+Tower&limit=5
app.get('/geo/forward', async (req, res) => {
  try {
    res.json(await pp.forward(req.query));
  } catch (e) {
    res.status(e.status ?? 502).json({ error: e.message });
  }
});

// Reverse:  GET /geo/reverse?lat=48.85&lon=2.29&zoom=18
app.get('/geo/reverse', async (req, res) => {
  try {
    res.json(await pp.reverse(req.query));
  } catch (e) {
    res.status(e.status ?? 502).json({ error: e.message });
  }
});

// Search:   GET /geo/search?q=Baker+St&viewbox=…
app.get('/geo/search', async (req, res) => {
  try {
    res.json(await pp.search(req.query));
  } catch (e) {
    res.status(e.status ?? 502).json({ error: e.message });
  }
});
5

Routing endpoints

// ── Routing ───────────────────────────────────────────────────────────────

// Route:           POST /route  { locations, costing, … }
app.post('/route', async (req, res) => {
  try {
    res.json(await pp.route(req.body));
  } catch (e) {
    res.status(e.status ?? 502).json({ error: e.message });
  }
});

// Optimized route: POST /route/optimized
app.post('/route/optimized', async (req, res) => {
  try {
    res.json(await pp.optimizedRoute(req.body));
  } catch (e) {
    res.status(e.status ?? 502).json({ error: e.message });
  }
});
6

Device tracking - REST

// ── Device tracking - REST ────────────────────────────────────────────────

// List devices: GET /devices
app.get('/devices', async (req, res) => {
  try {
    res.json(await pp.devices.list(req.query));
  } catch (e) {
    res.status(e.status ?? 502).json({ error: e.message });
  }
});

app.listen(process.env.PORT || 3000);

Track history is REST-only today — see the Device Tracking guide for the GET /v2/devices/:uid/tracks curl example.

7

Device tracking - WebSocket subscriber relay

Your server mints a client token, subscribes with @pickpoint/sdk/tracking, and fans events out to browser clients over a plain WebSocket:

// ── Device tracking - WebSocket subscriber relay ─────────────────────────
import { WebSocketServer } from 'ws';
import { connect } from '@pickpoint/sdk/tracking';

const wss = new WebSocketServer({ port: 3001 });

async function mintToken() {
  // Client-token mint is server-side only (no JS SDK helper yet)
  const r = await fetch('https://api.pickpoint.io/v2/client-tokens', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.PICKPOINT_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ scopes: ['devices'], ttlSec: 600 }),
  });
  const { accessToken } = await r.json();
  return accessToken;
}

wss.on('connection', async (client, req) => {
  const deviceUid = new URL(req.url, 'http://x').searchParams.get('deviceUid');
  if (!deviceUid) { client.close(1008, 'deviceUid required'); return; }

  const session = await connect({
    endpoint: 'wss://tracking.pickpoint.io',
    auth: { accessToken: await mintToken() },
    subscribe: deviceUid,
    reconnect: false,
  });

  const off = session.on('location', (msg) => {
    if (client.readyState === 1) client.send(JSON.stringify(msg.point));
  });

  client.on('close', () => { off(); session.close(); });
});

← OverviewPython →