Skip to main content
Lot Ups
|API Documentation
Sign In

Lot Ups API

Integrate up capture with any website or application. Send form submissions directly to your Lot Ups ups board with a single API call.

Base URL: https://your-domain.com/api/leads/ingest

Authentication

Every request requires your API key. You can find your API key in the Settings page of your dashboard.

Pass the API key using either method:

  • 1.Header (recommended): Set the x-api-key request header.
  • 2.Body field: Include api_key in the request body. Useful for HTML form submissions.
Example: Header authentication
curl -X POST https://your-domain.com/api/leads/ingest \
  -H "Content-Type: application/json" \
  -H "x-api-key: lu_your_api_key_here" \
  -d '{"name": "John Doe", "phone": "555-0100"}'

Create an Up

POST/api/leads/ingest

Submit a new up to your ups board. Supports JSON, URL-encoded form data, and multipart form data.

Request Headers

HeaderValue
Content-Typeapplication/json or application/x-www-form-urlencoded
x-api-keyYour API key

Request Body

FieldTypeStatusDescription
namestringRequiredFull name of the up
phonestringOptionalPhone number
emailstringOptionalEmail address
service_typestringOptionalVehicle of interest or inquiry type
messagestringOptionalMessage or notes from the up
source_pagestringOptionalURL of the page where the form was submitted
api_keystringOptionalAPI key (alternative to header)
custom_fieldsobjectOptionalAny additional key-value pairs

Example Request

curl
curl -X POST https://your-domain.com/api/leads/ingest \
  -H "Content-Type: application/json" \
  -H "x-api-key: lu_abc123def456..." \
  -d '{
    "name": "Jane Smith",
    "phone": "555-0199",
    "email": "jane@example.com",
    "service_type": "Window Tinting",
    "message": "Interested in a quote for my 2024 F-150.",
    "source_page": "https://example.com/contact"
  }'

Success Response

200 OK
{
  "success": true,
  "lead_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

If a duplicate up is detected (same phone or email within 30 days), the response will include:

200 OK (duplicate detected)
{
  "success": true,
  "lead_id": "new-lead-id-here",
  "duplicate": true,
  "duplicate_of": "original-lead-id-here"
}

Error Response

401 Unauthorized
{
  "success": false,
  "error": "Missing API key. Provide x-api-key header or api_key field."
}

Integration Examples

HTML Form (Direct POST)

The simplest integration. Your form POSTs directly to the API. Include your API key as a hidden field.

HTML
<form action="https://your-domain.com/api/leads/ingest" method="POST">
  <input type="hidden" name="api_key" value="lu_your_api_key_here" />
  <input type="hidden" name="source_page" value="https://example.com/contact" />

  <label>Name *</label>
  <input type="text" name="name" required />

  <label>Phone</label>
  <input type="tel" name="phone" />

  <label>Email</label>
  <input type="email" name="email" />

  <label>Service Type</label>
  <select name="service_type">
    <option value="General Inquiry">General Inquiry</option>
    <option value="Quote Request">Quote Request</option>
  </select>

  <label>Message</label>
  <textarea name="message"></textarea>

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

JavaScript (Fetch API)

For custom form handling with a better user experience (no page redirect).

JavaScript
async function submitLead(formData) {
  const response = await fetch('https://your-domain.com/api/leads/ingest', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'lu_your_api_key_here',
    },
    body: JSON.stringify({
      name: formData.name,
      phone: formData.phone,
      email: formData.email,
      service_type: formData.serviceType,
      message: formData.message,
      source_page: window.location.href,
    }),
  });

  const data = await response.json();

  if (data.success) {
    // Show success message
    alert('Thank you! We will be in touch shortly.');
  } else {
    // Handle error
    alert('Something went wrong. Please try again.');
  }
}

Embeddable Widget

Drop this script tag into any page to add a simple contact form. Customize the fields as needed.

