Smart Intake

Custom HTML Sites

Capture forms from any website with zero code.

For static HTML sites, custom web applications, or any platform not covered by our specific guides, this documentation shows you how to integrate the Kantos Universal Script with complete control over your implementation.

What You'll Need

  • Access to edit your website's HTML
  • Your Kantos API key from Settings → API Keys
  • An Object Definition ID for lead storage

Basic Installation

Add the Universal Script to any HTML page by including it before the closing </body> tag:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Contact Us</title>
</head>
<body>
  <!-- Your page content -->

  <form id="contact-form">
    <label for="name">Name</label>
    <input type="text" id="name" name="name" required />

    <label for="email">Email</label>
    <input type="email" id="email" name="email" required />

    <label for="message">Message</label>
    <textarea id="message" name="message" rows="4"></textarea>

    <button type="submit">Send Message</button>
  </form>

  <!-- Kantos Universal Script -->
  <script
    src="https://cdn.kantos.ai/intake.js"
    data-api-key="YOUR_API_KEY"
    data-object-definition-id="YOUR_OBJECT_DEFINITION_ID"
    data-success-redirect="/thank-you.html"
    defer
  ></script>
</body>
</html>

Complete Configuration Options

The Universal Script supports several configuration options via data attributes:

<script
  src="https://cdn.kantos.ai/intake.js"
  data-api-key="YOUR_API_KEY"
  data-object-definition-id="YOUR_OBJECT_DEFINITION_ID"
  data-success-redirect="/thank-you.html"
  data-error-redirect="/error.html"
  data-honeypot="true"
  data-form-selector="form.kantos-form"
  defer
></script>

Configuration Reference

AttributeRequiredDescription
data-api-keyYesYour Kantos Intake API key
data-object-definition-idYesTarget object for storing form data
data-success-redirectNoURL to redirect after successful submission
data-error-redirectNoURL to redirect on submission error
data-honeypotNoEnable honeypot spam protection ("true")
data-form-selectorNoCSS selector to target specific forms

Form Structure Best Practices

The Universal Script works with any standard HTML form, but following these guidelines ensures the best results:

Use Semantic Field Names

<!-- Good: Descriptive, lowercase names -->
<input type="text" name="first_name" />
<input type="text" name="last_name" />
<input type="email" name="email" />
<input type="tel" name="phone" />
<input type="text" name="company" />

<!-- Avoid: Generic or unclear names -->
<input type="text" name="field1" />
<input type="text" name="q2" />

Include Form ID

<!-- Form ID helps identify the source -->
<form id="contact-form">...</form>
<form id="newsletter-signup">...</form>
<form id="quote-request">...</form>

Use Appropriate Input Types

<input type="email" name="email" />     <!-- Email validation -->
<input type="tel" name="phone" />        <!-- Phone keyboard on mobile -->
<input type="url" name="website" />      <!-- URL validation -->
<input type="number" name="quantity" />  <!-- Number keyboard -->
<input type="date" name="start_date" />  <!-- Date picker -->

Advanced Form Examples

Multi-Step Form

For multi-step forms, the script captures all visible fields when the form is submitted:

<form id="multi-step-form">
  <!-- Step 1 -->
  <div class="step" data-step="1">
    <input type="text" name="name" required />
    <input type="email" name="email" required />
    <button type="button" onclick="nextStep()">Continue</button>
  </div>

  <!-- Step 2 -->
  <div class="step" data-step="2" style="display: none;">
    <input type="text" name="company" />
    <input type="tel" name="phone" />
    <button type="button" onclick="prevStep()">Back</button>
    <button type="submit">Submit</button>
  </div>
</form>

Dynamic Form with Hidden Context

<form id="inquiry-form">
  <input type="text" name="name" required />
  <input type="email" name="email" required />
  <textarea name="message"></textarea>

  <!-- Hidden fields for context -->
  <input type="hidden" name="page_url" id="page-url" />
  <input type="hidden" name="referrer" id="referrer" />
  <input type="hidden" name="utm_source" id="utm-source" />

  <button type="submit">Send</button>
</form>

