# Leads

Send enquiries from your own forms to the clinic's CRM: field aliases, warnings, strict mode.

A lead is a patient's enquiry. This page explains how to send one from your own form so that it reaches the clinic's CRM exactly like an enquiry from the clinic's site.

## Send a lead

Call [POST /leads](https://pozyskajpacjenta.pl/docs/reference/leads/create-lead) from your server with the form's fields as JSON:

```bash cURL
curl -X POST "https://app.pozyskajpacjenta.pl/api/v1/leads" \
  -H "Authorization: Bearer $PP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Anna Kowalska", "phone": "+48 600 100 200", "message": "Proszę o kontakt w sprawie higienizacji.", "utm_source": "google" }'
```

```json 200 OK
{
  "ok": true,
  "leadId": "rS2bIhedVSStSQLc7DL_T"
}
```

## What happens next

The lead lands in the clinic's panel under **Zapytania**, with its activity history. Reception gets an e-mail at the clinic's notification address (a text message only when the clinic connected its own SMS operator account), and a configured [webhook](https://pozyskajpacjenta.pl/docs/webhooks) receives `lead.created`.

## Field names

Field names are matched loosely, in Polish or English and in any letter case; the first non-empty alias wins:

| Lead field | Accepted names |
| --- | --- |
| `name` | `name`, `full_name`, `fullname`, `imie`, `imię`, `imie_nazwisko` |
| `phone` | `phone`, `tel`, `telefon`, `phone_number`, `numer` |
| `email` | `email`, `e-mail`, `mail` |
| `message` | `message`, `wiadomosc`, `wiadomość`, `msg`, `comment`, `opis` |

Nothing is lost: fields outside the table are kept with the lead as extra fields and shown in the CRM (for example `"formularz": "landing-higienizacja"`). Campaign parameters `utm_source`, `utm_medium`, `utm_campaign`, `gclid` and `fbclid` are stored as the lead's tracking data too: pass them on from your landing pages.

## A lead without a contact

For the clinic to call back, send a phone number (at least 6 digits) or an e-mail address. The server looks for one under the aliases, then in the other fields (for example `phoneNumber`, or any value that looks like an e-mail). A lead without either is still stored, and the response warns you:

```json 200 OK
{
  "ok": true,
  "leadId": "Sj2mY5tuT1UZP0QfgdvLH",
  "warnings": [
    "missing_contact"
  ]
}
```

To refuse such a lead instead, add `?strict=1`: nothing is stored and you get 400 `missing_contact`. Your form can then ask for a phone or an e-mail.

## Errors

| Status | code | Meaning |
| --- | --- | --- |
| 400 | `invalid_json` | The body is not JSON. Nothing was stored. |
| 400 | `invalid_body` | The JSON is not an object. Nothing was stored. |
| 400 | `missing_contact` | Only with `?strict=1`: no phone and no e-mail. |
| 400 | `invalid_time_request` | Only with `?strict=1`: `timeRequest` failed validation. |
| 401 | | The key is missing or not valid. |
| 429 | | Over 120 requests in this minute. |

## Other ways to send a lead

- `POST /api/v1/leads` is the endpoint for new integrations: Bearer header only, counted in the per-key limit.
- `POST /api/ingest/lead` is the older endpoint for form tools and automations that cannot set headers. It takes the same key and the same field mapping, and also accepts the key in the address (`?key=…`). Use v1 in new code.
- The clinic's **embed script** puts a form on a site that has no backend. It uses a separate public key (`ppe_…`) from **Ustawienia → Integracje → Skrypt embed**. Never put the secret `pp_live_` key in browser code.

Spam traps (honeypot fields) apply to browser forms only; the API accepts a request with a valid key as it is.

## Privacy and a request for a time

Show the clinic's information clause under your form and send its version with the lead: see [Privacy](https://pozyskajpacjenta.pl/docs/concepts/privacy). A lead can also carry a request for a time: see [Booking modes](https://pozyskajpacjenta.pl/docs/concepts/booking-modes#request-a-time).
