Create Lead
/api/v1/public/leads/Used to submit a new lead (a potential order).
Auth: Provider API Key (Bearer). See Authentication.
:::tip Simplified: state & city are auto-detected from ZIP
You no longer need to look up numeric state IDs. The backend now automatically
detects state and city from the ZIP codes you provide. Just send origin_zip
(and optionally destination_zip) — the origin_state / destination_state
fields are deprecated and ignored. See Data Models.
:::
:::info Idempotency
external_id must be unique per provider — this prevents duplicate leads
(it is the idempotency key).
:::
Body fields
| Field | Type | Required | Description |
|---|---|---|---|
external_id | String | Required | Unique ID on the provider side (must not repeat) |
first_name | String | Required | Customer's first name |
last_name | String | Required | Customer's last name |
email | String (email) | Required | Customer's email |
phone_number | String | Required | Primary phone number |
origin_zip | String | Required | Pickup ZIP — valid US ZIP. State & city are auto-detected from this. |
estimated_ship_date | Date YYYY-MM-DD | Required | Estimated ship date |
overseas_type | String (enum) | Required | DOMESTIC or FOREIGN. Selects which ship_via set applies — see below. |
ship_via | String (enum) | Required | Shipping method. Allowed values depend on overseas_type — see below. |
vehicles | Array<Vehicle> | Required | At least 1 vehicle (see below) |
destination_zip | String | Optional | Recommended. Delivery ZIP — valid US ZIP. State & city are auto-detected from this. |
origin_city | String | Optional | Pickup city — auto-filled from origin_zip if omitted |
destination_city | String | Optional | Delivery city — auto-filled from destination_zip if omitted |
company_name | String | Optional | Company name |
note_from_shipper | String | Optional | Note from the customer |
origin_state | Integer (ID) | Deprecated | Omit. Ignored if sent — auto-detected from origin_zip. |
destination_state | Integer (ID) | Deprecated | Omit. Ignored if sent — auto-detected from destination_zip. |
overseas_type & ship_via
ship_via accepts a different set of values depending on overseas_type. All
values are exact, case-sensitive strings — send them exactly as shown (note the
underscore in DRIVE_AWAY and ROLLON_ROLLOFF).
overseas_type: "DOMESTIC" — domestic (ground) shipping:
ship_via | Meaning |
|---|---|
OPEN | Open carrier (standard) |
ENCLOSED | Enclosed carrier |
DRIVE_AWAY | Driven to destination (drive-away) |
overseas_type: "FOREIGN" — overseas leg (container / vessel shipping):
ship_via | Meaning |
|---|---|
CONTAINER_20FT | 20 ft container |
CONTAINER_40FT | 40 ft container |
SHARED | Shared container |
ROLLON_ROLLOFF | Roll-on / roll-off (RoRo) vessel |
:::warning Match ship_via to overseas_type
Send a ship_via value from the set that matches your overseas_type. For example,
DRIVE_AWAY is only valid when overseas_type is DOMESTIC; CONTAINER_40FT only
when FOREIGN. See the full reference in Data Models.
:::
Vehicle object
vehicles is an array of at least one vehicle. Each element:
| Field | Type | Required | Description |
|---|---|---|---|
year | Integer | Required | Model year |
make | String | Required | Make (Toyota, Tesla…) |
model | String | Required | Model (Camry, Model S…) |
type | String (enum) | Required | Vehicle type enum |
tariff | Integer | Required | Shipping price |
deposit | Integer | Required | Down payment |
vehicle_run | Boolean | Optional | Whether the vehicle is operational / can be driven |
Request sample
With ZIP-based auto-detection, a minimal valid request only needs ZIPs — no state IDs, no cities:
{
"external_id": "lead_998123A",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "+1234567890",
"origin_zip": "90210",
"destination_zip": "10001",
"estimated_ship_date": "2026-06-15",
"overseas_type": "DOMESTIC",
"ship_via": "OPEN",
"company_name": "Doe Logistics",
"note_from_shipper": "Call before pickup",
"vehicles": [
{
"year": 2023,
"make": "Tesla",
"model": "Model S",
"type": "CAR",
"tariff": 1200,
"deposit": 200,
"vehicle_run": true
}
]
}
Response — 201 Created
Expected response shape (matches the get-lead response):
{
"id": 1042,
"order_number": "00001042-XT",
"state": "LEAD",
"lead_status": "LEAD",
"external_id": "lead_998123A"
}
:::note TODO: verify — create response body The exact create-response body depends on the backend serializer. If it differs, confirm with the backend team and update this section. :::
Code samples
- curl
- JavaScript
- Python
curl -X POST https://api.navigocrm.com/api/v1/public/leads/ \
-H "Authorization: Bearer $NAVIGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "lead_998123A",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "+1234567890",
"origin_zip": "90210",
"destination_zip": "10001",
"estimated_ship_date": "2026-06-15",
"overseas_type": "DOMESTIC",
"ship_via": "OPEN",
"vehicles": [{"year":2023,"make":"Tesla","model":"Model S","type":"CAR","tariff":1200,"deposit":200,"vehicle_run":true}]
}'
const res = await fetch("https://api.navigocrm.com/api/v1/public/leads/", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.NAVIGO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
external_id: "lead_998123A",
first_name: "John",
last_name: "Doe",
email: "john.doe@example.com",
phone_number: "+1234567890",
origin_zip: "90210",
destination_zip: "10001",
estimated_ship_date: "2026-06-15",
overseas_type: "DOMESTIC",
ship_via: "OPEN",
vehicles: [{ year: 2023, make: "Tesla", model: "Model S", type: "CAR", tariff: 1200, deposit: 200, vehicle_run: true }],
}),
});
if (!res.ok) throw new Error(`Lead failed: ${res.status}`);
const data = await res.json();
import os, requests
resp = requests.post(
"https://api.navigocrm.com/api/v1/public/leads/",
headers={"Authorization": f"Bearer {os.environ['NAVIGO_API_KEY']}"},
json={
"external_id": "lead_998123A",
"first_name": "John", "last_name": "Doe",
"email": "john.doe@example.com", "phone_number": "+1234567890",
"origin_zip": "90210", "destination_zip": "10001",
"estimated_ship_date": "2026-06-15",
"overseas_type": "DOMESTIC", "ship_via": "OPEN",
"vehicles": [{"year": 2023, "make": "Tesla", "model": "Model S",
"type": "CAR", "tariff": 1200, "deposit": 200, "vehicle_run": True}],
},
timeout=15,
)
resp.raise_for_status()
lead = resp.json()
Possible errors
| Status | Reason |
|---|---|
400 | Validation error, invalid ZIP, or duplicate external_id |
401 | API key is invalid or expired |
429 | Rate limit exceeded (60/min, 2000/day) |
Full format: Errors.