Developers

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.

REST v1 + v2HMAC-signed webhooksPer-product API keys
POST/api/v1/leads
POST /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

What you can build

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.

API reference

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.

POST/api/v1/leads
POST /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"
  }
}
Response
201 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.

POST/api/v1/leads/career
POST /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 posts

Fetch published posts for a product to render headlessly on any frontend.

GET/api/v1/blog
GET /api/v1/blog?product={product_slug}&limit=50
GET /api/v1/blog/{slug}?product={product_slug}
Response
200 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 posts

Same shape as v1, but returns the winning headline variant based on live experiment data.

GET/api/v2/blog/{slug}
GET /api/v2/blog/{slug}?product={product_slug}
Response
200 OK

{
  "slug": "cut-saas-spend",
  "title": "The $250/mo problem",   // winning variant
  "experiment": { "variant": "B", "ctr": 0.048 }
}

Serves the best-performing title automatically

Webhooks

Events, pushed to your stack.

Subscribe in Settings → Integrations → Webhooks. Every payload is HMAC-signed, retried, and logged.

Events

  • lead.createdFired on new lead intake
  • lead.status_changedFired on pipeline status update
  • post.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 header
Forms, your way

Keep 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
POSTapp/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 })
}
FAQ

Developer questions, answered.

Can’t find what you need? Contact us — we reply fast.

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