Base URL: http://localhost:8000/api/v1
LeadFlow AI uses JWT (JSON Web Token) authentication with access and refresh tokens.
POST /api/v1/auth/login/
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword"
}
Response (200 OK):
{
"success": true,
"message": "Login successful.",
"data": {
"access": "eyJhbGciOiJIUzI1NiIs...",
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}
}Include the access token in the Authorization header for all authenticated requests:
Authorization: Bearer <access_token>
POST /api/v1/auth/refresh/
Content-Type: application/json
{
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}
Response (200 OK):
{
"success": true,
"message": "Token refreshed successfully.",
"data": {
"access": "eyJhbGciOiJIUzI1NiIs...",
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}
}| Token | Default Lifetime |
|---|---|
| Access | 15 minutes |
| Refresh | 7 days |
Configure via JWT_ACCESS_TOKEN_LIFETIME_MINUTES and JWT_REFRESH_TOKEN_LIFETIME_DAYS environment variables.
{
"success": true,
"message": "Operation successful.",
"data": { ... }
}{
"success": false,
"message": "Error message.",
"errors": { ... }
}{
"success": false,
"error": {
"status_code": 400,
"message": "Validation failed.",
"details": {
"field_name": ["This field is required."]
}
}
}| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful deletion) |
| 400 | Bad Request / Validation Error |
| 401 | Unauthorized (missing or invalid token) |
| 403 | Forbidden (insufficient permissions) |
| 404 | Not Found |
| 500 | Internal Server Error |
All list endpoints support pagination using page number pagination.
Query Parameters:
| Parameter | Default | Description |
|---|---|---|
page |
1 | Page number |
page_size |
20 | Items per page (max 100) |
Response Format:
{
"success": true,
"pagination": {
"count": 150,
"total_pages": 8,
"current_page": 1,
"page_size": 20,
"next": "http://localhost:8000/api/v1/leads/?page=2",
"previous": null
},
"results": [ ... ]
}List endpoints support filtering, search, and ordering via query parameters.
Filtering:
GET /api/v1/leads/?status=new&source=website
Search:
GET /api/v1/leads/?search=john
Ordering:
GET /api/v1/leads/?ordering=-created_at
GET /api/v1/leads/?ordering=score
Register a new user account.
Request:
{
"email": "user@example.com",
"password": "securepassword123",
"first_name": "John",
"last_name": "Doe",
"business_name": "Acme Corp"
}business_name is optional. If provided, the user becomes a business_owner and a new business is created.
Response (201 Created):
{
"success": true,
"message": "Registration successful.",
"data": {
"user": {
"id": "uuid-string",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"role": "business_owner",
"phone": "",
"avatar": null,
"business": {
"id": "uuid-string",
"name": "Acme Corp"
},
"date_joined": "2026-01-01T00:00:00Z"
},
"tokens": {
"access": "eyJhbGciOiJIUzI1NiIs...",
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}
}
}Obtain JWT tokens.
Request:
{
"email": "user@example.com",
"password": "securepassword123"
}Response (200 OK):
{
"success": true,
"message": "Login successful.",
"data": {
"access": "eyJhbGciOiJIUzI1NiIs...",
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}
}Blacklist the refresh token (requires authentication).
Request:
{
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}Response (200 OK):
{
"success": true,
"message": "Logout successful."
}Refresh the access token.
Request:
{
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}Response (200 OK):
{
"success": true,
"message": "Token refreshed successfully.",
"data": {
"access": "eyJhbGciOiJIUzI1NiIs...",
"refresh": "eyJhbGciOiJIUzI1NiIs..."
}
}Get the current user's profile.
Response (200 OK):
{
"success": true,
"message": "Success.",
"data": {
"id": "uuid-string",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"role": "business_owner",
"phone": "+1234567890",
"avatar": "/media/avatars/avatar.jpg",
"business": {
"id": "uuid-string",
"name": "Acme Corp"
},
"date_joined": "2026-01-01T00:00:00Z"
}
}Update the current user's profile.
Request:
{
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1987654321"
}Response (200 OK):
{
"success": true,
"message": "Profile updated successfully.",
"data": {
"id": "uuid-string",
"email": "user@example.com",
"first_name": "Jane",
"last_name": "Smith",
"role": "business_owner",
"phone": "+1987654321",
"avatar": null,
"business": {
"id": "uuid-string",
"name": "Acme Corp"
},
"date_joined": "2026-01-01T00:00:00Z"
}
}Change the current user's password.
Request:
{
"old_password": "currentpassword",
"new_password": "newsecurepassword123"
}Response (200 OK):
{
"success": true,
"message": "Password changed successfully."
}Request a password reset (sends email if configured).
Request:
{
"email": "user@example.com"
}Response (200 OK):
{
"success": true,
"message": "If the email exists, a password reset link has been sent."
}List all businesses the current user owns or has access to.
Response (200 OK):
{
"success": true,
"pagination": {
"count": 1,
"total_pages": 1,
"current_page": 1,
"page_size": 20,
"next": null,
"previous": null
},
"results": [
{
"id": "uuid-string",
"name": "Acme Corp",
"slug": "acme-corp",
"logo": "/media/business_logos/logo.png",
"website": "https://acme.com",
"industry": "Technology",
"description": "Leading tech company",
"services": ["Consulting", "Development"],
"faq": [{"question": "What do you do?", "answer": "..."}],
"timezone": "UTC",
"operating_hours": {},
"ai_prompt_config": {},
"owner": "uuid-string",
"is_active": true,
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
]
}Create a new business.
Request:
{
"name": "New Business",
"industry": "Healthcare",
"description": "Healthcare solutions",
"services": ["Consulting", "Training"],
"timezone": "America/New_York"
}Response (201 Created):
{
"success": true,
"message": "Created successfully.",
"data": {
"id": "uuid-string",
"name": "New Business",
"slug": "new-business",
...
}
}Retrieve a business by its slug.
Update a business. Only the owner can update.
Deactivate a business (soft delete). Only the owner can deactivate.
Get the AI prompt configuration for a business.
Response (200 OK):
{
"success": true,
"data": {
"ai_prompt_config": {
"greeting": "Hello! Welcome to Acme Corp.",
"qualification_questions": ["What is your budget?"],
"booking_prompt": "Let me schedule a meeting for you."
}
}
}Update the AI prompt configuration. Only the owner can update.
Request:
{
"ai_prompt_config": {
"greeting": "Hi there! How can we help?",
"qualification_questions": ["What is your team size?"]
}
}List all leads for the current business.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status |
source |
string | Filter by source |
assigned_to |
uuid | Filter by assigned user |
search |
string | Search name, email, phone, company |
ordering |
string | Sort by field (prefix - for descending) |
Response (200 OK):
{
"success": true,
"pagination": {
"count": 50,
"total_pages": 3,
"current_page": 1,
"page_size": 20,
"next": "http://localhost:8000/api/v1/leads/leads/?page=2",
"previous": null
},
"results": [
{
"id": "uuid-string",
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890",
"company": "Acme Inc",
"source": "website",
"status": "new",
"score": 0,
"assigned_to": {
"id": "uuid-string",
"email": "sales@acme.com",
"first_name": "Sales",
"last_name": "Rep"
},
"tags": ["enterprise", "demo"],
"notes": "Interested in our product",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
]
}Create a new lead.
Request:
{
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+1987654321",
"company": "Tech Corp",
"source": "referral",
"status": "new",
"score": 25,
"notes": "Referred by John",
"tags": ["warm-lead"]
}Response (201 Created):
{
"success": true,
"message": "Lead created successfully",
"data": {
"id": "uuid-string",
"name": "Jane Smith",
...
}
}Retrieve a lead by ID.
Update a lead.
Delete a lead.
Assign a lead to a user.
Request:
{
"user_id": "uuid-string"
}Response (200 OK):
{
"success": true,
"message": "Lead assigned successfully",
"data": {
"id": "uuid-string",
"name": "Jane Smith",
"assigned_to": {
"id": "uuid-string",
"email": "sales@acme.com",
"first_name": "Sales",
"last_name": "Rep"
},
...
}
}Update a lead's pipeline status.
Request:
{
"status": "contacted"
}Valid statuses: new, contacted, qualified, unqualified, meeting_booked, won, lost
Response (200 OK):
{
"success": true,
"message": "Lead status updated successfully",
"data": {
"id": "uuid-string",
"status": "contacted",
...
}
}Update status for multiple leads at once.
Request:
{
"lead_ids": ["uuid-1", "uuid-2", "uuid-3"],
"status": "qualified"
}Response (200 OK):
{
"success": true,
"message": "3 leads updated successfully",
"data": {
"updated_count": 3
}
}List all notes for a lead.
Create a note for a lead.
Request:
{
"content": "Had a great call with the lead. They are interested in our enterprise plan."
}Response (201 Created):
{
"success": true,
"message": "Lead note created successfully",
"data": {
"id": "uuid-string",
"lead": "uuid-string",
"content": "Had a great call with the lead...",
"created_by": {
"id": "uuid-string",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe"
},
"created_at": "2026-01-01T00:00:00Z"
}
}Delete a note from a lead.
List all conversations for the current business.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter: active, paused, closed, ai_handoff |
channel |
string | Filter: web, email, sms, whatsapp |
ai_paused |
boolean | Filter by AI pause state |
search |
string | Search lead name or email |
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"business": "uuid-string",
"lead": {
"id": "uuid-string",
"name": "Jane Smith",
"email": "jane@example.com"
},
"status": "active",
"channel": "web",
"ai_paused": false,
"assigned_to": null,
"last_message_at": "2026-01-01T12:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T12:00:00Z"
}
]
}Create a new conversation.
Request:
{
"lead": "uuid-string",
"channel": "web",
"status": "active"
}Retrieve a conversation with full details including recent messages.
Update a conversation.
Pause AI auto-responses. A system message is added to the conversation.
Response (200 OK):
{
"success": true,
"message": "AI paused successfully",
"data": {
"id": "uuid-string",
"ai_paused": true,
...
}
}Resume AI auto-responses.
Hand off conversation to the current user. Sets status to ai_handoff, assigns the user, and pauses AI.
Response (200 OK):
{
"success": true,
"message": "Handoff successful",
"data": {
"id": "uuid-string",
"status": "ai_handoff",
"ai_paused": true,
"assigned_to": {
"id": "uuid-string",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe"
},
...
}
}Close a conversation.
List all messages in a conversation.
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"conversation": "uuid-string",
"sender_type": "lead",
"sender_id": null,
"content": "Hi, I'm interested in your product",
"channel": "web",
"is_ai_generated": false,
"metadata": {},
"created_at": "2026-01-01T00:00:00Z"
},
{
"id": "uuid-string",
"conversation": "uuid-string",
"sender_type": "ai",
"sender_id": null,
"content": "Hello! Welcome to Acme Corp. How can I help you today?",
"channel": "web",
"is_ai_generated": true,
"metadata": {},
"created_at": "2026-01-01T00:00:01Z"
}
]
}Send a message in a conversation (as staff).
Request:
{
"content": "Thanks for reaching out! Let me connect you with our sales team."
}Response (201 Created):
{
"success": true,
"message": "Message sent successfully",
"data": {
"id": "uuid-string",
"conversation": "uuid-string",
"sender_type": "staff",
"sender_id": "uuid-string",
"content": "Thanks for reaching out!...",
"channel": "web",
"is_ai_generated": false,
"metadata": {},
"created_at": "2026-01-01T12:00:00Z"
}
}Mark a message as read.
Execute the AI agent for a specific lead. The agent will analyze the lead, conversation history, and business context, then take an appropriate action.
Request:
{
"lead_id": "uuid-string"
}Response (201 Created):
{
"success": true,
"message": "Agent execution completed",
"data": {
"execution_id": "uuid-string",
"status": "completed",
"decision": "send_message",
"tool_output": {
"tool": "send_email",
"to": "lead@example.com",
"subject": "Welcome! Let's connect",
"body_preview": "Hi there, thank you for your interest...",
"sent_at": "2026-01-01T12:00:00Z"
},
"messages": [
{
"role": "assistant",
"content": "Decision: send_message"
}
]
}
}Possible decisions: send_message, book_meeting, schedule_followup, update_lead_status, notify_sales, search_knowledge, create_note
List agent execution history.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
business_id |
uuid | Filter by business |
lead_id |
uuid | Filter by lead |
status |
string | Filter: pending, running, completed, failed, paused |
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"lead": {
"id": "uuid-string",
"name": "Jane Smith"
},
"business": {
"id": "uuid-string",
"name": "Acme Corp"
},
"conversation": "uuid-string",
"status": "completed",
"input_data": {
"lead_id": "uuid-string",
"business_id": "uuid-string"
},
"output_data": {
"decision": "send_message",
"tool_output": { ... }
},
"error_message": "",
"started_at": "2026-01-01T12:00:00Z",
"completed_at": "2026-01-01T12:00:01Z",
"created_at": "2026-01-01T12:00:00Z"
}
]
}Retrieve a specific agent execution.
List agent memories (knowledge the agent has learned).
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
business_id |
uuid | Filter by business |
lead_id |
uuid | Filter by lead |
memory_type |
string | Filter: conversation, business_profile, customer_info, interaction |
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"business": {
"id": "uuid-string",
"name": "Acme Corp"
},
"lead": {
"id": "uuid-string",
"name": "Jane Smith"
},
"memory_type": "interaction",
"content": {
"decision": "send_message",
"tool_output": { ... }
},
"created_at": "2026-01-01T12:00:00Z",
"updated_at": "2026-01-01T12:00:00Z"
}
]
}Retrieve a specific memory.
List all knowledge base documents for the current business.
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"business": "uuid-string",
"title": "Product Pricing Guide",
"file": "/media/knowledge/2026/01/pricing.pdf",
"content": "Our pricing starts at...",
"document_type": "pdf",
"is_indexed": true,
"metadata": {},
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
]
}Upload a knowledge base document (multipart/form-data).
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Document title |
file |
file | Yes | Document file (PDF, DOCX, TXT, MD) |
document_type |
string | Yes | One of: pdf, docx, txt, md |
Retrieve a document.
Update a document.
Delete a document.
Search knowledge base documents by content.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | Yes | Search query |
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"title": "Product Pricing Guide",
"content": "...pricing details...",
"document_type": "pdf",
"is_indexed": true,
...
}
]
}List calendar integrations.
Create a calendar integration.
Request:
{
"provider": "google",
"credentials": {
"access_token": "...",
"refresh_token": "..."
}
}Test the calendar connection.
Response (200 OK):
{
"success": true,
"message": "Connection test successful",
"data": {
"connected": true,
"calendar_name": "Primary Calendar"
}
}List calendar events.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
start |
datetime | Filter events starting after this date |
end |
datetime | Filter events ending before this date |
status |
string | Filter: scheduled, completed, cancelled, rescheduled |
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"business": "uuid-string",
"lead": {
"id": "uuid-string",
"name": "Jane Smith"
},
"title": "Discovery call with Jane Smith",
"description": "Initial qualification call",
"start_time": "2026-01-02T14:00:00Z",
"end_time": "2026-01-02T14:30:00Z",
"status": "scheduled",
"external_id": "google-event-id",
"metadata": {},
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
]
}Create a calendar event. If a calendar integration is active, the event is also created in the external calendar.
Request:
{
"lead": "uuid-string",
"title": "Follow-up Meeting",
"description": "Discuss proposal",
"start_time": "2026-01-02T14:00:00Z",
"end_time": "2026-01-02T14:30:00Z"
}Retrieve a calendar event.
Update a calendar event. Status changes are synced to the external calendar.
Delete a calendar event.
Get dashboard analytics summary.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
days |
integer | 30 | Analysis period in days |
Response (200 OK):
{
"success": true,
"message": "Success.",
"data": {
"date": "2026-01-01",
"period_start": "2026-01-01",
"period_end": "2026-01-31",
"total_leads": 150,
"new_leads": 25,
"qualified_leads": 15,
"meetings_booked": 8,
"conversion_rate": 5.3,
"avg_response_time": 12.5,
"ai_interactions": 45,
"active_conversations": 12,
"trend": {
"total_leads": 15.2,
"meetings_booked": 33.3,
"conversion_rate": -2.1
}
}
}List historical analytics snapshots.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
start_date |
date | Start date (YYYY-MM-DD) |
end_date |
date | End date (YYYY-MM-DD) |
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"business": "uuid-string",
"date": "2026-01-01",
"total_leads": 150,
"new_leads": 25,
"qualified_leads": 15,
"meetings_booked": 8,
"conversion_rate": 5.3,
"avg_response_time": 12.5,
"ai_interactions": 45,
"active_conversations": 12,
"created_at": "2026-01-01T23:59:59Z"
}
]
}List notifications for the current user.
Response (200 OK):
{
"success": true,
"pagination": { ... },
"results": [
{
"id": "uuid-string",
"user": "uuid-string",
"business": "uuid-string",
"title": "Lead Assigned",
"message": "Jane Smith has been assigned to you.",
"notification_type": "lead_assigned",
"is_read": false,
"link": "/leads/uuid-string",
"metadata": {},
"created_at": "2026-01-01T12:00:00Z"
}
]
}Retrieve a notification.
Mark a single notification as read.
Mark all unread notifications as read.
Response (200 OK):
{
"success": true,
"message": "5 notifications marked as read",
"data": {
"updated_count": 5
}
}Get the count of unread notifications.
Response (200 OK):
{
"success": true,
"message": "Success.",
"data": {
"unread_count": 12
}
}API rate limits:
| User Type | Rate |
|---|---|
| Anonymous | 100 requests/hour |
| Authenticated | 1000 requests/hour |
Exceeding the limit returns a 429 Too Many Requests response.