Features Pricing
Open App
Home Documentation Overview

SafiTrack Documentation

v1.4.0  ·  Mar 2026

Everything you need to integrate SafiTrack into your workflow — from quick-start guides to full API references and SDK examples. If you get stuck, the Help Center and API Reference have you covered.

Quick Start

Get your team set up in under 10 minutes. You'll need an active SafiTrack account — sign up here if you don't have one yet.

  1. Create your workspace — sign in at /crm/ and complete the onboarding flow. It takes about 2 minutes.
  2. Import contacts — upload a CSV (max 50,000 rows) or connect a Google Sheet from Settings → Integrations.
  3. Add companies and assign reps — companies can be created manually or synced via the REST API.
  4. Log your first visit — open the mobile app, tap New Visit, pick a company, and tap Save. GPS coordinates are captured automatically.
  5. Create a route plan — from the web dashboard go to Route Plans → New, select up to 25 stops, and tap Optimise.
Tip

Use the Chrome extension to import contacts directly from LinkedIn or your CRM while browsing. Install it from Settings → Extensions.

Authentication

SafiTrack uses Supabase Auth under the hood. All API calls require a short-lived JWT Bearer token obtained after sign-in. Tokens expire after 1 hour — use the refresh token to get a new one without re-authenticating.

Obtain a token

bash
curl -X POST "https://ndrkncirkekpqjjkasiy.supabase.co/auth/v1/token?grant_type=password" \
  -H "apikey: YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"you@company.com","password":"yourpassword"}'

The response includes access_token, refresh_token, and expires_in. Pass the access token in every subsequent request:

bash
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Security note

Never commit your ANON_KEY or access_token to version control. Store secrets in environment variables or a secrets manager.

Contacts & Companies

Every person and business in your pipeline lives in SafiTrack's contact graph. The contacts table stores individuals; companies stores organisations. A contact can belong to multiple companies via the contact_companies join table.

Fetch companies

javascript
const { data, error } = await supabase
  .from('companies')
  .select('id, name, industry, owner_id, created_at')
  .order('created_at', { ascending: false })
  .limit(50);

if (error) throw error;
console.log(data); // [{ id: 'co_...', name: 'Acme Ltd', ... }]

Create a contact

javascript
const { data, error } = await supabase
  .from('contacts')
  .insert({
    first_name: 'Jane',
    last_name:  'Mwangi',
    email:      'jane@acme.co',
    phone:      '+254712345678',
    company_id: 'co_abc123',
    owner_id:   'rep_xyz789'
  })
  .select()
  .single();

Bulk import via CSV

Navigate to Contacts → Import in the dashboard and upload a .csv file. Supported columns:

Column Type Notes
first_name required string Max 100 chars
last_name string Max 100 chars
email required string Must be valid email format
phone string E.164 format recommended
company_name string Auto-matched or created if new
tags string Comma-separated, e.g. vip,renewal

Sales Visits

Visit records are the core data unit in SafiTrack. Each visit captures GPS coordinates, duration, structured outcome, free-text notes, and optional photo attachments. Visits power AI summaries in the Intelligence Hub and the weekly performance digest emails.

Visit object

Field Type Description
id string UUID, auto-generated
rep_id string ID of the rep who made the visit
company_id string Company visited
contact_id string Primary contact met (optional)
lat / lng float GPS coordinates at check-in
duration_mins integer Duration in minutes
outcome enum demo_booked · follow_up · no_contact · closed_won
notes string Free-text, max 5,000 chars
visited_at timestamp ISO 8601, defaults to now
Note

GPS coordinates are captured automatically when using the mobile app. When creating visits via the API, you may pass lat/lng manually or omit them.

Route Plans

A route plan is an ordered list of stops (companies or GPS waypoints) that SafiTrack's optimisation engine sequences for minimum travel time. Route plans can be created in the dashboard or via the API and are pushed to the mobile app automatically.