HTML (Script Tag)
<!-- Lot Ups Contact Form -->
<div id="lu-contact-form"></div>
<script>
(function() {
  var API_KEY = 'lu_your_api_key_here';
  var ENDPOINT = 'https://your-domain.com/api/leads/ingest';

  var container = document.getElementById('lu-contact-form');
  container.innerHTML = '<form id="lu-form">' +
    '<input name="name" placeholder="Your Name" required style="display:block;width:100%;margin:8px 0;padding:10px;border:1px solid #ddd;border-radius:6px;" />' +
    '<input name="phone" placeholder="Phone" style="display:block;width:100%;margin:8px 0;padding:10px;border:1px solid #ddd;border-radius:6px;" />' +
    '<input name="email" type="email" placeholder="Email" style="display:block;width:100%;margin:8px 0;padding:10px;border:1px solid #ddd;border-radius:6px;" />' +
    '<textarea name="message" placeholder="Message" style="display:block;width:100%;margin:8px 0;padding:10px;border:1px solid #ddd;border-radius:6px;"></textarea>' +
    '<button type="submit" style="background:#2563eb;color:#fff;padding:10px 24px;border:none;border-radius:6px;cursor:pointer;">Send</button>' +
    '</form>';

  document.getElementById('lu-form').addEventListener('submit', function(e) {
    e.preventDefault();
    var form = e.target;
    fetch(ENDPOINT, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'x-api-key': API_KEY },
      body: JSON.stringify({
        name: form.name.value,
        phone: form.phone.value,
        email: form.email.value,
        message: form.message.value,
        source_page: window.location.href
      })
    }).then(function() {
      container.innerHTML = '<p style="padding:20px;text-align:center;color:#16a34a;">Thank you! We\'ll be in touch.</p>';
    });
  });
})();
</script>

WordPress

If you use a contact form plugin (Contact Form 7, WPForms, Gravity Forms), configure its webhook/notification to POST to the API endpoint. Most plugins have a webhook add-on.

Webhook URL
POST https://your-domain.com/api/leads/ingest

Headers:
  x-api-key: lu_your_api_key_here
  Content-Type: application/json

Map your form fields to:
  name, phone, email, service_type, message

Squarespace

Add a Code Block to your Squarespace page (or use Code Injection in page settings) with the JavaScript fetch example above, or use the embeddable widget script tag.

Webhooks

Webhooks let you receive real-time notifications when events happen in your account. Configure webhook URLs in your dashboard Settings page.

Event Types

EventDescription
lead.createdA new lead has been submitted
lead.updatedA lead's details or stage changed
lead.wonA lead was moved to a "won" stage
lead.lostA lead was moved to a "lost" stage

Payload Format

POST to your webhook URL
{
  "event": "lead.created",
  "timestamp": "2026-03-19T14:30:00.000Z",
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Jane Smith",
    "phone": "555-0199",
    "email": "jane@example.com",
    "service_type": "Window Tinting",
    "message": "Interested in a quote.",
    "source_page": "https://example.com/contact",
    "source": "website",
    "status": "new",
    "created_at": "2026-03-19T14:30:00.000Z"
  }
}

Signature Verification

Each webhook request includes an x-lotups-signature header containing an HMAC-SHA256 hash of the request body, signed with your API key. Verify this to ensure the request came from Lot Ups.

Node.js Verification
const crypto = require('crypto');

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

// In your webhook handler:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-lotups-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    'lu_your_api_key_here'
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process the webhook
  const { event, data } = req.body;
  console.log('Received event:', event, data);

  res.status(200).send('OK');
});

Error Codes

StatusMeaningExample
400Bad RequestMissing required fields (name is required)
401UnauthorizedMissing or invalid API key
403ForbiddenClient account is inactive
429Too Many RequestsRate limit exceeded (100 leads/hour)
500Server ErrorInternal server error (retry later)

All error responses follow the same format:

{
  "success": false,
  "error": "Human-readable error message."
}

Rate Limiting

The API enforces a rate limit of 100 leads per hour per API key. This resets on a rolling window. If you exceed the limit, you will receive a429response.

For most businesses this is more than enough. If you need a higher limit, contact us to discuss your use case.

Lot Ups

A VirtualGSM product.