<script>
  // Populate hidden fields with context
  document.getElementById('page-url').value = window.location.href;
  document.getElementById('referrer').value = document.referrer;
  document.getElementById('utm-source').value =
    new URLSearchParams(window.location.search).get('utm_source') || '';
</script>

Form with File References

While the Universal Script doesn't upload files directly, you can reference externally hosted files:

<form id="application-form">
  <input type="text" name="name" required />
  <input type="email" name="email" required />

  <!-- Link to externally hosted file -->
  <label>Resume (upload to Dropbox/Google Drive and paste link)</label>
  <input type="url" name="resume_url" placeholder="https://..." />

  <button type="submit">Submit Application</button>
</form>

Targeting Specific Forms

By default, the script captures all forms on the page. Use data-form-selector to target specific forms:

<!-- Only capture forms with the .kantos-capture class -->
<script
  src="https://cdn.kantos.ai/intake.js"
  data-api-key="YOUR_API_KEY"
  data-object-definition-id="YOUR_OBJECT_DEFINITION_ID"
  data-form-selector=".kantos-capture"
  defer
></script>

<!-- This form WILL be captured -->
<form class="kantos-capture" id="contact">...</form>

<!-- This form will NOT be captured -->
<form id="search-form">...</form>

Excluding Forms

Add the data-kantos-ignore attribute to exclude specific forms:

<!-- This form will be ignored -->
<form data-kantos-ignore id="site-search">
  <input type="search" name="q" />
  <button type="submit">Search</button>
</form>

<!-- This form will be captured -->
<form id="contact-form">
  <input type="text" name="name" />
  <input type="email" name="email" />
  <button type="submit">Submit</button>
</form>

Custom Success/Error Handling

For SPAs or when you need custom behavior, you can listen for script events:

<script>
  window.addEventListener('kantos:submit:success', function(event) {
    console.log('Form submitted successfully', event.detail);
    // Custom success handling
    document.getElementById('success-message').style.display = 'block';
    document.getElementById('contact-form').style.display = 'none';
  });

  window.addEventListener('kantos:submit:error', function(event) {
    console.error('Form submission failed', event.detail);
    // Custom error handling
    alert('Sorry, there was an error. Please try again.');
  });
</script>

Event Handling

When using custom event handlers, the default redirect behavior is disabled. You have full control over what happens after submission.

CORS and Security

The Universal Script handles CORS automatically. For additional security:

  • Use HTTPS - Always serve your site over HTTPS
  • Intake API keys only - Use keys scoped for intake, not full admin keys
  • Enable honeypot - Add data-honeypot="true" to filter bots
  • Rate limiting - Built into the Kantos API to prevent abuse

Debugging

Enable verbose logging to troubleshoot issues:

<script>
  // Enable debug mode before loading the script
  window.KANTOS_DEBUG = true;
</script>
<script
  src="https://cdn.kantos.ai/intake.js"
  data-api-key="YOUR_API_KEY"
  data-object-definition-id="YOUR_OBJECT_DEFINITION_ID"
  defer
></script>

With debug mode enabled, open your browser's console to see:

  • Forms detected on the page
  • Field names being captured
  • API request/response details
  • Any errors or warnings

Integration with Frameworks

React / Next.js

// pages/_document.js or app/layout.js
import Script from 'next/script';

export default function Layout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://cdn.kantos.ai/intake.js"
          data-api-key={process.env.NEXT_PUBLIC_KANTOS_API_KEY}
          data-object-definition-id="YOUR_OBJECT_DEFINITION_ID"
          strategy="lazyOnload"
        />
      </body>
    </html>
  );
}

Vue.js

// In your main App.vue or a layout component
export default {
  mounted() {
    const script = document.createElement('script');
    script.src = 'https://cdn.kantos.ai/intake.js';
    script.setAttribute('data-api-key', 'YOUR_API_KEY');
    script.setAttribute('data-object-definition-id', 'YOUR_OBJECT_DEFINITION_ID');
    script.defer = true;
    document.body.appendChild(script);
  }
}

Next Steps

    Custom HTML Sites - Smart Intake | Kantos Docs