---
search:
  tags:
    - Leads
    - POST
seo:
  description: >-
    Creates one lead for one Preferred Partner. 201 when this call inserts the
    row, whether… Reference for the POST /api/leads endpoint in the Comarketing
    API.
sidebar:
  label: Send a lead
  badge: POST
title: Send a lead
type: openapi-operation
---
Creates one lead for one Preferred Partner. `201` when this call inserts the row, whether the partner received it or it is queued for budget or payment.

Unknown fields are rejected. `consentAt` is required, must parse as a timestamp, and cannot be in the future. An invalid phone creates nothing.

Omit `serviceId` when `serviceIdRequired` is false. The API pins the single Default service, or the single non-Default service. Omit `memberEmail` when this account's own system sent the lead. When `memberEmail` is set, it must be an active member of this account. An unrecognized email creates no lead and no idempotency row.

Send `Idempotency-Key` to make a retry safe for 24 hours. The key is scoped to this account and `agreementId`. The same key, phone, and email returns the original `201` and the original `id`. It does not create a second lead. A declined lead still replays that `201`. The same key with a different phone or email is `409` and creates nothing. No `Idempotency-Key` header means every call creates a lead. A second call while the first is still running is `503` and creates nothing.

`POST /api/leads`

**Request body** (`application/json`, required)

- `agreementId` (string, required)
- `categoryId` (string, required)
- `serviceId` (string | null) — Required when the category's \`serviceIdRequired\` is true. Otherwise omit it or send null.
- `name` (string, required)
- `phone` (string, required)
- `email` (string<email>, required)
- `notes` (string | null)
- `consentAt` (string<date-time>, required) — When the person consented. Required, must parse as a timestamp, and cannot be in the future.
- `memberEmail` (string | null) — Omit or send null when this account's own system sent the lead. When set, it must be an active member of this account.

Request body example:

```json
{
  "agreementId": "agr_id",
  "categoryId": "cat_id",
  "serviceId": null,
  "name": "Sam Rivera",
  "phone": "5551234567",
  "email": "sam@example.com",
  "notes": null,
  "consentAt": "2026-01-15T12:00:00.000Z",
  "memberEmail": null
}
```

**Responses**

- `201` — The lead was created, or this idempotency key replayed the original create. Status starts at \`pending\`. \`delivered\` with \`pending\` is the accepted state.
- `401` — The key is missing or unknown.
- `403` — The key cannot send leads.
- `404` — The agreement is outside this key.
- `409` — The idempotency key was already used for a different phone or email. Nothing is created.
- `422` — The body, phone, consent time, category, service, or member email is invalid. Nothing is created.
- `503` — The lead was not saved, or the same idempotency key is still in flight. Retry a 503 that says the lead was not saved. A 503 creates nothing.

Response example, 201 · Delivered:

```json
{
  "id": "lead_id",
  "status": "pending",
  "delivery": "delivered"
}
```

Response example, 201 · Queued:

```json
{
  "id": "lead_id",
  "status": "pending",
  "delivery": "queued",
  "queuedReason": "budget_exceeded"
}
```

Response example, 401:

```json
{
  "error": "Invalid API key."
}
```

Response example, 403:

```json
{
  "error": "This key cannot send leads."
}
```

Response example, 404:

```json
{
  "error": "Agreement is not an active Preferred Partner for this account."
}
```

Response example, 409:

```json
{
  "error": "This idempotency key was already used for a different client."
}
```

Response example, 422 · Invalid body:

```json
{
  "error": "Request body is invalid."
}
```

Response example, 422 · Invalid phone:

```json
{
  "error": "Phone number is invalid."
}
```

Response example, 422 · Consent time:

```json
{
  "error": "consentAt cannot be in the future."
}
```

Response example, 503 · Not saved:

```json
{
  "error": "The lead was not saved. Retry the request."
}
```

Response example, 503 · Still running:

```json
{
  "error": "A request with this idempotency key is still running."
}
```
