Quick Start Guide

Get started with the Flotac REST API in 5 minutes.

Prerequisites

  • Node.js 14+ or Python 3.8+ (or any HTTP client)
  • Flotac account with company access
  • API key or Supabase credentials

Step 1: Get Your API Key

Option A: Use an Existing API Key

If your company administrator has provided you with an API key:

export FLOTAC_API_KEY="flotac_api_key_live_..."

Option B: Generate an API Key (Admins Only)

Contact your system administrator to generate an API key for your company.

Option C: Use Supabase Auth (For User Applications)

If building a user-facing application, authenticate via Supabase:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  'https://chwjbbvcqsxxgaytqlix.supabase.co',
  'YOUR_ANON_KEY'
);

const { data } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'password'
});

const jwt = data.session.access_token;

Step 2: Make Your First API Call

List Customers

cURL:

curl -X GET "https://chwjbbvcqsxxgaytqlix.supabase.co/functions/v1/api-gateway/api/v1/customers" \
  -H "Authorization: Bearer $FLOTAC_API_KEY" \
  -H "Content-Type: application/json"

JavaScript/Node.js:

const BASE_URL = 'https://chwjbbvcqsxxgaytqlix.supabase.co/functions/v1/api-gateway';
const FLOTAC_API_KEY = process.env.FLOTAC_API_KEY;

async function listCustomers() {
  const response = await fetch(`${BASE_URL}/api/v1/customers`, {
    headers: {
      'Authorization': `Bearer ${FLOTAC_API_KEY}`,
      'Content-Type': 'application/json'
    }
  });

  const result = await response.json();

  if (result.success) {
    console.log('Customers:', result.data);
    console.log('Total:', result.meta.pagination.totalRecords);
  } else {
    console.error('Error:', result.error);
  }
}

listCustomers();

Python:

import os
import requests

BASE_URL = 'https://chwjbbvcqsxxgaytqlix.supabase.co/functions/v1/api-gateway'
FLOTAC_API_KEY = os.environ['FLOTAC_API_KEY']

def list_customers():
    response = requests.get(
        f'{BASE_URL}/api/v1/customers',
        headers={'Authorization': f'Bearer {FLOTAC_API_KEY}'}
    )

    result = response.json()

    if result.get('success'):
        print('Customers:', result['data'])
        print('Total:', result['meta']['pagination']['totalRecords'])
    else:
        print('Error:', result['error'])

list_customers()

Expected Response:

{
  "success": true,
  "data": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Acme Transportation",
      "customer_type": "fleet",
      "email": "contact@acme.com",
      "phone": "+1-555-0100",
      "status": "active",
      "created_at": "2025-10-01T10:00:00Z"
    }
  ],
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2025-10-14T12:00:00Z",
    "version": "v1",
    "pagination": {
      "page": 1,
      "pageSize": 25,
      "totalPages": 1,
      "totalRecords": 1,
      "hasNextPage": false,
      "hasPreviousPage": false
    }
  }
}

Step 3: Create a Resource

Create a New Customer

JavaScript:

async function createCustomer() {
  const newCustomer = {
    name: 'Blue Sky Logistics',
    customer_type: 'fleet',
    email: 'contact@bluesky.com',
    phone: '+1-555-0200',
    status: 'active',
    billing_address: {
      street: '123 Main St',
      city: 'Springfield',
      state: 'IL',
      zip: '62701'
    }
  };

  const response = await fetch(`${BASE_URL}/api/v1/customers`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${FLOTAC_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(newCustomer)
  });

  const result = await response.json();

  if (result.success) {
    console.log('Created customer:', result.data);
    return result.data.id;
  } else {
    console.error('Error:', result.error);
  }
}

Step 4: Update and Delete

Update a Customer

async function updateCustomer(customerId) {
  const updates = {
    phone: '+1-555-0999',
    status: 'inactive'
  };

  const response = await fetch(`${BASE_URL}/api/v1/customers/${customerId}`, {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${FLOTAC_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(updates)
  });

  const result = await response.json();
  console.log('Updated customer:', result.data);
}

Delete a Customer (Soft Delete)

async function deleteCustomer(customerId) {
  const response = await fetch(`${BASE_URL}/api/v1/customers/${customerId}`, {
    method: 'DELETE',
    headers: {
      'Authorization': `Bearer ${FLOTAC_API_KEY}`
    }
  });

  const result = await response.json();
  console.log('Deleted:', result.data.message);
}

Pagination

All list endpoints support pagination:

async function fetchAllCustomers() {
  let allCustomers = [];
  let page = 1;
  let hasMore = true;

  while (hasMore) {
    const response = await fetch(
      `${BASE_URL}/api/v1/customers?page=${page}&page_size=100`,
      {
        headers: { 'Authorization': `Bearer ${FLOTAC_API_KEY}` }
      }
    );

    const result = await response.json();
    allCustomers.push(...result.data);

    hasMore = result.meta.pagination.hasNextPage;
    page++;
  }

  console.log(`Fetched ${allCustomers.length} total customers`);
  return allCustomers;
}

Error Handling

Always check the success field and handle errors:

async function safeApiCall(url, options) {
  try {
    const response = await fetch(url, options);
    const result = await response.json();

    if (!result.success) {
      console.error('API Error:', result.error);

      switch (result.error.code) {
        case 'VALIDATION_ERROR':
          console.error('Validation failed:', result.error.details);
          break;
        case 'RESOURCE_NOT_FOUND':
          console.error('Resource not found');
          break;
        case 'CONFLICT':
          console.error('Duplicate or conflict:', result.error.message);
          break;
        default:
          console.error('Unknown error:', result.error);
      }

      return null;
    }

    return result.data;
  } catch (error) {
    console.error('Network error:', error);
    return null;
  }
}

Rate Limiting

The API limits requests to 100 per minute per company. Handle rate limits gracefully:

async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || 60;
      console.log(`Rate limited. Waiting ${retryAfter}s...`);
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

Next Steps