# Send leads into Measured Bid

Post leads from any website form, CRM or automation to a widget's form leads URL. They land in the same lead list as widget leads, and you can keep their stage in sync.

Source: https://measuredbid.com/docs/lead-intake

## Your form leads URL

- Find it in the widget's settings, under Leads from your other website forms. It looks like `https://measuredbid.com/api/intake/<token>`.
- Keep it private. Anyone with it can add leads. Rotating it stops the old URL right away.
- Demo widgets don't have one.

## The request

- `POST` with JSON, form-encoded or multipart data. JSON can be nested; it's flattened.
- Up to 64 KB and 300 fields.
- Browsers can post to it directly (CORS is open).
- Optional `Idempotency-Key` header, up to 200 characters, so a retry isn't saved twice.

From a browser or Node:

```js
fetch("YOUR_FORM_LEADS_URL", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    external_id: "your-lead-id",
    name: "Jordan Example",
    email: "jordan@example.com"
  })
});
```

From the command line:

```bash
curl -X POST "YOUR_FORM_LEADS_URL" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-123" \
  -d '{"name":"Jordan Example","phone":"(916) 555-0142","address":"412 Sample Ridge Ct, Roseville, CA 95661","service":"gutters","external_id":"crm-123"}'
```

## Fields it understands

Field names are matched loosely, so most form plugins work without renaming anything.

| Meaning | Field names accepted |
| --- | --- |
| Name | `full_name`, `fullname`, `your-name`, `contact_name`, `name` |
| First and last name | `first_name`, `fname`, `firstname`; `last_name`, `lname`, `lastname` |
| Phone | `phone_number`, `your-phone`, `phone`, `tel`, `telephone`, `mobile`, `cell` |
| Email | `email_address`, `your-email`, `email`, `e-mail` |
| Full address | `full_address`, `street_address`, `property_address`, `address` |
| Address parts | `address1`, `address_line_1`, `street`, `city`, `state`, `zip`, `zipcode`, `postal_code` |
| Message | `your-message`, `message`, `comments`, `notes`, `details`, `description` |
| Trade | `service`, `trade`, `project`, `project_type`, `interested_in`. Matched to the widget's trades by keyword. |
| Form name | `form_name`, `form`, `source` |
| Your lead ID | `external_id`, `externalid`, `hub_lead_id`. Needed for stage sync. |
| Spam trap | `website`, `_gotcha`, `hp`. Leave it empty. A filled one gets a normal answer and is not saved. |

Any `utm_*` field is kept. A lead needs a name (or first and last name, or an email) and a way to reach them: a phone number with at least 10 digits or an email.

## Responses

| Status | Means |
| --- | --- |
| 200 | Saved: `{ "ok": true, "id": "..." }`. |
| 400 | Missing name or contact (listed in `missing`), or a bad `Idempotency-Key`. |
| 404 | `unknown_url`: the URL is wrong or was rotated. |
| 413 | Body over 64 KB. |
| 415 | Content type it can't read. |
| 429 | Too many requests: 60 an hour and 500 a day per URL. |
| 503 | Try again after 60 seconds (see `Retry-After`). |

## Duplicates

The same `Idempotency-Key` is saved once. A lead with the same phone or email within 24 hours is merged into the first one instead of creating a second.

## Update a lead's stage

Post to your form leads URL with `/status` on the end. Use the `external_id` you sent with the lead.

POST <form leads URL>/status:

```json
{
  "external_id": "your-lead-id",
  "status": "won",
  "value": 1775
}
```

- `status`: `new`, `contacted`, `quoted`, `won`, `lost` or `spam` (`spam` is saved as lost). `value` is optional, in dollars.
- `contacted` and `quoted` never move a booked lead back.
- Changes you send aren't echoed back to your [lead updates webhook](https://measuredbid.com/docs/webhooks#updates).
- Answers: 200 `{ "ok": true, "id", "status" }`, 400, 404 `unknown_url` or `unknown_lead`, 429 after 600 an hour.

> **Why these leads skip the webhook.** Leads sent in through this URL are not forwarded to the new lead webhook or the CRM app, so a CRM that sends leads in can't receive its own leads back in a loop.