javascript
// Create and optimise a route plan
const { data } = await supabase
  .from('route_plans')
  .insert({
    name:       'Nairobi East — Tue 4 Mar',
    rep_id:     'rep_xyz789',
    date:       '2026-03-04',
    stops:      [
      { company_id: 'co_001', priority: 1 },
      { company_id: 'co_002', priority: 2 },
      { company_id: 'co_003', priority: 1 }
    ],
    optimise:   true  // triggers server-side TSP optimisation
  })
  .select()
  .single();

Opportunities

Opportunities track deals through a configurable Kanban pipeline. Each opportunity belongs to one company and one owner, and moves through stages you define in Settings → Pipeline.

Opportunity fields include title, value (currency amount), stage, close_date, probability (0–100), and notes. The Intelligence Hub surfaces stalled opportunities automatically when a deal hasn't moved stages in 14+ days.

Reminders & Tasks

Reminders are time-based notifications attached to contacts, companies, or opportunities. Tasks are checklist items within a visit or deal. Both are synced to the mobile app and can optionally fire email or push notifications.

javascript
// Create a follow-up reminder
const { data } = await supabase
  .from('reminders')
  .insert({
    title:       'Follow up on demo',
    contact_id:  'ct_111',
    company_id:  'co_001',
    due_at:      '2026-03-06T09:00:00Z',
    notify_push: true,
    notify_email: false
  })
  .select()
  .single();

Webhooks

Subscribe to real-time events using webhook endpoints. SafiTrack sends a signed POST request to your URL whenever a trigger fires. Each request includes an X-SafiTrack-Signature header — a HMAC-SHA256 of the raw body using your webhook secret.

Available events

Event Fires when
visit.completed A rep saves a completed visit
opportunity.stage_changed An opportunity moves to a new pipeline stage
contact.created A new contact is added (any source)
route_plan.started A rep begins navigating a route plan
reminder.due A reminder's due_at timestamp is reached

Example payload

json
{
  "event":     "visit.completed",
  "timestamp": "2026-03-01T09:41:22Z",
  "version":   "1",
  "data": {
    "visit_id":   "vis_abc123",
    "rep_id":     "rep_456",
    "company_id": "co_789",
    "outcome":    "demo_booked",
    "lat":         -1.2921,
    "lng":         36.8219,
    "duration_mins": 28
  }
}

Verify the signature

javascript
import crypto from 'crypto';

function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

SDKs

SafiTrack exposes its data via the Supabase JS and Python clients. Install them with your package manager:

bash
# JavaScript / TypeScript
npm install @supabase/supabase-js

# Python
pip install supabase
python
from supabase import create_client

url  = "https://ndrkncirkekpqjjkasiy.supabase.co"
key  = "YOUR_ANON_KEY"
client = create_client(url, key)

# Fetch visits for a rep
response = (
    client.table("visits")
    .select("*")
    .eq("rep_id", "rep_456")
    .order("visited_at", desc=True)
    .limit(20)
    .execute()
)
print(response.data)

Changelog

v1.4.0 March 2026 Latest
  • Intelligence Hub: AI visit summaries and rep coaching suggestions
  • Bulk contact import — up to 50,000 rows, with duplicate detection
  • Webhook delivery retries with exponential back-off (up to 5 attempts)
  • Python SDK now officially supported
v1.3.0 October 2025
  • Route plan optimisation engine (TSP-based, up to 25 stops)
  • Territory management UI with polygon drawing on maps
  • Google Calendar two-way sync for reminders and tasks
  • Custom pipeline stages in Settings → Pipeline
v1.2.0 August 2025
  • Opportunities Kanban board with drag-and-drop stage changes
  • Custom fields on contacts and companies (text, number, date, select)
  • CSV export for all entities including visits and call logs
  • Role-based access control — Manager, Rep, Read-only
v1.0.0 May 2025
  • Initial public launch
  • Core CRM: contacts, companies, visits, reminders, call logs
  • iOS and Android mobile apps
  • REST API and Supabase JS SDK support