Authentication All API requests require a Bearer token in the Authorization header:
HTTP HeaderCopy
Authorization: Bearer tk_test_your_key_hereTest vs Live keys: Test keys (tk_test_*) work in sandbox mode. Live keys (tk_live_*) create real deliveries.
Quick Start Get live delivery tracking running in 5 minutes.
Step 1: Create a delivery When a customer places an order, create a delivery to get a tracking URL:
typescriptCopy
const response = await fetch ('https://trackkitapi-production.up.railway.app/v1/deliveries' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer tk_test_your_key' ,
'Content-Type' : 'application/json'
},
body: JSON.stringify ({
pickup: { address: 'Chicken Republic, Yaba, Lagos, Nigeria' },
dropoff: { address: '12 Adeola Odeku, VI, Lagos, Nigeria' },
externalId: 'ORDER-9842' ,
metadata: {
customerName: 'Tunde' ,
items: ['Jollof Rice x2' , 'Chicken x1' ]
}
})
})
const delivery = await response.json ()
// { id, trackingCode: "TK-J8K2M1", trackingUrl, status: "PENDING", eta }
// Send tracking link to customer
sendSMS (customer.phone, `Track your order: ${delivery.trackingUrl}`)Step 2: Assign a driver typescriptCopy
await fetch (`https://trackkitapi-production.up.railway.app/v1/deliveries/${delivery.id}/assign` , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer tk_test_your_key' ,
'Content-Type' : 'application/json'
},
body: JSON.stringify ({ driverId: 'driver_456' })
})Step 3: Stream driver location Call this from the driver app every 5-10 seconds:
typescript — driver appCopy
navigator.geolocation.watchPosition (async (pos) => {
await fetch (`https://trackkitapi-production.up.railway.app/v1/deliveries/${deliveryId}/location` , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer tk_test_your_key' ,
'Content-Type' : 'application/json'
},
body: JSON.stringify ({
lat: pos.coords.latitude,
lng: pos.coords.longitude,
speed: pos.coords.speed,
heading: pos.coords.heading
})
})
}, null , { enableHighAccuracy: true })Step 4: Customer sees live tracking The customer clicks the tracking URL and sees a real-time map with driver location, ETA countdown, status updates, and your branding. No code needed on the customer side.
Step 5: Receive webhooks typescriptCopy
await fetch ('https://trackkitapi-production.up.railway.app/v1/webhooks' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer tk_test_your_key' ,
'Content-Type' : 'application/json'
},
body: JSON.stringify ({
url: 'https://yourapp.com/webhooks/trackkit' ,
events: ['delivery.status_changed' , 'delivery.driver_assigned' ]
})
})Deliveries API Full CRUD for deliveries with automatic geocoding, routing, and ETA calculation.
POST /v1/deliveriesCreate delivery
GET /v1/deliveriesList deliveries
GET /v1/deliveries/:idGet delivery
PATCH /v1/deliveries/:id/statusUpdate status
POST /v1/deliveries/:id/locationUpdate driver location
POST /v1/deliveries/:id/assignAssign driver
Create Delivery — Request Body jsonCopy
{
"pickup" : { "address" : "Yaba Tech, Lagos, Nigeria" },
"dropoff" : { "address" : "Victoria Island, Lagos, Nigeria" },
"externalId" : "ORDER-123" , // optional: your own order ID
"driverId" : "driver_456" , // optional: assign immediately
"metadata" : { "any" : "data" } // optional: arbitrary JSON
}You can pass lat/lng instead of address for pickup/dropoff. If only an address is provided, it's geocoded automatically via Nominatim. Append "Nigeria" for best results with Lagos addresses.
Status Transitions valid statusesCopy
CONFIRMED · DRIVER_ASSIGNED · PICKUP_EN_ROUTE · PICKED_UP · DELIVERING · ARRIVING · DELIVERED · CANCELLEDDrivers API Manage your driver fleet. Track online status and location.
POST /v1/driversCreate driver
GET /v1/driversList drivers
GET /v1/drivers/:idGet driver
POST /v1/drivers/:id/locationUpdate location
PATCH /v1/drivers/:id/statusSet online/offline
Create Driver jsonCopy
{
"name" : "Emeka Obi" ,
"phone" : "+2348012345678" , // optional
"externalId" : "DRV-100" // optional: your own driver ID
}Webhooks Get notified when delivery events happen. All payloads are signed with HMAC-SHA256.
POST /v1/webhooksRegister webhook
GET /v1/webhooksList webhooks
DELETE /v1/webhooks/:idDelete webhook
Webhook Payload jsonCopy
{
"event" : "delivery.status_changed" ,
"data" : {
"id" : "clx7abc123" ,
"trackingCode" : "TK-J8K2M1" ,
"status" : "DELIVERED" ,
"previousStatus" : "ARRIVING"
},
"timestamp" : "2026-03-20T14:30:00Z" ,
"id" : "wh_1710940200_abc123"
}Verify Signature Every webhook includes an x-trackkit-signature header:
typescriptCopy
const signature = request.headers['x-trackkit-signature' ]
const expected = crypto
.createHmac ('sha256' , webhookSecret)
.update (JSON.stringify (request.body))
.digest ('hex' )
if (`sha256=${expected}` !== signature) {
return res.status (401 ).send ('Invalid signature' )
}EVENT FIRED WHEN
delivery.created New delivery created
delivery.status_changed Status transitions
delivery.driver_assigned Driver assigned to delivery
delivery.location_updated Driver location update received
Live Tracking Customers can track deliveries in real-time via WebSocket or the tracking URL.
Tracking URL Every delivery returns a trackingUrl. Share it with your customer via SMS, WhatsApp, or email. They see a live map with driver location, ETA, and status — branded with your logo and colors.
WebSocket Connect to the WebSocket endpoint for real-time updates in your own UI:
javascriptCopy
const ws = new WebSocket ('wss://trackkitapi-production.up.railway.app/ws/track/TK-J8K2M1' )
ws.onmessage = (event) => {
const msg = JSON.parse (event.data)
if (msg.type === 'location' ) {
// { lat, lng, heading, speed, eta, distance }
updateMap(msg.data)
}
if (msg.type === 'status' ) {
// { status: "DELIVERING", eta: 8 }
updateStatus(msg.data)
}
}Status Flow PENDING → CONFIRMED → DRIVER_ASSIGNED → PICKUP_EN_ROUTE → PICKED_UP → DELIVERING → ARRIVING → DELIVERED
Any status can also transition to CANCELLED
Rate Limits Rate limits are enforced per tenant (API key), not per IP address.
PLAN DELIVERIES/MO API CALLS/MIN WEBHOOKS
Free 500 100 1
Growth ($49/mo) 5,000 500 5
Scale ($199/mo) 50,000 2,000 20
Managed (custom) Unlimited 10,000 100
When you exceed the delivery limit, the API returns 429 limit_exceeded. Delivery counts reset automatically on the 1st of each month.
JavaScript / TypeScript SDK The official SDK wraps the REST API and WebSocket for easy integration.
bashCopy
npm install trackkit-sdktypescriptCopy
import TrackKit from 'trackkit-sdk'
const tk = new TrackKit ({ apiKey: 'tk_live_your_key' })
// Create a delivery
const delivery = await tk.deliveries.create ({
pickup: { address: 'Yaba Tech, Lagos, Nigeria' },
dropoff: { address: 'Victoria Island, Lagos, Nigeria' },
metadata: { orderId: 'ORD-123' }
})
// Update driver location
await tk.deliveries.updateLocation (delivery.id, {
lat: 6.4738 , lng: 3.3952 , speed: 35
})
// Real-time tracking
const unsub = tk.realtime.subscribe (delivery.trackingCode, {
onLocation : (data) => console.log ('Driver at:' , data.lat, data.lng),
onStatus : (data) => console.log ('Status:' , data.status),
})Published on npm as
trackkit-sdk . Supports both CommonJS and ESM. Full TypeScript types included.