Create Lead
/api/v1/public/leads/Used to submit a new lead (a potential order).
Auth: Provider API Key (Bearer). See Authentication.
:::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_city | String | Required | Pickup city |
origin_state | Integer (ID) | Required | Navigo state ID — state lookup |
origin_zip | String | Required | Pickup ZIP code |
destination_city | String | Required | Delivery city |
destination_zip | String | TODO: verify | Delivery ZIP (present in sample) |
estimated_ship_date | Date YYYY-MM-DD | Required | Estimated ship date |
vehicles | Array<Vehicle> | Required | At least 1 vehicle (see below) |
company_name | String | Optional | Company name |
note_from_shipper | String | Optional | Note from the customer |
:::warning TODO: verify — destination_zip
destination_zip appears in the request sample, but whether it is required must
be confirmed against the backend serializer. Check with the Navigo backend team.
:::
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 | TODO: verify | Whether the vehicle runs (sample has true) |
:::warning TODO: verify — vehicle_run
vehicle_run appears as true in the request sample, but it was not in the HTML
table. Confirm the field name and whether it is required with the backend.
:::
Request sample
{
"external_id": "lead_998123A",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "+1234567890",
"origin_city": "Los Angeles",
"origin_state": 5,
"origin_zip": "90001",
"destination_city": "New York",
"destination_zip": "10001",
"estimated_ship_date": "2026-06-15",
"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.navigo.example/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_city": "Los Angeles",
"origin_state": 5,
"origin_zip": "90001",
"destination_city": "New York",
"destination_zip": "10001",
"estimated_ship_date": "2026-06-15",
"vehicles": [{"year":2023,"make":"Tesla","model":"Model S","type":"CAR","tariff":1200,"deposit":200}]
}'
const res = await fetch("https://api.navigo.example/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_city: "Los Angeles",
origin_state: 5,
origin_zip: "90001",
destination_city: "New York",
destination_zip: "10001",
estimated_ship_date: "2026-06-15",
vehicles: [{ year: 2023, make: "Tesla", model: "Model S", type: "CAR", tariff: 1200, deposit: 200 }],
}),
});
if (!res.ok) throw new Error(`Lead failed: ${res.status}`);
const data = await res.json();
import os, requests
resp = requests.post(
"https://api.navigo.example/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_city": "Los Angeles", "origin_state": 5, "origin_zip": "90001",
"destination_city": "New York", "destination_zip": "10001",
"estimated_ship_date": "2026-06-15",
"vehicles": [{"year": 2023, "make": "Tesla", "model": "Model S",
"type": "CAR", "tariff": 1200, "deposit": 200}],
},
timeout=15,
)
resp.raise_for_status()
lead = resp.json()
Possible errors
| Status | Reason |
|---|---|
400 | Validation error or duplicate external_id |
401 | API key is invalid or expired |
429 | Rate limit exceeded (60/min, 2000/day) |
Full format: Errors.