Skip to main content

Third-Party Integrations

Documentation for all external platform integrations


Overview

ComplyAI integrates with several third-party platforms to provide its ad compliance services. This documentation covers the technical details of each integration.


1. Meta (Facebook) Integration

Overview

ComplyAI uses the Meta Graph API to access ad account data, receive real-time updates via webhooks, and manage ad compliance workflows.

API Version

Current Version: v19.0
Base URL: https://graph.facebook.com/v19.0/

Authentication Types

1.1 User Access Token

  • Purpose: Initial user authentication and linking
  • Lifetime: Short-lived (1 hour) → exchanged for long-lived (60 days)
  • Obtained via: OAuth 2.0 flow
User clicks "Connect Facebook"


┌─────────────────────┐
│ Facebook OAuth │
│ Dialog opens │
└─────────────────────┘

▼ User grants permissions
┌─────────────────────┐
│ Redirect to app │
│ with auth code │
└─────────────────────┘


┌─────────────────────┐
│ Exchange code for │
│ user access token │
└─────────────────────┘


┌─────────────────────┐
│ Exchange for │
│ long-lived token │
└─────────────────────┘

1.2 System User Access Token

  • Purpose: Server-to-server API calls
  • Lifetime: Never expires (unless revoked)
  • Created in: Business Manager → System Users
# How we use system user tokens
def get_system_user_token(business_manager_id):
"""
Retrieved from org_business_accounts table
Encrypted at rest, decrypted on use
"""
org_bm = OrgBusinessAccounts.query.filter_by(
facebook_id=business_manager_id
).first()
return org_bm.client_bm_su_access_token_v2 # Uses Fernet encryption

Required Permissions

PermissionPurposeScope
ads_managementRead/manage adsRequired
ads_readRead ad performanceRequired
business_managementAccess business managerRequired
pages_read_engagementRead page dataOptional
pages_manage_adsManage page adsOptional

API Endpoints Used

Business Manager Operations

# List Business Managers user has access to
GET /me/businesses
?access_token={user_token}

Response:
{
"data": [
{
"id": "123456789012345",
"name": "Acme BM",
"permitted_roles": ["ADMIN"]
}
]
}
# Get ad accounts owned by Business Manager
GET /{bm_id}/owned_ad_accounts
?access_token={system_user_token}
&fields=id,name,account_status,currency,amount_spent
&limit=100

Response:
{
"data": [
{
"id": "act_123456789",
"name": "Acme - US Market",
"account_status": 1,
"currency": "USD",
"amount_spent": "15000.50"
}
],
"paging": {...}
}

Ad Account Operations

# Get ad account details
GET /act_{account_id}
?access_token={token}
&fields=id,name,account_status,disable_reason,amount_spent,
balance,currency,business_city,business_country_code,
business_name,funding_source,created_time,timezone_name

Response:
{
"id": "act_123456789",
"name": "Acme - US Market",
"account_status": 1,
"currency": "USD",
"amount_spent": "15000.50",
"timezone_name": "America/Los_Angeles"
}
# Get ads in ad account
GET /act_{account_id}/ads
?access_token={token}
&fields=id,name,status,effective_status,creative{
id,title,body,image_url,video_id,call_to_action_type,
object_story_spec
}
&filtering=[{"field":"effective_status","operator":"IN",
"value":["ACTIVE","PAUSED","DISAPPROVED"]}]
&limit=100

Creative/Ad Content

# Get ad creative details
GET /{ad_id}/adcreatives
?access_token={token}
&fields=id,name,title,body,image_url,image_hash,video_id,
call_to_action_type,object_story_spec,
asset_feed_spec,link_url

# Download ad image
GET /{image_hash}
?access_token={token}

Webhook Integration

Webhook Configuration

App Dashboard Settings:

  • Callback URL: https://api.gocomply.ai/webhook/meta
  • Verify Token: {VERIFY_TOKEN} (configured in environment)
  • Subscribed Fields: ad_status, ad_creative

Webhook Events Subscribed

EventFieldDescription
Ad Status Changead_statusWhen ad status changes (e.g., DISAPPROVED)
Creative Updatead_creativeWhen ad creative is modified
Account Statusaccount_statusWhen account is disabled/enabled

Webhook Payload Format

{
"object": "ad_account",
"entry": [
{
"id": "123456789",
"time": 1703500800,
"changes": [
{
"field": "ad_status",
"value": {
"ad_id": "23849203842934",
"ad_account_id": "123456789",
"status": "DISAPPROVED",
"old_status": "ACTIVE",
"effective_status": "DISAPPROVED"
}
}
]
}
]
}

Webhook Signature Verification

import hmac
import hashlib

