Build on LiftUp. Any stack, any framework.
A clean REST API for lead capture and headless blog content, plus HMAC-signed webhooks for everything that happens in your workspace. Authenticate with a per-product key, respect the rate limits, and ship.
/api/v1/leadsPOST /api/v1/leads
Authorization: Bearer {PRODUCT_API_KEY}
Content-Type: application/json
{
"name": "Jane Smith",
"email": "[email protected]",
"company": "Acme Corp",
"message": "I'd like to discuss a project.",
"lead_source": "organic",
"source_page": "/services/",
"custom_fields": {
"budget_range": "$25K-$50K"
}
}2
API versions (v1 + v2)
3
Webhook events
30/min
Lead intake rate limit
SHA-256
HMAC-signed payloads
Wire LiftUp into anything you ship.
A small, predictable surface area — REST in, webhooks out — so any framework can integrate in an afternoon.
Lead ingestion
POST leads from any site or backend with a product key.
Career applications
Multipart endpoint with resume upload (PDF/DOC).
Headless blog
Serve published posts to any frontend, no auth needed.
A/B headlines
The v2 blog API returns the winning title variant.
Webhooks
Subscribe to lead and publish events, HMAC-signed.
Custom fields
Send per-product intake fields, validated on ingest.
Per-product keys
Rotatable Bearer keys, scoped to one product.
Built-in protection
reCAPTCHA, honeypot, dedupe, and rate limits on intake.
On-publish revalidate
Trigger Next.js cache busts when posts go live.
Endpoints, at a glance.
Authenticate lead endpoints with a per-product Bearer key. The blog API needs no key for published content.
Lead intake
Bearer {PRODUCT_API_KEY}Create a lead from any source. Returns a computed score and an SLA deadline based on your scoring rules.
/api/v1/leadsPOST /api/v1/leads
Authorization: Bearer {PRODUCT_API_KEY}
Content-Type: application/json
{
"name": "Jane Smith",
"email": "[email protected]",
"company": "Acme Corp",
"phone": "+1 555 0100",
"message": "I'd like to discuss a project.",
"lead_source": "organic",
"source_page": "/services/web-development/",
"custom_fields": {
"budget_range": "$25K-$50K",
"project_timeline": "Q3 2026"
}
}Response201 Created
{
"id": 1234,
"score": 78,
"sla_deadline": "2026-06-13T14:00:00Z"
}Rate limits: 30/min · 200/hour · 1,000/day
Career application
Bearer {PRODUCT_API_KEY}Submit a job application with a resume attachment as multipart form data.
/api/v1/leads/careerPOST /api/v1/leads/career
Authorization: Bearer {PRODUCT_API_KEY}
Content-Type: multipart/form-data
name, email, phone, message (required)
resume (PDF/DOC, max 5MB, required)
lead_source, source_page (optional)Resume: PDF or DOC, up to 5 MB
Blog content
No auth for published postsFetch published posts for a product to render headlessly on any frontend.
/api/v1/blogGET /api/v1/blog?product={product_slug}&limit=50
GET /api/v1/blog/{slug}?product={product_slug}Response200 OK
{
"title": "How we cut SaaS spend 40%",
"slug": "cut-saas-spend",
"excerpt": "...",
"content": "...",
"featured_image": "https://.../cover.jpg",
"categories": ["growth"],
"tags": ["saas", "ops"],
"published_at": "2026-06-10T09:00:00Z"
}Rate limit: 60/min
A/B headline (v2)
No auth for published postsSame shape as v1, but returns the winning headline variant based on live experiment data.
/api/v2/blog/{slug}GET /api/v2/blog/{slug}?product={product_slug}Response200 OK
{
"slug": "cut-saas-spend",
"title": "The $250/mo problem", // winning variant
"experiment": { "variant": "B", "ctr": 0.048 }
}Serves the best-performing title automatically
Events, pushed to your stack.
Subscribe in Settings → Integrations → Webhooks. Every payload is HMAC-signed, retried, and logged.
Events
lead.createdFired on new lead intakelead.status_changedFired on pipeline status updatepost.publishedFired when a blog post goes live
Delivery & reliability
- SigningHMAC SHA-256 per request
- Retries3× — 30s / 2min / 10min backoff
- Auto-disableAfter 10 consecutive failures
- Delivery logLast 100 per endpoint
Payload
POST to your endpoint{
"event": "lead.created",
"timestamp": "2026-06-13T08:00:00Z",
"data": { ...lead object... }
}Verify the signature
// Verify the signature header
// X-Console-Signature: sha256=...
const expected = hash_hmac('sha256', payload, secret)
// constant-time compare against the headerKeep your own forms. Connect them to the lead API.
LiftUp doesn’t take over your frontend. Keep your existing forms and post submissions to the lead API from your server or an edge function, using the product key kept safely server-side — never exposed in the browser.
- POST from your server or edge function — keys stay server-side
- One rotatable API key per product
- Send custom fields validated on ingest
- reCAPTCHA, honeypot, dedupe, and rate limits applied automatically
app/api/contact/route.ts// Next.js route handler — key stays on the server
export async function POST(req: Request) {
const form = await req.json()
const res = await fetch('https://app.liftup.sh/api/v1/leads', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIFTUP_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(form),
})
return Response.json(await res.json(), { status: res.status })
}Lead endpoints use a per-product API key as a Bearer token (Authorization: Bearer {key}). Keys are rotatable and scoped to a single product, so one site’s key never touches another’s data. The blog API needs no key for published posts.
Lead intake is 30 requests/minute, 200/hour, and 1,000/day per key. The blog API is 60 requests/minute. Exceeding a limit returns HTTP 429 — back off and retry.
Each delivery includes an X-Console-Signature: sha256=… header. Compute hash_hmac('sha256', rawBody, yourSecret) and compare it to the header with a constant-time check. Reject anything that doesn’t match.
Webhooks retry three times with 30-second, 2-minute, and 10-minute backoff. After 10 consecutive failures the endpoint auto-disables, and the last 100 deliveries are kept in the delivery log for replay and debugging.
No. Keep your product key on the server and post to the lead API from your backend or an edge function. Your existing forms stay on your frontend — the key never ships to the browser.
Yes. v1 covers lead intake, career applications, and blog reads; v2 adds A/B headline experiments to the blog API. Versions are pinned in the path so existing integrations keep working.
Ship your first integration today.
Start a 14-day Growth trial, generate a product API key, and post your first lead in minutes — no credit card required.
No credit card · 14-day Growth trial · Cancel anytime