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/leadsQuery Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
pageSize | integer | 10 | Items per page (max 100) |
status | string | - | Filter by status (new, contacted, qualified, lost, won) |
search | string | - | 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
| Parameter | Type | Description |
|---|---|---|
id | guid | Lead 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/leadsRequest Body
json
{
"name": "John Doe",
"email": "john@example.com",
"phone": "+46701234567",
"source": "website",
"notes": "Interested in bathroom renovation"
}Validation Rules
| Field | Rules |
|---|---|
name | Required, max 100 characters |
email | Required, valid email format |
phone | Optional, max 20 characters |
source | Optional, max 50 characters |
notes | Optional, 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
| Parameter | Type | Description |
|---|---|---|
id | guid | Lead 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
| Parameter | Type | Description |
|---|---|---|
id | guid | Lead 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'] });
},
});
}