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-keyrequest header. - 2.Body field: Include
api_keyin the request body. Useful for HTML form submissions.
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
/api/leads/ingestSubmit a new up to your ups board. Supports JSON, URL-encoded form data, and multipart form data.
Request Headers
| Header | Value |
|---|---|
Content-Type | application/json or application/x-www-form-urlencoded |
x-api-key | Your API key |
Request Body
| Field | Type | Status | Description |
|---|---|---|---|
name | string | Required | Full name of the up |
phone | string | Optional | Phone number |
email | string | Optional | Email address |
service_type | string | Optional | Vehicle of interest or inquiry type |
message | string | Optional | Message or notes from the up |
source_page | string | Optional | URL of the page where the form was submitted |
api_key | string | Optional | API key (alternative to header) |
custom_fields | object | Optional | Any additional key-value pairs |
Example Request
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
{
"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:
{
"success": true,
"lead_id": "new-lead-id-here",
"duplicate": true,
"duplicate_of": "original-lead-id-here"
}Error Response
{
"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.
<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).
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.
<!-- 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.
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, messageSquarespace
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
| Event | Description |
|---|---|
lead.created | A new lead has been submitted |
lead.updated | A lead's details or stage changed |
lead.won | A lead was moved to a "won" stage |
lead.lost | A lead was moved to a "lost" stage |
Payload Format
{
"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.
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
| Status | Meaning | Example |
|---|---|---|
| 400 | Bad Request | Missing required fields (name is required) |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Client account is inactive |
| 429 | Too Many Requests | Rate limit exceeded (100 leads/hour) |
| 500 | Server Error | Internal 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.
A VirtualGSM product.