LeadMove Docs
Sending leads in

Webhook API reference

Post leads into a pipeline in real time — endpoint, authentication, accepted payloads, response codes and code samples.

Every source in your pipeline has its own posting URL. Your supplier POSTs a lead to that URL and LeadMove validates, dedupes, scores and routes it immediately.

POST https://app.leadmove.io/api/i/{source_key}

The token in the URL is the authentication — no header, no API key to manage. Give one URL per supplier so you can see where every lead came from. Get yours in the pipeline canvas: click Intake, then click a source to copy its posting URL.

Request

MethodPOST only
Content-Typeapplication/json or application/x-www-form-urlencoded
BodyA flat object of field names and values
Rate limit60 requests per minute, per sending IP and per posting URL

Field names should match your pipeline's canonical fields. If a supplier uses different names (email_address, Phone1…), don't ask them to change: map their names to yours in the source's field mapping. Unmapped fields still arrive — they're stored on the lead and flagged in the Intake panel so you can decide what to do with them.

Responses

CodeMeaningBody
200Accepted{ "success": true, "leadId": "...", "displayId": "LD-XXXXXX", "duplicate": false }
401Invalid or inactive source key — usually a wrong or revoked URL{ "error": "..." }
403The pipeline isn't active. Paused and archived pipelines refuse leads{ "error": "..." }
422Unreadable body, or the lead failed validation{ "error": "...", "leadId": "...", "missingFields": [...], "field": "..." }
429Rate limit exceeded{ "error": "Too many requests", "retryAfter": 30 }

A duplicate still returns 200, with "duplicate": true. Under the default deduplication setting the lead is recorded but never sent to a buyer and never billed — see lead statuses.

A 422 returns the leadId of the lead LeadMove stored anyway. Nothing is lost: fix the data at the source and re-send, or correct the stored lead by hand.

429 responses carry Retry-After (seconds), X-RateLimit-Limit and X-RateLimit-Remaining. Back off and retry — a well-behaved sender never loses a lead to a rate limit.

Code samples

curl -X POST "https://app.leadmove.io/api/i/{source_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "sample.lead@example.com",
    "phone": "+15555550123",
    "firstName": "Sample",
    "lastName": "Lead",
    "zip": "00000"
  }'
const response = await fetch("https://app.leadmove.io/api/i/{source_key}", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "sample.lead@example.com",
    phone: "+15555550123",
    firstName: "Sample",
    lastName: "Lead",
    zip: "00000",
  }),
});
 
const data = await response.json();
console.log(data);
// { success: true, leadId: "...", displayId: "LD-XXXXXX", duplicate: false }
import requests
 
response = requests.post(
    "https://app.leadmove.io/api/i/{source_key}",
    json={
        "email": "sample.lead@example.com",
        "phone": "+15555550123",
        "firstName": "Sample",
        "lastName": "Lead",
        "zip": "00000",
    },
)
 
print(response.json())
# {"success": True, "leadId": "...", "displayId": "LD-XXXXXX", "duplicate": False}

Legacy pipeline endpoint

Integrations built before per-source URLs existed keep working:

POST https://app.leadmove.io/api/campaigns/{pipeline_id}/ingest

Authenticate with an X-API-Key header or an ?api_key= query parameter. Same content types, same rate limit (counted per IP and per pipeline), same response codes, plus 401 when the key is missing. Origin can be tagged with an X-Source header or a source field in the body.

Prefer the per-source URL for anything new: one URL per supplier, no header to configure, and per-supplier attribution and field mapping you don't get here.

Common questions

Do I need a different URL for each supplier? You don't have to, but you should. Sources are how LeadMove attributes leads, and each source carries its own field mapping — so one supplier's odd field names never affect another's.

A supplier posts form-encoded data. Do I need to change anything? No. Send Content-Type: application/x-www-form-urlencoded and post the fields as form data; everything downstream is identical.

What happens to a lead that returns 422? It's stored, marked invalid, and never distributed. The response includes its leadId so you can fix and re-send the same lead rather than losing it.

Can I rotate a posting URL if a supplier leaks it? Yes. Open the source in the Intake panel and regenerate its key. The old URL stops working immediately and starts returning 401, so give the new one to your supplier first.

How fast is a lead delivered after I post it? The response comes back as soon as the lead is accepted; routing and delivery run right behind it, typically within seconds. Leads can still wait on purpose — for your manual review, or for a buyer's operating hours. See how distribution works.

On this page