Introduction to BSTD API Integration

Welcome to the BSTD API Integration Guide — your resource for seamlessly embedding BSTD's powerful transport and logistics automation features directly into your existing websites and applications. This guide covers how to utilize our APIs for document generation, lead management, shipment tracking, and more.

Important Note for Developers

The BSTD UI Kit and embedded API scripts are designed to be lightweight, static HTML/CSS, and JavaScript components. They are not dependent on any specific CMS or backend language, making them highly flexible. You can integrate them into any static site or embed them into your existing platform (e.g., PHP, Node.js, Django, Ruby on Rails) with ease. Please note that these scripts do not include a CMS or dynamic data fetching by default; they are designed to fetch data from your BSTD account via API keys.

Quick Start: Embedding BSTD Features

This section will help you quickly integrate BSTD features into your web presence. The easiest way to get started is by embedding our pre-built UI components.

1. Embed & Access BSTD UI Components

To instantly load all BSTD UI components, styles, and interactivity, simply add the following script tag to your website's HTML, ideally just before the closing </body> tag:

html
<!-- Include BSTD UI Kit Script -->
<script src="https://api.bstd.digital.thugo.in/assets/js/bstd-ui-kit.min.js" defer></script>

This method requires no build tools or complex setup, allowing you to integrate BSTD features into your site within minutes.

Key API Integrations

To further enhance your website with interactive and dynamic BSTD functionalities, you can integrate the following APIs:

Document API

Use the Document API to securely embed and manage customer-specific documents such as invoices, agreements, contracts, or loading slips directly on your website. This allows your users to view, download, or even e-sign documents without leaving your platform.

javascript
document.addEventListener('DOMContentLoaded', () => {
  const urlParams = new URLSearchParams(window.location.search);
  const token = urlParams.get('key'); // Expects a secure token in the URL
  const apiKey = 'YOUR_BSTD_API_KEY'; // Replace with your actual BSTD API key

  if (!token) {
    document.body.innerHTML = '<h3 style="color: #dc3545; text-align: center; margin-top: 50px;">Error: Missing document access token in URL.</h3>';
  } else if (!apiKey || apiKey === 'YOUR_BSTD_API_KEY') {
    document.body.innerHTML = '<h3 style="color: #dc3545; text-align: center; margin-top: 50px;">Error: Please provide a valid BSTD API key.</h3>';
  } else {
    const script = document.createElement('script');
    script.src = `https://api.bstd.digital.thugo.in/api/embed/customer-docs.js?apikey=${apiKey}&key=${encodeURIComponent(token)}`;
    document.head.appendChild(script);
  }
});

Important Tip: Ensure you pass the secure key (document token) dynamically in the URL (e.g., yourwebsite.com/docs?key=YOUR_DOCUMENT_TOKEN) to identify the customer and securely load their specific documents. Remember to replace 'YOUR_BSTD_API_KEY' with your unique API key obtained from your BSTD dashboard.

Leads API

Automate lead capture on your website using the Leads API. This script will inject a customizable lead generation form or modal that seamlessly submits data directly to your BSTD lead management system.

html
<script src="https://api.bstd.digital.thugo.in/api/embed/delayed-form-modal.js?apikey=YOUR_BSTD_API_KEY" defer></script>

Use Case: This API is ideal for capturing sales inquiries, product interest, support requests, or any user data that you want to funnel directly into your BSTD lead workflow. Remember to replace 'YOUR_BSTD_API_KEY' with your actual API key.

Shipment Tracking API

Empower your customers to track their orders and shipments with ease by embedding our Shipment Tracking API. This integration provides a tracking form that allows customers to enter an LR (Lorry Receipt) number or tracking ID to view live shipment status.

html
<!-- Placeholder where the shipment tracking widget will appear -->
<div id="shipmentTrackingContainer"></div>

<!-- Include the tracking script before the closing </body> tag -->
<script>
document.addEventListener('DOMContentLoaded', () => {
  const apiKey = 'YOUR_BSTD_API_KEY'; // Replace with your actual BSTD API key

  if (!apiKey || apiKey === 'YOUR_BSTD_API_KEY') {
    document.getElementById('shipmentTrackingContainer').innerHTML = '<h3 style="color: #dc3545; text-align: center; margin-top: 50px;">Error: Please provide a valid BSTD API key for shipment tracking.</h3>';
  } else {
    const script = document.createElement('script');
    script.src = `https://bstd.digital.thugo.in/api/embed/delayed-shipment-tracking-modal.js?apikey=${apiKey}`;
    script.defer = true;
    document.head.appendChild(script);
  }
});
</script>

Result: Integrating this API significantly improves customer transparency and can reduce inbound support calls related to shipment status. Ensure you replace 'YOUR_BSTD_API_KEY' with your unique API key for this integration to function correctly and display accurate tracking information.

Custom Leads Form API

For advanced use cases, deploy a standalone, fully-branded lead capture form directly on any page. This method gives you complete control over styling while maintaining the same server-side protections as the modal widget: honeypot bot detection, anti-timing checks, UTM attribution, device fingerprinting, and automatic geo-location.