def verify_webhook_signature(payload, signature, app_secret):
"""
Verify that webhook came from Meta
"""
expected_signature = hmac.new(
app_secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()

return hmac.compare_digest(
f"sha256={expected_signature}",
signature
)

Ad Rules Integration

ComplyAI creates automated rules in Meta to trigger webhooks:

# Create ad rule for new ad detection
POST /act_{account_id}/adrules_library
?access_token={token}

Body:
{
"name": "ComplyAI - New Ad Monitor",
"evaluation_spec": {
"evaluation_type": "TRIGGER",
"trigger": {
"type": "STATS_CHANGE",
"field": "impressions",
"value": 0,
"operator": "GREATER_THAN"
}
},
"execution_spec": {
"execution_type": "NOTIFICATION"
},
"schedule_spec": {
"schedule_type": "REALTIME"
}
}

Rate Limits

Endpoint TypeRate Limit
Standard200 calls/user/hour
Batch50 batch calls/hour
Insights60 calls/hour

Handling Rate Limits:

# Check rate limit headers
X-Business-Use-Case-Usage: {
"ad_account_id": [{
"type": "ads_insights",
"call_count": 50,
"total_cputime": 25,
"total_time": 45,
"estimated_time_to_regain_access": 0
}]
}

Error Handling

Error CodeMeaningAction
190Invalid/expired tokenRefresh token
4API rate limit reachedWait and retry
17User request limitReduce batch size
100Invalid parameterCheck field names
200Permissions errorCheck app permissions
278Account disabledNotify customer

2. Stripe Integration

Overview

Stripe handles all billing, subscriptions, and payment processing for ComplyAI.

API Version

Version: 2023-10-16
Base URL: https://api.stripe.com/v1/

Authentication

Authorization: Bearer sk_live_...

Key Objects

Customer

{
"id": "cus_ABC123",
"email": "jane@acme.com",
"name": "Acme Advertising",
"metadata": {
"organization_id": "15"
}
}

Subscription

{
"id": "sub_ABC123",
"customer": "cus_ABC123",
"status": "active",
"items": {
"data": [{
"price": {
"id": "price_professional_monthly",
"unit_amount": 29900,
"currency": "usd",
"recurring": {
"interval": "month"
}
}
}]
},
"current_period_start": 1701388800,
"current_period_end": 1704067199
}

Webhooks

Endpoint: https://api.gocomply.ai/stripe/webhook

Events Handled

EventAction
customer.subscription.createdCreate organization subscription
customer.subscription.updatedUpdate subscription dates
customer.subscription.deletedMark subscription cancelled
invoice.paidExtend subscription period
invoice.payment_failedSend payment failure notification

Webhook Signature Verification

import stripe

def verify_stripe_webhook(payload, sig_header, endpoint_secret):
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
return event
except stripe.error.SignatureVerificationError:
return None

Pricing Plans

Plan IDNameMonthlyYearly
price_starter_monthlyStarter$99$990
price_professional_monthlyProfessional$299$2,990
price_enterprise_monthlyEnterpriseCustomCustom

3. Auth0 Integration

Overview

Auth0 provides authentication and user management for ComplyAI.

Configuration

SettingValue
Domaincomplyai.auth0.com
Client ID{AUTH0_CLIENT_ID}
Audiencehttps://api.gocomply.ai

Authentication Flow

┌─────────────┐       ┌─────────────┐       ┌─────────────┐
│ Frontend │──────▶│ Auth0 │──────▶│ Core API │
│ │ │ │ │ │
│ 1. Click │ │ 2. Login │ │ 4. Validate │
│ Login │ │ Dialog │ │ Token │
│ │ │ │ │ │
│ │◀──────│ 3. Return │ │ │
│ │ │ Token │ │ │
└─────────────┘ └─────────────┘ └─────────────┘

JWT Token Structure

{
"iss": "https://complyai.auth0.com/",
"sub": "auth0|abc123",
"aud": ["https://api.gocomply.ai"],
"iat": 1703500800,
"exp": 1703587200,
"scope": "openid profile email",
"permissions": ["read:ads", "write:ads"]
}

User Metadata Sync

# Auth0 user metadata synced to users table
{
"sub_id": "auth0|abc123", # Auth0 user ID
"email": "jane@acme.com",
"name": "Jane Smith",
"email_verified": True
}

4. Slack Integration

Overview

Slack is used for internal alerts and notifications about platform events.

Webhook Configuration

ChannelWebhook URLPurpose
#alertshttps://hooks.slack.com/...Critical alerts
#winshttps://hooks.slack.com/...Appeal wins
#errorshttps://hooks.slack.com/...System errors

Message Format

# Example alert message
slack_message = {
"channel": "#alerts",
"username": "ComplyAI Bot",
"icon_emoji": ":robot_face:",
"attachments": [{
"color": "danger",
"title": "Ad Disapproved",
"fields": [
{"title": "Ad ID", "value": "23849203842934", "short": True},
{"title": "Account", "value": "Acme - US Market", "short": True},
{"title": "Reason", "value": "Policy violation"}
],
"footer": "ComplyAI Alert System",
"ts": 1703500800
}]
}

5. AWS Services

S3 (Media Storage)

BucketPurpose
complyai-media-prodProcessed media assets
complyai-backupsDatabase backups
complyai-logsApplication logs

SES (Email)

Used for transactional emails:

  • Welcome emails
  • Appeal notifications
  • Password resets

CloudWatch (Monitoring)

Custom metrics tracked:

  • API response times
  • Webhook processing time
  • ML inference latency
  • Error rates

6. Google Cloud Services

BigQuery

Used for analytics and reporting:

  • Ad performance aggregations
  • Historical trend analysis
  • Customer usage metrics

Cloud Storage

Backup storage for ML models and training data.


Integration Status Dashboard

┌────────────────────────────────────────────────────────────────┐
│ INTEGRATION STATUS │
├────────────────────────────────────────────────────────────────┤
│ │
│ Meta Graph API [████████████████████] ✅ Healthy │
│ Meta Webhooks [████████████████████] ✅ Healthy │
│ Stripe API [████████████████████] ✅ Healthy │
│ Auth0 [████████████████████] ✅ Healthy │
│ Slack [████████████████████] ✅ Healthy │
│ AWS S3 [████████████████████] ✅ Healthy │
│ AWS SES [████████████████████] ✅ Healthy │
│ │
│ Last Updated: 2024-12-25 10:00:00 UTC │
└────────────────────────────────────────────────────────────────┘

📝 Changelog

DateChange
2024-12Initial integration documentation