Lawfficient API
Leads

Create a lead

POST /api/leads — create a lead with a per-firm API key.

POST /api/leads

Creates a lead. With a per-firm API key (scope leads:write) the payload is validated, the lead lands in the firm's first open pipeline stage, and the created lead is returned in full. A lead.created webhook fires.

Request body

JSON. first_name, last_name, and source are required, plus at least one of email / phone — a lead has to be reachable.

FieldTypeNotes
first_namestringRequired.
last_namestringRequired.
sourcestringRequired. Where the lead came from.
emailstringRequired if no phone.
phonestringRequired if no email.
assignee_idstring | nullOptional firm member (UUID) to assign.
dataobjectOptional firm-defined fields (case type, etc.). Only the fields your firm defines are stored.

Idempotency

Send an Idempotency-Key header to make a create safe to retry — a repeat with the same key returns the original lead instead of creating a second. Use a fresh unique value (e.g. a UUID) per logical create.

Idempotency-Key: 9d2b7c1e-5a4b-4c3d-8e2f-1a2b3c4d5e6f

Example

curl https://app.lawfficient.com/api/leads \
  -H "Authorization: Bearer $LAWFFICIENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9d2b7c1e-5a4b-4c3d-8e2f-1a2b3c4d5e6f" \
  -d '{
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com",
    "source": "partner_referral",
    "data": { "caseType": "Family" }
  }'
201 Created
{
  "id": "3f8c1e2a-1b2c-4d5e-8f90-abcdef012345",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "email": "ada@example.com",
  "phone": "",
  "source": "partner_referral",
  "status": { "key": "new", "name": "New" },
  "assignee_id": null,
  "archived": false,
  "created_at": "2026-06-24T10:00:00.000Z",
  "last_activity_at": "2026-06-24T10:00:00.000Z",
  "data": { "caseType": "Family" }
}

Errors use the error envelope: 422 invalid_request (e.g. no contact method, or an unknown data value), 403 insufficient_scope (the key lacks leads:write), 409 no_open_stage (the firm has no open pipeline stage configured).

Inbound ingestion shares this path. Authenticate with a per-source ingestion key instead of an API key and POST /api/leads is the inbound webhook: it takes the source's mapped fields, dedupes on externalId, and returns { status, leadId }. See the lead-ingestion spec.

On this page