REST API Endpoint Reference Guide
This document is the definitive REST API endpoint reference for MetaPilot. It details all request paths, HTTP methods, authorization levels, request parameters, JSON body schemas, success responses, error payloads, and cURL examples for every endpoint.
1. Authentication Endpoints (/api/auth/
)
/api/auth/1.1 User Login
Authenticates user credentials and issues a pair of JWT Access (60-min TTL) and Refresh (7-day TTL) tokens.
- HTTP Method:
POST - Path:
/api/auth/login/ - Authentication: None ()
AllowAny - Headers:
http
Content-Type: application/json
Request Payload:
json
{
"email": "admin@metapilot.in",
"password": "AdminPassword123"
}
Success Response (HTTP 200 OK
):
HTTP 200 OKjson
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzcxOTEwNDAwLCJqdGkiOiJmYTlhMzRjOSIsInVzZXJfaWQiOiJjMDI3MTJlMy1hNDU2LTRkYmMtOGQ0Zi1kMTljYTQ2ZGY3NjgiLCJyb2xlIjoiU1VQRVJfQURNSU4iLCJ0ZW5hbnRfaWQiOm51bGx9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIiLCJleHAiOjE3NzI1MTUyMDAsImp0aSI6IjlmMWEzYjRjIiwidXNlcl9pZCI6ImMwMjcxMmUzLWE0NTYtNGRiYy04ZDRmLWQxOWNhNDZkZjc2OCJ9...",
"user": {
"id": "c02712e3-a456-4dbc-8d4f-d19ca46df768",
"email": "admin@metapilot.in",
"role": "SUPER_ADMIN",
"first_name": "Super",
"last_name": "Admin",
"is_active": true,
"tenant": null,
"agency": null
}
}
Error Responses:
- (Invalid credentials):
HTTP 401 Unauthorizedjson{ "detail": "No active account found with the given credentials" } - (Missing required fields):
HTTP 400 Bad Requestjson{ "email": ["This field is required."], "password": ["This field is required."] }
cURL Example:
bash
curl -X POST http://localhost:8000/api/auth/login/ \
-H "Content-Type: application/json" \
-d '{"email": "admin@metapilot.in", "password": "AdminPassword123"}'
1.2 Refresh Access Token
Obtains a fresh JWT Access Token using a valid Refresh Token.
- HTTP Method:
POST - Path:
/api/auth/token/refresh/ - Authentication: None
- Request Payload:
json
{ "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } - Success Response ():
HTTP 200 OKjson{ "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.new_access_token..." } - Error Response ():
HTTP 401 Unauthorizedjson{ "detail": "Token is invalid or expired", "code": "token_not_valid" }
1.3 Logout / Blacklist Refresh Token
Invalidates a refresh token on user logout.
- HTTP Method:
POST - Path:
/api/auth/token/blacklist/ - Authentication: JWT Access Token ()
IsAuthenticated - Headers:
http
Authorization: Bearer <access_token> Content-Type: application/json - Request Payload:
json
{ "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } - Success Response ():
HTTP 200 OKjson{ "message": "Token blacklisted successfully" }
2. Client / Tenant Management Endpoints (/api/clients/
)
/api/clients/2.1 List Tenants
Retrieves a paginated list of tenants. Super Admins view all tenants; Agency Admins view clients under their agency.
- HTTP Method:
GET - Path:
/api/clients/ - Authentication: JWT Access Token (or
SUPER_ADMIN)AGENCY_ADMIN - Query Parameters:
- (optional, default=1): Page number.
page - (optional): Filter by tenant name or slug.
search
Headers:
http
Authorization: Bearer <access_token>
Success Response (HTTP 200 OK
):
HTTP 200 OKjson
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "96598ec0-9ee5-4e10-9948-85894cbc9fcf",
"name": "Acme Retail Org",
"slug": "acme-retail",
"agency": "405b16e0-3215-40fc-bac6-c3fb9b2649c4",
"agency_name": "Apex Marketing Agency",
"is_active": true,
"created_at": "2026-07-23T19:38:16Z"
},
{
"id": "2096415f-0d26-4842-8c45-dc3c0690a879",
"name": "Global Health Corp",
"slug": "global-health",
"agency": "405b16e0-3215-40fc-bac6-c3fb9b2649c4",
"agency_name": "Apex Marketing Agency",
"is_active": true,
"created_at": "2026-07-23T19:35:10Z"
}
]
}
2.2 Create Tenant Account
Creates a new tenant account and encrypts its Meta WhatsApp access token using Fernet AES-256.
- HTTP Method:
POST - Path:
/api/clients/ - Authentication: JWT Access Token (or
SUPER_ADMIN)AGENCY_ADMIN
Request Payload:
json
{
"name": "Acme Retail Org",
"slug": "acme-retail",
"agency": "405b16e0-3215-40fc-bac6-c3fb9b2649c4",
"wa_access_token": "EAAGm0PX4ZC74BAO...",
"wba_id": "100982348192381",
"phone_number_id": "109283749182374"
}
Success Response (HTTP 201 Created
):
HTTP 201 Createdjson
{
"id": "96598ec0-9ee5-4e10-9948-85894cbc9fcf",
"name": "Acme Retail Org",
"slug": "acme-retail",
"agency": "405b16e0-3215-40fc-bac6-c3fb9b2649c4",
"is_active": true,
"created_at": "2026-07-23T19:38:16Z"
}
Error Responses:
- (Duplicate slug or invalid access token format):
HTTP 400 Bad Requestjson{ "slug": ["Tenant with this slug already exists."] } - (Missing Fernet Encryption Key in production):
HTTP 500 Internal Server Errorjson{ "error": "Fernet key must be 32 url-safe base64-encoded bytes." }
cURL Example:
bash
curl -X POST http://localhost:8000/api/clients/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Retail Org",
"slug": "acme-retail",
"agency": "405b16e0-3215-40fc-bac6-c3fb9b2649c4",
"wa_access_token": "EAAGm0PX4ZC74BAO..."
}'
2.3 Retrieve Tenant Details
- HTTP Method:
GET - Path:
/api/clients/{id}/ - Authentication: JWT Access Token
- Success Response ():
HTTP 200 OKjson{ "id": "96598ec0-9ee5-4e10-9948-85894cbc9fcf", "name": "Acme Retail Org", "slug": "acme-retail", "agency": "405b16e0-3215-40fc-bac6-c3fb9b2649c4", "is_active": true, "created_at": "2026-07-23T19:38:16Z" }
2.4 Retrieve Tenant Configurations
Retrieves stored configurations for a tenant (excluding raw secret tokens).
- HTTP Method:
GET - Path:
/api/clients/{id}/configs/ - Authentication: JWT Access Token (or higher)
TENANT_ADMIN - Success Response ():
HTTP 200 OKjson[ { "id": "e81f9a23-45bc-48d2-81e1-92fa023bf891", "provider": "meta", "key_name": "wa_access_token", "is_encrypted": true, "updated_at": "2026-07-23T19:38:16Z" } ]
3. User Management Endpoints (/api/users/
)
/api/users/3.1 List Users
- HTTP Method:
GET - Path:
/api/users/ - Authentication: JWT Access Token (,
SUPER_ADMIN,AGENCY_ADMIN)TENANT_ADMIN - Headers:
http
Authorization: Bearer <access_token> X-Tenant-ID: 96598ec0-9ee5-4e10-9948-85894cbc9fcf - Success Response ():
HTTP 200 OKjson{ "count": 1, "results": [ { "id": "d76f7251-46aa-4ff0-8915-2439b146ed3d", "email": "operator@acme.com", "role": "TENANT_USER", "first_name": "John", "last_name": "Doe", "is_active": true } ] }
3.2 Create User
- HTTP Method:
POST - Path:
/api/users/ - Authentication: JWT Access Token (or higher)
TENANT_ADMIN - Request Payload:
json
{ "email": "operator@acme.com", "password": "UserPassword123", "role": "TENANT_USER", "first_name": "John", "last_name": "Doe", "tenant": "96598ec0-9ee5-4e10-9948-85894cbc9fcf" } - Success Response ():
HTTP 201 Createdjson{ "id": "d76f7251-46aa-4ff0-8915-2439b146ed3d", "email": "operator@acme.com", "role": "TENANT_USER", "first_name": "John", "last_name": "Doe" }
4. Campaign Broadcast Endpoints (/api/campaigns/
)
/api/campaigns/4.1 List Campaigns
- HTTP Method:
GET - Path:
/api/campaigns/ - Authentication: JWT Access Token
- Headers:
http
Authorization: Bearer <access_token> X-Tenant-ID: 96598ec0-9ee5-4e10-9948-85894cbc9fcf - Success Response ():
HTTP 200 OKjson{ "count": 1, "results": [ { "id": "5f8a12e3-99b4-4c8d-8e4f-b19ca46df768", "name": "Summer Flash Sale 2026", "status": "COMPLETED", "template": "128937192837192", "scheduled_at": "2026-07-24T02:00:00Z", "total_recipients": 100, "sent_count": 98, "failed_count": 2 } ] }
4.2 Create & Schedule Campaign
- HTTP Method:
POST - Path:
/api/campaigns/ - Authentication: JWT Access Token (or
TENANT_ADMIN)TENANT_USER - Request Payload:
json
{ "name": "Summer Flash Sale 2026", "template": "128937192837192", "scheduled_at": "2026-07-24T02:00:00Z", "variable_bindings": { "1": "First_Name", "2": "FLASH20" } } - Success Response ():
HTTP 201 Createdjson{ "id": "5f8a12e3-99b4-4c8d-8e4f-b19ca46df768", "name": "Summer Flash Sale 2026", "status": "SCHEDULED", "scheduled_at": "2026-07-24T02:00:00Z" }
5. Notifications & Dashboard Endpoints
5.1 Unread Notifications Count
- HTTP Method:
GET - Path:
/api/notifications/unread-count/ - Authentication: JWT Access Token
- Success Response ():
HTTP 200 OKjson{ "unread_count": 11 }
5.2 Dashboard Analytics Summary
- HTTP Method:
GET - Path:
/api/dashboard/analytics/ - Query Parameters: or
range=weekrange=month - Authentication: JWT Access Token
- Success Response ():
HTTP 200 OKjson{ "range": "week", "total_messages_sent": 1420, "total_delivered": 1398, "total_read": 1150, "active_campaigns": 3, "response_rate_percentage": 82.4 }
6. Meta Webhook Ingestion Endpoint (/api/webhooks/whatsapp/
)
/api/webhooks/whatsapp/6.1 Meta Webhook Ingestion
Receives real-time events from Meta WhatsApp Cloud API (inbound messages, status receipts).
- HTTP Method:
POST - Path:
/api/webhooks/whatsapp/ - Authentication: HMAC SHA-256 header validation against tenant's App Secret.
X-Hub-Signature-256
Request Headers:
http
X-Hub-Signature-256: sha256=7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b
Content-Type: application/json
Request Payload:
json
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "100982348192381",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "+14155552671",
"phone_number_id": "109283749182374"
},
"contacts": [
{
"profile": { "name": "Jane Smith" },
"wa_id": "14155552671"
}
],
"messages": [
{
"from": "14155552671",
"id": "wamid.HBgLMTQxNTU1NTI2NzEVAgARGBI1RjM4NkE3RjU4RjA1QkQ0AA==",
"timestamp": "1771910400",
"text": { "body": "I would like to inquire about pricing." },
"type": "text"
}
]
},
"field": "messages"
}
]
}
]
}
Success Response (HTTP 200 OK
):
HTTP 200 OKjson
{
"status": "received"
}