ComplyAI API Documentation
Complete API reference for all internal and external endpoints
Overview
ComplyAI's backend consists of multiple microservices, each exposing REST APIs. This documentation covers all endpoints across our services.
API Architecture
┌─────────────────┐
│ API Gateway │
│ (AWS ALB/NLB) │
└────────┬────────┘
│
┌──────────────────────────────┼──────────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Core API │ │ Main API │ │ Maestro │
│ /api/core/* │ │ /api/main/* │ │ /api/maestro/*│
│ │ │ │ │ │
│ Port: 5000 │ │ Port: 5001 │ │ Port: 5002 │
└────────────────┘ └────────────────┘ └────────────────┘
│ │ │
└──────────────────────────────┴──────────────────────────────┘
│
┌────────┴────────┐
│ PostgreSQL │
│ Database │
└─────────────────┘
Base URLs
| Environment | Base URL |
|---|---|
| Production | https://api.gocomply.ai |
| Staging | https://staging-api.gocomply.ai |
| Development | http://localhost:5000 |
Authentication
API Token Authentication
Internal service-to-service calls use API tokens:
POST /api/endpoint HTTP/1.1
Authorization: Bearer {API_TOKEN}
Content-Type: application/json
User Session Authentication
User-facing endpoints use Flask-Security sessions with CSRF protection:
POST /api/endpoint HTTP/1.1
Cookie: session={SESSION_COOKIE}
X-CSRF-Token: {CSRF_TOKEN}
Content-Type: application/json
Service: complyai-core
Base Path: /
Authentication Endpoints
POST /auth/login
Authenticate user via OAuth/Auth0
Request:
{
"email": "user@example.com",
"password": "string",
"provider": "auth0"
}
Response (200):
{
"user": {
"id": 42,
"email": "user@example.com",
"name": "Jane Smith",
"roles": ["client"]
},
"token": "eyJ...",
"expires_at": "2024-12-25T00:00:00Z"
}
Organization Endpoints
GET /orgs/
Get current user's organization
Response (200):
{
"id": 15,
"name": "Acme Advertising",
"subscription_plan": "professional",
"subscription_start_date": "2024-01-01T00:00:00Z",
"subscription_end_date": "2024-12-31T23:59:59Z",
"active": true,
"average_score": 85.5,
"users": [
{"id": 42, "name": "Jane Smith", "email": "jane@acme.com"}
]
}
POST /orgs/create
Create new organization
Request:
{
"name": "New Company Inc",
"contact_person": "John Director"
}
Response (201):
{
"id": 16,
"name": "New Company Inc",
"message": "Organization created successfully"
}
Business Manager Endpoints
GET /businessmanagers/
List connected business managers
Response (200):
{
"data": [
{
"id": 100,
"facebook_id": "123456789012345",
"name": "Acme BM",
"role": "ADMIN",
"ad_accounts_count": 5
}
]
}
POST /businessmanagers/connect
Connect a new business manager
Request:
{
"access_token": "EAAGx...",
"business_id": "123456789012345"
}
Response (201):
{
"id": 101,
"facebook_id": "123456789012345",
"name": "New Business Manager",
"system_user_id": "12345678901234567",
"message": "Business manager connected successfully"
}
Ad Account Endpoints
GET /adaccounts/
List ad accounts for organization
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number (default: 1) |
limit | integer | No | Items per page (default: 20) |
status | string | No | Filter by status |
bm_id | string | No | Filter by business manager |
Response (200):
{
"data": [
{
"id": 500,
"facebook_id": "act_123456789",
"name": "Acme - US Market",
"currency": "USD",
"account_status": 1,
"average_score": 87.2,
"business_manager": {
"id": 100,
"name": "Acme BM"
}
}
],
"paging": {
"current_page": 1,
"total_pages": 5,
"total_items": 100
}
}
Ad Endpoints
GET /ads/
List ads for organization
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number |
limit | integer | No | Items per page |
status | string | No | Filter: ACTIVE, PAUSED, DISAPPROVED |
ad_account_id | string | No | Filter by ad account |
date_from | date | No | Filter by date range |
date_to | date | No | Filter by date range |
Response (200):
{
"data": [
{
"id": 5000,
"facebook_id": "23849203842934",
"name": "Summer Sale Banner",
"status": "ACTIVE",
"effective_status": "ACTIVE",
"score": {
"overall": 85.5,
"text": 88.2,
"media": 82.8
},
"creative": {
"title": "50% Off Summer Sale",
"text": "Shop our biggest sale...",
"image_url": "https://..."
}
}
]
}
GET /ads/{ad_id}
Get specific ad details
Response (200):
{
"id": 5000,
"facebook_id": "23849203842934",
"name": "Summer Sale Banner",
"status": "ACTIVE",
"effective_status": "ACTIVE",
"ad_account": {
"id": 500,
"name": "Acme - US Market"
},
"creative": {
"title": "50% Off Summer Sale",
"text": "Shop our biggest sale of the year!",
"description": "Limited time offer",
"image_url": "https://cdn.../img.jpg",
"destination_url": "https://acme.com/sale",
"call_to_action": "SHOP_NOW"
},
"score": {
"overall": 85.5,
"text_score": 88.2,
"media_score": 82.8
},
"compliance_status": {
"status": "Open",
"facebook_reason": null,
"last_updated": "2024-06-25T10:00:00Z"
}
}
User Endpoints
GET /user/
Get current user profile
Response (200):
{
"id": 42,
"email": "jane@acme.com",
"name": "Jane Smith",
"avatar": "https://...",
"roles": ["client"],
"organizations": [
{"id": 15, "name": "Acme Advertising"}
],
"last_login": "2024-06-25T09:00:00Z"
}
PUT /user/update
Update user profile
Request:
{
"name": "Jane M. Smith",
"avatar": "https://new-avatar-url.com/img.jpg"
}
Notification Endpoints
GET /notifications/
Get notifications for user's organization
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number |
limit | integer | No | Items per page |
unread_only | boolean | No | Filter to unread only |
Response (200):
{
"data": [
{
"id": 500,
"title": "Appeal Won!",
"content": "Your ad 23849203842934 appeal was successful",
"type": "appeal_result",
"read": false,
"created_at": "2024-06-25T10:00:00Z"
}
],
"unread_count": 3
}
PUT /notifications/{id}/read
Mark notification as read
Service: complyai-api
Base Path: /
Internal API Endpoints
These endpoints are for service-to-service communication and require API token authentication.
POST /bm_tokens
Get business manager tokens for specified BM IDs
Request:
{
"list_of_bm_ids": ["123456789012345", "987654321098765"]
}
Response (200):
{
"123456789012345": {
"token": "EAAGx...",
"org_name": "Acme Advertising",
"bm_name": "Acme BM"
}
}
POST /bm_token_from_adaccount
Get business manager token for a specific ad account
Request:
{
"ad_account_id": "123456789"
}
Response (200):
{
"id": "act_123456789",
"account_id": "123456789",
"name": "Acme - US Market",
"client_name": "Acme Advertising",
"owner_id": "123456789012345",
"facebook_business_manager_name": "Acme BM",
"access_token": "EAAGx..."
}
POST /dynamic_status
Update ad status based on webhook
Request:
{
"ad_id": "23849203842934",
"old_ad_effective_status": "ACTIVE",
"new_ad_effective_status": "DISAPPROVED",
"old_ad_status": "ACTIVE",
"new_ad_status": "ACTIVE",
"rerejected": false,
"win": false,
"ad_account_id": "act_123456789"
}
Response (200):
{
"message": "Ad with the id: 23849203842934 has changed from ACTIVE to DISAPPROVED",
"status_code": 200
}
POST /core_ad_accounts
Get ad accounts from core database
Request:
{
"org_id": 15
}
Response (200):
[
{
"adaccount_id": "act_123456789",
"business_id": "123456789012345",
"organization_name": "Acme Advertising"
}
]
Ad Data Endpoints
GET /adaccounts/
Get ad accounts with detailed data
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
limit | integer | Items per page |
status | integer | Account status filter |
country | string | Country code filter |
GET /adaccounts/{account_id}/ads
Get ads for specific ad account
POST /adaccounts/sync
Trigger manual sync for ad account
Service: complyai-maestro
Base Path: /
Webhook Endpoints
POST /webhook/meta
Receive Meta platform webhooks
Headers:
| Header | Value |
|---|---|
X-Hub-Signature-256 | HMAC signature |
Request (Ad Status Change):
{
"object": "ad_account",
"entry": [
{
"id": "123456789",
"time": 1703500800,
"changes": [
{
"field": "ad_status",
"value": {
"ad_id": "23849203842934",
"status": "DISAPPROVED"
}
}
]
}
]
}
Response (200):
{
"status": "received"
}
GET /webhook/meta
Webhook verification endpoint
Query Parameters:
| Parameter | Description |
|---|---|
hub.mode | Should be "subscribe" |
hub.verify_token | Verification token |
hub.challenge | Challenge to echo back |
AI/ML Endpoints
POST /analyze/media
Analyze media content for compliance
Request:
{
"media_url": "https://cdn.../image.jpg",
"media_type": "image",
"ad_id": "23849203842934"
}
Response (200):
{
"task_id": "celery-task-123",
"status": "processing",
"estimated_time_seconds": 30
}
GET /results/{task_id}
Get analysis results
Response (200):
{
"task_id": "celery-task-123",
"status": "completed",
"results": {
"media_score": 82.8,
"text_score": 88.2,
"overall_score": 85.5,
"issues": [
{
"type": "text_prominence",
"severity": "medium",
"description": "Text covers >50% of image"
}
]
}
}
Error Responses
All endpoints return standard error responses:
400 Bad Request
{
"error": "Bad Request",
"message": "Missing required field: ad_account_id",
"status_code": 400
}
401 Unauthorized
{
"error": "Unauthorized",
"message": "Invalid or expired token",
"status_code": 401
}
403 Forbidden
{
"error": "Forbidden",
"message": "Insufficient permissions",
"status_code": 403
}
404 Not Found
{
"error": "Not Found",
"message": "Ad account not found",
"status_code": 404
}
500 Internal Server Error
{
"error": "Internal Server Error",
"message": "Database connection failed",
"status_code": 500
}
Rate Limiting
| Endpoint Type | Rate Limit |
|---|---|
| Public API | 100 req/min |
| Authenticated API | 1000 req/min |
| Internal Service | 10000 req/min |
Rate limit headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1703500860
Pagination
All list endpoints support pagination:
{
"data": [...],
"paging": {
"current_page": 1,
"total_pages": 10,
"data_per_page": 20,
"total_data": 200
}
}
Query parameters:
page: Page number (1-indexed)limit: Items per page (max: 100)
📝 Changelog
| Date | Version | Changes |
|---|---|---|
| 2024-12 | 1.0.0 | Initial API documentation |