Skip to content

Leads API

Lead management endpoints for the CRM functionality.

Status

These endpoints are planned and not yet implemented.

Endpoints

List Leads

Returns a paginated list of leads.

http
GET /api/leads

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
pageSizeinteger10Items per page (max 100)
statusstring-Filter by status (new, contacted, qualified, lost, won)
searchstring-Search by name or email

Success Response 200 OK

json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "+46701234567",
      "status": "new",
      "source": "website",
      "createdAt": "2026-01-01T00:00:00Z"
    }
  ],
  "meta": {
    "total": 1,
    "page": 1,
    "pageSize": 10
  }
}

Get Lead

Returns a single lead by ID.

http
GET /api/leads/{id}

Path Parameters

ParameterTypeDescription
idguidLead ID

Success Response 200 OK

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "+46701234567",
    "status": "new",
    "source": "website",
    "notes": "Interested in bathroom renovation",
    "createdAt": "2026-01-01T00:00:00Z",
    "updatedAt": "2026-01-10T15:30:00Z"
  },
  "error": null,
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "abc-123"
  }
}

Error Response 404 Not Found

Lead does not exist.


Create Lead

Creates a new lead.

http
POST /api/leads

Request Body

json
{
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "+46701234567",
  "source": "website",
  "notes": "Interested in bathroom renovation"
}

Validation Rules

FieldRules
nameRequired, max 100 characters
emailRequired, valid email format
phoneOptional, max 20 characters
sourceOptional, max 50 characters
notesOptional, max 2000 characters

Success Response 201 Created

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "error": null,
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "def-456"
  }
}

Update Lead

Updates an existing lead.

http
PUT /api/leads/{id}

Path Parameters

ParameterTypeDescription
idguidLead ID

Request Body

json
{
  "name": "John Doe",
  "email": "john.doe@example.com",
  "status": "contacted",
  "notes": "Called on Jan 10, scheduled site visit"
}

Success Response 200 OK

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "John Doe",
    "email": "john.doe@example.com",
    "status": "contacted"
  },
  "error": null,
  "meta": {
    "timestamp": "2026-01-12T10:00:00Z",
    "requestId": "ghi-789"
  }
}

Delete Lead

Deletes a lead.

http
DELETE /api/leads/{id}

Path Parameters

ParameterTypeDescription
idguidLead ID

Success Response 204 No Content

No response body.


Lead Status Flow

┌─────────┐     ┌───────────┐     ┌───────────┐
│   New   │ ──► │ Contacted │ ──► │ Qualified │
└─────────┘     └───────────┘     └───────────┘
                     │                   │
                     ▼                   ▼
                ┌────────┐          ┌────────┐
                │  Lost  │          │  Won   │
                └────────┘          └────────┘

Frontend Integration

typescript
// features/leads/hooks/useLeads.ts
export function useLeads(params?: LeadQueryParams) {
  return useQuery({
    queryKey: ['leads', params],
    queryFn: () => leadsApi.getAll(params),
  });
}

export function useLead(id: string) {
  return useQuery({
    queryKey: ['leads', id],
    queryFn: () => leadsApi.getById(id),
  });
}

export function useCreateLead() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateLeadRequest) => leadsApi.create(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['leads'] });
    },
  });
}

export function useUpdateLead() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateLeadRequest }) =>
      leadsApi.update(id, data),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['leads', id] });
      queryClient.invalidateQueries({ queryKey: ['leads'] });
    },
  });
}

Built with VitePress | v1.1.0