The form submits to POST /custom-form/:apikey. Copy the HTML below, replace YOUR_BSTD_API_KEY, and paste it into any static page or CMS.

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Get Moving Quote</title>
<style>
  *{box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}
  body{background:#f5f5f5;padding:20px;margin:0}
  .form-container{max-width:480px;margin:0 auto;background:#fff;padding:32px;border-radius:16px;box-shadow:0 1px 3px rgba(0,0,0,0.1)}
  .form-title{font-size:20px;font-weight:700;margin-bottom:4px;color:#111}
  .form-subtitle{font-size:13px;color:#666;margin-bottom:20px}
  .form-group{margin-bottom:16px}
  label{display:block;font-size:12px;font-weight:600;color:#444;margin-bottom:6px;text-transform:uppercase;letter-spacing:0.3px}
  input,select,textarea{width:100%;padding:10px 12px;border:1px solid #ddd;border-radius:8px;font-size:14px;transition:border-color 0.2s;background:#fff;color:#111}
  input:focus,select:focus,textarea:focus{outline:none;border-color:#ED1C24}
  textarea{resize:vertical;min-height:80px}
  button[type="submit"]{width:100%;padding:12px;background:#ED1C24;color:#fff;border:none;border-radius:8px;font-size:15px;font-weight:600;cursor:pointer;transition:opacity 0.2s}
  button[type="submit"]:hover{opacity:0.9}
  .status{margin-top:16px;padding:12px;border-radius:8px;font-size:13px;display:none}
  .status.success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0}
  .status.error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca}
  .required{color:#ED1C24}
</style>
</head>
<body>

<div class="form-container">
  <div class="form-title">Request a Free Quote</div>
  <div class="form-subtitle">Fill in your details and we'll get back to you shortly</div>

  <form id="leadForm" action="#">
    <!-- HONEYPOT: Bot protection. Leave hidden. -->
    <div style="position:absolute;left:-9999px;opacity:0">
      <input type="text" name="website" tabindex="-1" autocomplete="off">
      <input type="text" name="_gotcha" tabindex="-1" autocomplete="off">
    </div>

    <!-- Anti-bot timestamp -->
    <input type="hidden" name="_timestamp" id="ts">

    <!-- UTM & Tracking fields (auto-filled by JS) -->
    <input type="hidden" name="gclid" id="f-gclid">
    <input type="hidden" name="gbraid" id="f-gbraid">
    <input type="hidden" name="wbraid" id="f-wbraid">
    <input type="hidden" name="fbclid" id="f-fbclid">
    <input type="hidden" name="fbp" id="f-fbp">
    <input type="hidden" name="fbc" id="f-fbc">
    <input type="hidden" name="ttclid" id="f-ttclid">
    <input type="hidden" name="ttp" id="f-ttp">
    <input type="hidden" name="utm_source" id="f-utm_source">
    <input type="hidden" name="utm_medium" id="f-utm_medium">
    <input type="hidden" name="utm_campaign" id="f-utm_campaign">
    <input type="hidden" name="utm_term" id="f-utm_term">
    <input type="hidden" name="utm_content" id="f-utm_content">
    <input type="hidden" name="utm_id" id="f-utm_id">
    <input type="hidden" name="landing_page" id="f-landing">
    <input type="hidden" name="referrer" id="f-referrer">
    <input type="hidden" name="source_url" id="f-source">

    <!-- Device & Browser (auto-filled by JS) -->
    <input type="hidden" name="browser" id="f-browser">
    <input type="hidden" name="browser_version" id="f-bver">
    <input type="hidden" name="os" id="f-os">
    <input type="hidden" name="device_type" id="f-dev">
    <input type="hidden" name="language" id="f-lang">
    <input type="hidden" name="screen_resolution" id="f-res">
    <input type="hidden" name="timezone" id="f-tz">
    <input type="hidden" name="connection_type" id="f-conn">

    <!-- REQUIRED FIELDS -->
    <div class="form-group">
      <label>Full Name <span class="required">*</span></label>
      <input type="text" name="name" required placeholder="John Doe">
    </div>

    <div class="form-group">
      <label>Phone <span class="required">*</span></label>
      <input type="tel" name="phone" required pattern="[6-9][0-9]{9}" placeholder="10-digit mobile number">
    </div>

    <div class="form-group">
      <label>Shifting Type <span class="required">*</span></label>
      <select name="shifting_type" required>
        <option value="">Select shifting type</option>
        <option value="Home">Home Shifting</option>
        <option value="Office">Office Shifting</option>
        <option value="Vehicle">Vehicle Transport</option>
        <option value="Storage">Storage & Warehouse</option>
        <option value="International">International Move</option>
      </select>
    </div>

    <div class="form-group">
      <label>Pickup Location <span class="required">*</span></label>
      <input type="text" name="pickup_location" required placeholder="City name or 6-digit pincode">
    </div>

    <div class="form-group">
      <label>Drop Location <span class="required">*</span></label>
      <input type="text" name="drop_location" required placeholder="City name or 6-digit pincode">
    </div>

    <!-- OPTIONAL FIELDS -->
    <div class="form-group">
      <label>Email</label>
      <input type="email" name="email" placeholder="john@example.com">
    </div>

    <div class="form-group">
      <label>Shifting Date</label>
      <input type="date" name="shifting_date">
    </div>

    <div class="form-group">
      <label>Message</label>
      <textarea name="message" placeholder="Any specific requirements..."></textarea>
    </div>

    <button type="submit">Get Free Quote</button>
    <div id="status" class="status"></div>
  </form>
</div>

<script>
(function() {
  // 1. Anti-bot timestamp (must be >3s old on server)
  document.getElementById('ts').value = Date.now();

  // 2. Capture UTM & page data from URL
  var p = new URLSearchParams(window.location.search);
  var map = {
    gclid:'f-gclid', gbraid:'f-gbraid', wbraid:'f-wbraid',
    fbclid:'f-fbclid', fbp:'f-fbp', fbc:'f-fbc',
    ttclid:'f-ttclid', ttp:'f-ttp',
    utm_source:'f-utm_source', utm_medium:'f-utm_medium',
    utm_campaign:'f-utm_campaign', utm_term:'f-utm_term',
    utm_content:'f-utm_content', utm_id:'f-utm_id'
  };
  for(var k in map) {
    var el = document.getElementById(map[k]);
    if(el) el.value = p.get(k) || '';
  }
  document.getElementById('f-landing').value = location.href;
  document.getElementById('f-referrer').value = document.referrer || '';
  document.getElementById('f-source').value = location.href;

  // 3. Capture device / browser info
  document.getElementById('f-browser').value = navigator.userAgent;
  document.getElementById('f-lang').value = navigator.language;
  document.getElementById('f-res').value = screen.width + 'x' + screen.height;
  document.getElementById('f-tz').value = Intl.DateTimeFormat().resolvedOptions().timeZone;
  document.getElementById('f-conn').value = (navigator.connection && navigator.connection.effectiveType) || 'unknown';

  // 4. Form submission handler
  document.getElementById('leadForm').addEventListener('submit', async function(e) {
    e.preventDefault();
    var form = e.target;
    var status = document.getElementById('status');
    var data = {};
    var formData = new FormData(form);
    formData.forEach(function(v, k) { data[k] = v; });

    // Client-side validation (mirrors backend rules)
    var phone = (data.phone || '').replace(/\D/g, '');
    if(!/^[6-9]\d{9}$/.test(phone)) {
      status.className = 'status error'; status.style.display = 'block';
      status.textContent = 'Please enter a valid 10-digit Indian mobile number.';
      return;
    }
    if(data.email && data.email.length > 0) {
      if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
        status.className = 'status error'; status.style.display = 'block';
        status.textContent = 'Please enter a valid email address.';
        return;
      }
    }

    var API_KEY = 'YOUR_BSTD_API_KEY'; // Replace with your actual API key
    var API_BASE = 'https://api.bstd.digital.thugo.in';

    try {
      var res = await fetch(API_BASE + '/custom-form/' + API_KEY, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      });
      var result = await res.json();

      if(res.ok) {
        status.className = 'status success';
        status.style.display = 'block';
        status.textContent = 'Quote requested! Inquiry ID: ' + result.inquiry_id;
        form.reset();
      } else {
        status.className = 'status error';
        status.style.display = 'block';
        status.textContent = result.message || 'Something went wrong. Please try again.';
      }
    } catch(err) {
      status.className = 'status error';
      status.style.display = 'block';
      status.textContent = 'Network error. Please check your connection and try again.';
    }
  });
})();
</script>

</body>
</html>

Key Features: Hidden honeypot fields (website & _gotcha), anti-bot timestamp, automatic UTM capture, device/browser fingerprinting, client-side phone/email validation, and a styled success/error status message.

API Reference & Security

Technical details for the Custom Leads Form endpoint and the security mechanisms protecting your submissions.

Endpoint & Headers

EndpointPOST /custom-form/:apikey
Headers
Content-Type: application/jsonOrigin: <<your-domain>>
Required Fields
namephoneshifting_typepickup_locationdrop_location
Response Codes
201 CreatedLead captured successfully
400 Bad RequestValidation error or spam detected
401 UnauthorizedInvalid API key format or unknown key
403 ForbiddenOrigin not in ALLOWED_ORIGINS
429 Too Many RequestsIP or phone rate limit exceeded

CORS & Bot Protection

  • •Set ALLOWED_ORIGINS env variable with a comma-separated list of domains that may submit the form (e.g. https://your-site.com,https://www.your-site.com).
  • •Honeypot: The form includes two hidden fields (website & _gotcha). If either contains data, the submission is rejected as spam.
  • •Anti-bot timing: The hidden _timestamp field is set on page load. Submissions faster than 3 seconds are rejected.
  • •Rate limits: 5 submissions per IP per hour; 2 submissions per phone number per 10 minutes.
  • •Phone rule: Must be a 10-digit Indian mobile number starting with 6-9. Pincode extraction (6 digits) is automatic from pickup/drop location strings.
  • •Geo lookup: Server-side IP geolocation via ip-api.com enriches every lead with city, region, country, postal code, and lat/lon.