Skip to main content

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

EnvironmentBase URL
Productionhttps://api.gocomply.ai
Staginghttps://staging-api.gocomply.ai
Developmenthttp://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:

ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoItems per page (default: 20)
statusstringNoFilter by status
bm_idstringNoFilter 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:

ParameterTypeRequiredDescription
pageintegerNoPage number
limitintegerNoItems per page
statusstringNoFilter: ACTIVE, PAUSED, DISAPPROVED
ad_account_idstringNoFilter by ad account
date_fromdateNoFilter by date range
date_todateNoFilter 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:

ParameterTypeRequiredDescription
pageintegerNoPage number
limitintegerNoItems per page
unread_onlybooleanNoFilter 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:

ParameterTypeDescription
pageintegerPage number
limitintegerItems per page
statusintegerAccount status filter
countrystringCountry 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:

HeaderValue
X-Hub-Signature-256HMAC 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:

ParameterDescription
hub.modeShould be "subscribe"
hub.verify_tokenVerification token
hub.challengeChallenge 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 TypeRate Limit
Public API100 req/min
Authenticated API1000 req/min
Internal Service10000 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

DateVersionChanges
2024-121.0.0Initial API documentation