Nordsat API Documentation

TMS Integration — Connect your Transport Management System to Nordsat

Overview

The Nordsat Integration API allows your TMS to create orders, build routes, assign drivers, and receive real-time status updates via webhooks. The driver workflow is handled through the Nordsat Driver App.

Base URL: https://nordsat.vercel.app/api/integration

Format: All requests and responses use JSON. Set Content-Type: application/json for all POST/PATCH requests.

Authentication

All integration endpoints require an API key. API keys are managed in the Nordsat dashboard under Settings > API Keys for Integrations.

Include your key in the X-API-Key header:

curl -H "X-API-Key: CTRK.YOUR_KEY_HERE" \
  https://nordsat.vercel.app/api/integration/orders

Scopes

ScopeAllows
readGET requests (query orders, routes, drivers, locations, history)
writePOST, PATCH, DELETE requests (create/update orders, routes, drivers)

When creating an API key, select the scopes you need. For full TMS integration, use ["read", "write"].

Integration Workflow

1

Create orders in your TMS

Assign vehicles to delivery points with addresses, cargo types, and delivery dates.

2

Upload data to Nordsat

Use POST /api/integration/orders to transfer all details automatically.

3

Create a route on Nordsat

Use POST /api/integration/routes to build routes combining loading/unloading tasks with rest stops.

4

Send the route to the driver

The driver opens /driver.html and follows the task sequence with turn-by-turn navigation.

5

Monitor task progress

Use the Task Map in the dispatcher panel or poll GET /api/integration/orders for real-time status.

6

Synchronise with TMS

Register webhooks to receive order.status_changed and order.completed events, or poll the orders endpoint.

Orders

Orders represent delivery tasks. Each order can optionally be linked to a tracking device and assigned to a driver.

POST/api/integration/orders

Create one or more orders from your TMS.

Scope: write

{
  "orders": [
    {
      "externalId": "TMS-ORD-12345",
      "reference": "ORD-12345",
      "deviceId": "868373079552768",
      "driverId": "driver-abc123",
      "pickupAddress": "Warehouse A, Helsinki",
      "deliveryAddress": "Customer B, Espoo",
      "pickupLat": 60.1699,
      "pickupLng": 24.9384,
      "deliveryLat": 60.2055,
      "deliveryLng": 24.6559,
      "cargoType": "electronics",
      "weight": "250 kg",
      "plannedPickup": "2026-02-22T08:00:00Z",
      "plannedDelivery": "2026-02-22T12:00:00Z",
      "priority": "high",
      "notes": "Fragile cargo, handle with care"
    }
  ]
}

Response (201):

{
  "created": [
    { "externalId": "TMS-ORD-12345", "orderId": "order-1740...", "status": "planned" }
  ],
  "count": 1
}

GET/api/integration/orders

Query orders with filters. Returns current device telemetry alongside each order.

Scope: read

ParameterTypeDescription
statusstringFilter by status: planned, in_transit, arrived, delayed, missed
externalIdstringFilter by your TMS external ID
driverIdstringFilter by driver
fromISO dateCreated after this date
toISO dateCreated before this date
limitintMax results (default 500, max 5000)
curl -H "X-API-Key: CTRK.YOUR_KEY" \
  "https://nordsat.vercel.app/api/integration/orders?status=in_transit"

PATCH/api/integration/orders

Update an order's status, driver, or priority.

Scope: write

{
  "orderId": "order-1740...",
  "status": "in_transit",
  "driverId": "driver-abc123"
}

DELETE/api/integration/orders?id=order-1740...

Cancel an order (sets status to "cancelled").

Scope: write

Routes

Routes combine multiple orders into an ordered sequence of stops for a driver, including rest breaks or fuel stations.

POST/api/integration/routes

Create a route plan with ordered stops. The system calculates total distance and estimated duration automatically.

Scope: write

{
  "driverId": "driver-abc123",
  "date": "2026-02-22",
  "stops": [
    {
      "orderId": "order-1740...",
      "type": "pickup",
      "address": "Warehouse A, Helsinki",
      "lat": 60.1699,
      "lng": 24.9384,
      "plannedArrival": "2026-02-22T08:00:00Z",
      "plannedDeparture": "2026-02-22T08:30:00Z"
    },
    {
      "type": "fuel",
      "address": "Neste Station, Ring I",
      "lat": 60.1872,
      "lng": 24.8103,
      "notes": "Refuel before long leg"
    },
    {
      "orderId": "order-1740...",
      "type": "delivery",
      "address": "Customer B, Espoo",
      "lat": 60.2055,
      "lng": 24.6559,
      "plannedArrival": "2026-02-22T11:30:00Z"
    }
  ]
}

Response (201):

{
  "routeId": "rp-1740...",
  "driverId": "driver-abc123",
  "date": "2026-02-22",
  "totalDistanceKm": 28.4,
  "totalDurationMin": 34,
  "stops": [ ... ]
}

GET/api/integration/routes

List route plans with optional filters.

Scope: read

ParameterDescription
driverIdFilter by driver
dateFilter by date (YYYY-MM-DD)
statusFilter by status (draft, active, completed)

Drivers

GET/api/integration/drivers

List all drivers for your tenant.

Scope: read

POST/api/integration/drivers

Create or update a driver.

Scope: write

{
  "name": "John Smith",
  "email": "john@company.com",
  "phone": "+358 40 123 4567",
  "vehiclePlate": "ABC-123",
  "vehicleType": "truck",
  "capacity": "1000 kg"
}

Locations (Live Telemetry)

GET/api/integration/locations

Get the latest GPS position, battery, temperature, and speed for all devices in your fleet.

Scope: read

curl -H "X-API-Key: CTRK.YOUR_KEY" \
  https://nordsat.vercel.app/api/integration/locations

Telemetry History

GET/api/integration/history

Get historical telemetry points for a specific device within a time range.

Scope: read

ParameterRequiredDescription
deviceIdYesDevice ID or IMEI
fromNoStart time (ISO, default: 24h ago)
toNoEnd time (ISO, default: now)
limitNoMax points (default: 2000, max: 10000)

Webhooks

Register webhook URLs to receive real-time notifications when order statuses change, deliveries complete, or route deviations are detected.

Event Types

EventTriggered When
order.status_changedAny status change (planned → in_transit → arrived, etc.)
order.completedOrder is marked as delivered/arrived
order.deviatedDevice is detected off the planned route corridor
route.startedDriver begins executing a route plan
route.completedAll stops in a route are completed

Register a Webhook

Webhooks are managed via the dashboard (session-authenticated, not API key).

POST /api/webhooks
{
  "url": "https://your-tms.com/nordsat-webhook",
  "events": ["order.status_changed", "order.completed"],
  "secret": "your-signing-secret"
}

Payload Format

Each webhook delivery is a POST request to your registered URL:

{
  "event": "order.status_changed",
  "timestamp": "2026-02-22T10:30:00.000Z",
  "data": {
    "orderId": "order-1740...",
    "externalId": "TMS-ORD-12345",
    "status": "in_transit",
    "previousStatus": "planned",
    "driverId": "driver-abc123"
  }
}

Verifying Signatures

Each request includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the request body using your registered secret:

const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return expected === signature;
}

Error Codes

CodeMeaning
400Bad request — missing or invalid parameters
401Unauthorized — missing or invalid API key
403Forbidden — API key lacks the required scope
404Not found — resource does not exist
405Method not allowed
413Payload too large
500Internal server error

All error responses follow this format:

{ "error": "Description of the error" }