How Lantern writes AI attribution data back to HubSpot via the Contacts and Deals APIs — batch patterns, rate-limit handling, and idempotency for re-runs.
Lantern's core job is writing AI attribution data onto HubSpot records. This happens continuously (real-time on new sessions) and in batches (nightly reconciliation, historical backfill). Done naively, this hits HubSpot's rate limits and pollutes audit trails. Lantern uses HubSpot's Batch API endpoints (up to 100 records per call), exponential backoff, and idempotency keys so the same session never writes twice.
You don't interact with the API directly — Lantern handles it. But RevOps teams often want to see the API patterns to validate before install (rightfully so: bad HubSpot API usage has torched more than one CRM). Lantern uses the documented v3 CRM APIs with Batch endpoints, respects the 150/10s rate limit, and includes a hubspotobjectid-keyed idempotency layer so re-runs don't duplicate.
Install-time: Lantern registers as a Private App with the listed OAuth scopes, gets a token, and uses it against api.hubapi.com/crm/v3/*. Ongoing: Lantern batches contact updates every 60 seconds (up to 100 per batch), with 250ms spacing between batches to stay under 150/10s. Deal updates are lower-volume (triggered only on stage change), typically 5-20 per minute. All writes include a lantern_request_id custom property for dedup.
# Lantern's HubSpot Batch Update pattern
import requests
import time
from typing import List, Dict
HUBSPOT_BATCH_UPDATE = "https://api.hubapi.com/crm/v3/objects/contacts/batch/update"
def batch_update_contacts(
token: str,
updates: List[Dict], # [{"id": "123", "properties": {...}}]
max_retries: int = 3
) -> Dict:
"""
Batch update up to 100 contacts per call.
Respects 150 req / 10s rate limit with exponential backoff.
Idempotent via lantern_request_id property.
"""
headers = {"Authorization": f"Bearer {token}",
"Content-Type": "application/json"}
# Chunk into 100-record batches
for i in range(0, len(updates), 100):
batch = updates[i:i+100]
payload = {"inputs": batch}
for attempt in range(max_retries):
resp = requests.post(HUBSPOT_BATCH_UPDATE,
json=payload, headers=headers)
if resp.status_code == 200:
break
elif resp.status_code == 429: # Rate limited
backoff = (2 ** attempt) * 0.5
time.sleep(backoff)
else:
resp.raise_for_status()
# Throttle: max 150 req / 10s
time.sleep(0.25)
return {"batches_written": (len(updates) + 99) // 100}This page describes one specific surface inside HubSpot where Lantern's AEO pipeline attribution plugs in. The full integration stitches together across HubSpot Contacts, Deals, Workflows, Lists, Reports, Forms, CMS, and the Marketing/Sales/Service Hub stack. If you're evaluating where to start, the comparison hub has side-by-side comparisons of Lantern against Profound, Scrunch, Peec AI, AthenaHQ, and HubSpot's own AEO product — scored on the dimensions that matter for a CMO buyer (CRM integration depth, reporting quality, prompt-scaling economics).
If you're about to walk this work into a renewal review or budget conversation, the CFO's Guide to AEO Budget Defense has the memo template, the five-slide deck structure, the attribution-math cheat sheet, and the three most-common CFO objections with counter-arguments. It's the long-form companion that translates the technical HubSpot setup on this page into a defensible dollar number for finance.
Instead of hand-wiring properties, workflows, and tracking snippets, Lantern installs the full HubSpot integration in under 30 minutes — then ships the monthly AEO pipeline ROI report your CFO signs off on. $99/mo Starter or Enterprise. 14-day free trial.
Start free trial