Quick Start
Get started with AIGC Compliance API in under 5 minutes:
- Get your API key from the dashboard
- Make your first request to
/comply - Download your compliance-ready image
Authentication
All API requests require authentication via Bearer token in the Authorization header:
Authorization: Bearer your-api-key
Security Note: Never expose your API key in client-side code. Use server-side proxy endpoints for browser applications.
๐ Professional Response Format
All API responses follow a consistent professional format with success, message, and structured data fields. This ensures immediate status checking and clear error handling across all endpoints.
๐ OAuth Authentication (Google & GitHub)
AIGC Compliance API supports OAuth 2.0 authentication for user login and signup, allowing seamless integration with Google and GitHub accounts.
โ ๏ธ Important: Terms & Conditions Requirement
All OAuth requests MUST include accept_terms: true in the request body. Users must accept Terms of Service and Privacy Policy before authentication. Requests without this field or with accept_terms: false will be rejected with HTTP 400.
Supported Providers
- Google OAuth 2.0 - Sign in with Google account
- GitHub OAuth - Sign in with GitHub account
OAuth Flow Overview
- User clicks "Sign in with Google/GitHub" on your frontend
- Frontend displays Terms & Conditions checkbox (REQUIRED)
- User accepts terms by checking the checkbox
- Frontend calls
GET /auth/oauth/{provider}/authorizeto get authorization URL - User is redirected to Google/GitHub authorization page
- After authorization, provider redirects to your callback URL with
codeandstate - Frontend calls
POST /auth/oauth/{provider}with code, state, andaccept_terms: true - Backend validates terms acceptance, exchanges code for user info, creates/updates user account
- API returns user data and API key
GET /auth/oauth/{provider}/authorize
Generate OAuth authorization URL. Replace {provider} with google or github.
Example Request
curl -X GET \ https://aigc-compliance-api-production.up.railway.app/auth/oauth/google/authorize
Example Response
{
"authorization_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...&state=...",
"provider": "google"
}
POST /auth/oauth/google
Complete Google OAuth authentication. Automatically creates new user account or logs in existing user.
Request Body (JSON)
code- Authorization code from Google callback โ requiredstate- State parameter from callback (CSRF protection) โ requiredredirect_uri- Your registered callback URL (must be HTTPS) โ requiredaccept_terms- MUST betrueโ required
Example Request
curl -X POST \
https://aigc-compliance-api-production.up.railway.app/auth/oauth/google \
-H "Content-Type: application/json" \
-d '{
"code": "4/0AeanS0a...",
"state": "eyJwcm92aWRlciI6Imdvb2dsZSIsInRpbWVzdGFtcCI6...",
"redirect_uri": "https://yourdomain.com/oauth-callback",
"accept_terms": true
}'
Success Response (200 OK)
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@gmail.com",
"name": "John Doe",
"provider": "google",
"avatar": "https://lh3.googleusercontent.com/..."
},
"api_key": "sk-abc123xyz789...",
"message": "Google OAuth authentication successful"
}
Error Response: Terms Not Accepted (400)
{
"success": false,
"error": "HTTP_400",
"message": "You must accept the terms and conditions to continue",
"details": {
"status_code": 400,
"path": "/auth/oauth/google"
},
"timestamp": "2025-10-05T20:30:37.091398"
}
โ Common Errors
accept_terms: falseโ 400 "You must accept the terms..."- Missing
accept_termsfield โ 400 "You must accept the terms..." - Invalid or expired
stateโ 400 "Invalid state parameter" - Invalid
codeโ 400 "Google token exchange failed"
POST /auth/oauth/github
Complete GitHub OAuth authentication. Same requirements as Google OAuth.
Request Body (JSON)
Same structure as Google OAuth:
code- Authorization code from GitHub โ requiredstate- State parameter (CSRF protection) โ requiredredirect_uri- Your callback URL (HTTPS) โ requiredaccept_terms- MUST betrueโ required
Example Request
curl -X POST \
https://aigc-compliance-api-production.up.railway.app/auth/oauth/github \
-H "Content-Type: application/json" \
-d '{
"code": "a1b2c3d4e5f6",
"state": "eyJwcm92aWRlciI6ImdpdGh1YiIsInRpbWVzdGFtcCI6...",
"redirect_uri": "https://yourdomain.com/oauth-callback",
"accept_terms": true
}'
Response format identical to Google OAuth.
๐ Frontend Implementation Example
1. HTML: Terms & Conditions Checkbox (REQUIRED)
<!-- STEP 1: Add Terms Checkbox BEFORE OAuth Buttons -->
<div class="terms-container">
<label>
<input type="checkbox" id="oauth-terms-checkbox" required>
I accept the
<a href="/terms" target="_blank">Terms of Service</a>
and
<a href="/privacy" target="_blank">Privacy Policy</a>
</label>
</div>
<!-- STEP 2: OAuth Buttons (disabled by default) -->
<button id="google-oauth-btn" onclick="loginWithGoogle()" disabled>
Sign in with Google
</button>
<button id="github-oauth-btn" onclick="loginWithGitHub()" disabled>
Sign in with GitHub
</button>
2. JavaScript: Enable Buttons on Terms Acceptance
// Enable OAuth buttons when terms are accepted
const termsCheckbox = document.getElementById('oauth-terms-checkbox');
const googleBtn = document.getElementById('google-oauth-btn');
const githubBtn = document.getElementById('github-oauth-btn');
termsCheckbox.addEventListener('change', (e) => {
googleBtn.disabled = !e.target.checked;
githubBtn.disabled = !e.target.checked;
});
3. JavaScript: OAuth Initiation with Terms Validation
async function loginWithGoogle() {
// Validate terms acceptance
const termsAccepted = document.getElementById('oauth-terms-checkbox').checked;
if (!termsAccepted) {
alert('Please accept the Terms of Service to continue');
return;
}
// Store terms acceptance for callback
localStorage.setItem('oauth_terms_accepted', 'true');
// Get authorization URL
const response = await fetch(
'https://aigc-compliance-api-production.up.railway.app/auth/oauth/google/authorize'
);
const data = await response.json();
// Redirect to Google
window.location.href = data.authorization_url;
}
4. JavaScript: Handle OAuth Callback
// In your oauth-callback.html page
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const termsAccepted = localStorage.getItem('oauth_terms_accepted') === 'true';
if (!termsAccepted) {
alert('Terms must be accepted');
window.location.href = '/login.html';
return;
}
// Complete OAuth authentication
const response = await fetch(
'https://aigc-compliance-api-production.up.railway.app/auth/oauth/google',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code: code,
state: state,
redirect_uri: 'https://yourdomain.com/oauth-callback',
accept_terms: true // โ CRITICAL: Must be true
})
}
);
const data = await response.json();
if (data.success) {
// Store API key and user data
localStorage.setItem('apiKey', data.api_key);
localStorage.setItem('user', JSON.stringify(data.user));
// Clear OAuth state
localStorage.removeItem('oauth_terms_accepted');
// Redirect to dashboard
window.location.href = '/dashboard.html';
} else {
alert('Authentication failed: ' + data.message);
}
Security Notes
- โ CSRF Protection: State parameter validated server-side (10-minute expiry)
- โ Terms Enforcement: 3-layer validation (UI + Frontend JS + Backend API)
- โ HTTPS Required: All redirect URIs must use HTTPS
- โ API Key Auto-Generation: New users receive API key automatically
- โ Free Plan Default: OAuth users start with free plan (100 API calls)
Main Endpoint
POST /comply
Process an image file for compliance with EU AI Act or China Cybersecurity Law. Accepts multipart/form-data for direct file uploads.
Parameters
file- Image file (PNG, JPG, JPEG, max 10MB) โ requiredregion- "EU" or "CN" โ requiredwatermark_text- Custom watermark text (plan restrictions apply) โ optionalwatermark_position- "bottom-right", "bottom-left", "top-right", "top-left" โ optionallogo_file- Logo file for watermark (PNG/JPEG, plan restrictions apply) โ optionalinclude_base64- "true" or "false" โ optional (default: false)save_to_disk- "true" or "false" โ optional (default: true)
Example Request (cURL)
curl -X POST \ https://aigc-compliance-api-production.up.railway.app/comply \ -H "Authorization: Bearer your-api-key" \ -F "file=@ai-generated-image.jpg" \ -F "region=EU" \ -F "include_base64=true" \ -F "metadata_level=detailed"
Response Schema (200 OK)
{
"success": true,
"message": "Image successfully processed for EU compliance",
"status": "compliant",
"processed_file_url": "https://aigc-compliance-api-production.up.railway.app/download/processed_eu_20250917_123456_a1b2c3d4.png",
"metadata": {
"region": "EU",
"watermark_applied": true,
"c2pa_signed": true,
"processing_time_ms": 388,
"file_size_bytes": 797024,
"compliance_version": "1.0",
"timestamp": "2025-10-04T22:15:30.123456",
"processing_method": "c2pa_metadata_and_watermark",
"region_specific_data": {
"c2pa_info": {
"c2pa_compliant": true,
"c2pa_version": "1.3",
"claim_signature": "sig_eu_123456789",
"manifest_hash": "manifest_abc123def456",
"provenance_data": {
"creator": "AI Model XYZ",
"creation_time": "2025-10-04T22:15:30Z",
"ai_generated": true,
"model_version": "v2.1"
}
},
"eu_ai_act_article": "Article 52 - Transparency Obligations",
"watermark_text": "AI Generated"
},
"processing_details": {
"original_size": [1920, 1080],
"processed_size": [1920, 1080],
"original_format": "JPEG",
"output_format": "PNG"
}
}
},
"base64_image": null // included if include_base64=true
}
// Response Headers
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9995
X-RateLimit-Reset: 2025-11-01T00:00:00Z
China Region Response Example
{
"success": true,
"message": "Image successfully processed for CN compliance",
"status": "compliant",
"processed_file_url": "https://aigc-compliance-api-production.up.railway.app/download/processed_cn_20251004_223015_xyz789.png",
"metadata": {
"region": "CN",
"watermark_applied": true,
"c2pa_signed": false,
"processing_time_ms": 445,
"file_size_bytes": 812340,
"compliance_version": "1.0",
"timestamp": "2025-10-04T22:30:15.456789",
"processing_method": "watermark_and_metadata",
"region_specific_data": {
"cn_metadata": {
"cybersecurity_law_compliance": {
"data_localization_compliant": true,
"content_review_status": "approved",
"algorithm_registration": "ALG-CN-2025-001234"
},
"watermark_info": {
"watermark_type": "visible_text",
"watermark_text": "AIGC",
"watermark_position": "bottom-right",
"watermark_applied": true
},
"content_labeling": {
"ai_generated_label": "ๆฌๅ
ๅฎน็ฑไบบๅทฅๆบ่ฝ็ๆ",
"label_visibility": "visible"
}
},
"processing_details": {
"original_size": [1920, 1080],
"processed_size": [1920, 1080],
"original_format": "PNG",
"output_format": "PNG"
}
}
},
"base64_image": null
}
Error Responses
// 400 Bad Request
{
"error": "INVALID_REGION",
"message": "Supported regions: EU, CN",
"details": {
"status_code": 400,
"provided_region": "US"
}
}
// 413 Payload Too Large
{
"error": "FILE_TOO_LARGE",
"message": "Maximum file size is 10MB",
"details": {
"status_code": 413,
"file_size_mb": 15.7,
"max_size_mb": 10
}
}
// 429 Rate Limit Exceeded
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Monthly quota exceeded",
"details": {
"status_code": 429,
"quota_limit": 10000,
"quota_used": 10000,
"reset_date": "2025-10-01T00:00:00Z"
}
}
๐จ Watermark Customization
Professional watermark control with plan-based features. Customize text, position, opacity, and size to match your brand.
Available Parameters
watermark_text
- Type: string (optional)
- Description: Custom watermark text
- Plan Restrictions:
- Free: Fixed "AIGC" (no customization)
- Starter: Up to 10 characters
- Professional: Up to 20 characters
- Enterprise: Up to 50 characters
- Example:
"Madrid 2024","ยฉ MyCompany"
watermark_position
- Type: string (optional, default: "bottom-right")
- Options: bottom-right, bottom-left, top-right, top-left, center
- Plan Restrictions:
- Free/Starter: bottom-right only
- Professional: bottom-right, bottom-left
- Enterprise: All positions
watermark_opacity
- Type: float (optional, range: 0.0-1.0)
- Description: Watermark visibility (0.0 = invisible, 1.0 = fully opaque)
- Plan Restrictions:
- Free: Fixed 0.5 (50%)
- Starter: 0.4-0.7 (40%-70%)
- Professional: 0.3-0.8 (30%-80%)
- Enterprise: 0.1-1.0 (10%-100%)
- Example:
0.65for 65% opacity
watermark_size
- Type: float (optional, range: 0.5-2.0)
- Description: Size multiplier (1.0 = default, 2.0 = double size)
- Plan Restrictions:
- Free: Fixed 1.0 (100%)
- Starter: 0.8-1.5 (80%-150%)
- Professional: 0.6-1.8 (60%-180%)
- Enterprise: 0.5-2.0 (50%-200%)
- Example:
1.5for 150% size (50% larger)
logo_file
- Type: file (optional, PNG/JPEG)
- Description: Custom logo overlay on watermark
- Plan Restrictions:
- Free/Starter: Not available
- Professional: Max 100KB
- Enterprise: Max 200KB
- Note: Logo scales with watermark_size parameter
Example: Full Customization (Enterprise)
curl -X POST "https://aigc-compliance-api-production.up.railway.app/comply" \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "file=@image.jpg" \ -F "region=EU" \ -F "watermark_text=ยฉ MyBrand 2024" \ -F "watermark_position=center" \ -F "watermark_opacity=0.75" \ -F "watermark_size=1.5" \ -F "logo_file=@logo.png" \ -F "save_to_disk=true"
Plan Features Comparison
| Feature | Free | Starter | Professional | Enterprise |
|---|---|---|---|---|
| Custom Text | โ | 10 chars | 20 chars | 50 chars |
| Positions | 1 | 1 | 2 | 5 (all) |
| Opacity Control | Fixed 50% | 40-70% | 30-80% | 10-100% |
| Size Control | Fixed 100% | 80-150% | 60-180% | 50-200% |
| Logo Upload | โ | โ | โ 100KB | โ 200KB |
| API Calls | 100 lifetime | 10K/month | 50K/month | 500K/month |
๐ก Best Practices
- Opacity: Use 0.5-0.7 for subtle watermarks, 0.7-0.9 for prominent branding
- Size: Default 1.0x works for most cases. Use 1.5x for small images or 0.7x for large images
- Position: bottom-right is least intrusive, center is most visible
- Logo + Text: Combine both for professional branding (Pro+ plans)
- Testing: Use the Dashboard to preview settings before API integration
โก Async Processing Endpoints
90% Faster Response Times - Professional & Enterprise Plans Only
Async endpoints return immediately (~250ms) while processing your image in the background. Perfect for high-volume production environments where speed matters.
POST /comply/async PROFESSIONAL+
Submit image for asynchronous processing - returns job_id immediately.
- Free Plan: โ Not available (use POST /comply instead)
- Professional Plan: โ Standard queue processing
- Enterprise Plan: โ Priority queue + guaranteed <500ms response
Headers
Authorization: Bearer your-api-key-here Content-Type: multipart/form-data
Request Parameters (multipart/form-data)
Example Request (cURL)
curl -X POST https://aigc-compliance-api-production.up.railway.app/comply/async \ -H "Authorization: Bearer your-api-key-here" \ -F "file=@image.jpg" \ -F "region=EU" \ -F "webhook_url=https://your-server.com/webhook"
Response (Success - 200) - Immediate Response in ~250ms
{
"success": true,
"message": "Job submitted for processing",
"job_id": "f8c6101e-dee3-4303-9478-9ab388fc731b",
"status": "pending",
"status_url": "/comply/async/f8c6101e-dee3-4303-9478-9ab388fc731b",
"estimated_completion_time": "2-5 seconds",
"webhook_url": "https://your-server.com/webhook",
"processing_time_ms": 246.57
}
Response (Error - 403) - Free Plan User
{
"error": "async_endpoint_not_available",
"message": "Async processing requires Professional or Enterprise plan",
"current_plan": "free",
"upgrade_url": "https://aigc-compliance.com/payment.html",
"alternative": "Use POST /comply for synchronous processing (included in Free plan)"
}
GET /comply/async/{job_id} PROFESSIONAL+
Check status and retrieve results of async processing job.
Headers
Authorization: Bearer your-api-key-here
URL Parameters
| Parameter | Type | Description |
|---|---|---|
job_id |
String (UUID) | Job ID returned from POST /comply/async |
Possible Job Statuses
pending- Job queued, waiting to startprocessing- Job currently being processedcompleted- Job finished successfully (includes result with processed image URL)failed- Job failed (includes error message)
Example Request
curl -X GET https://aigc-compliance-api-production.up.railway.app/comply/async/f8c6101e-dee3-4303-9478-9ab388fc731b \ -H "Authorization: Bearer your-api-key-here"
Response (Pending)
{
"success": true,
"job_id": "f8c6101e-dee3-4303-9478-9ab388fc731b",
"status": "pending",
"created_at": "2025-10-26T13:19:42Z",
"updated_at": "2025-10-26T13:19:42Z",
"result": null,
"error": null
}
Response (Completed)
{
"success": true,
"job_id": "f8c6101e-dee3-4303-9478-9ab388fc731b",
"status": "completed",
"created_at": "2025-10-26T13:19:42Z",
"updated_at": "2025-10-26T13:19:44Z",
"result": {
"processed_file_url": "https://res.cloudinary.com/dzl9v6xrx/image/upload/v1761484783/aigc-compliance/EU/processed_image.png",
"metadata": {
"original_size": [1024, 1024],
"processing_method": "real_c2pa_metadata_and_watermark",
"watermark_applied": true,
"c2pa_compliant": true,
"timestamp": "2025-10-26T13:19:44Z"
},
"file_hash": "2b3f8b509bb91879bd6728b876fe2dba68b6f897d8d6d48233697c56d91a9424"
},
"error": null
}
Response (Failed)
{
"success": true,
"job_id": "f8c6101e-dee3-4303-9478-9ab388fc731b",
"status": "failed",
"created_at": "2025-10-26T13:19:42Z",
"updated_at": "2025-10-26T13:19:43Z",
"result": null,
"error": "Invalid image format"
}
๐ Async vs Sync Performance Comparison
| Metric | Sync (POST /comply) | Async (POST /comply/async) |
|---|---|---|
| Initial Response Time | 2-6 seconds โ | ~250ms โ |
| Total Processing Time | 2-6 seconds | 2-5 seconds (background) |
| Blocks API Call | Yes | No |
| Webhook Support | No | Yes |
| Best For | Simple integrations | Production, high-volume |
| Available Plans | All plans | Professional & Enterprise |
๐ Webhook Notifications
When you provide a webhook_url, we'll send a POST request when processing completes:
Webhook Payload (Completed)
{
"job_id": "f8c6101e-dee3-4303-9478-9ab388fc731b",
"status": "completed",
"result": {
"processed_file_url": "https://res.cloudinary.com/.../processed_image.png",
"metadata": { ... },
"file_hash": "2b3f8b..."
}
}
Webhook Payload (Failed)
{
"job_id": "f8c6101e-dee3-4303-9478-9ab388fc731b",
"status": "failed",
"error": "Invalid image format"
}
Requirements: Your webhook endpoint must respond with 2xx status within 5 seconds.
๐ Migration Guide: Sync โ Async
Before (Sync)
import requests
response = requests.post(
"https://aigc-compliance-api-production.up.railway.app/comply",
headers={"Authorization": "Bearer your-api-key"},
files={"file": open("image.jpg", "rb")},
data={"region": "EU"}
)
# Waits 2-6 seconds here โฐ
result = response.json()
processed_url = result["processed_file_url"]
After (Async)
import requests
import time
# Step 1: Submit job (returns immediately ~250ms) โก
response = requests.post(
"https://aigc-compliance-api-production.up.railway.app/comply/async",
headers={"Authorization": "Bearer your-api-key"},
files={"file": open("image.jpg", "rb")},
data={"region": "EU", "webhook_url": "https://your-server.com/webhook"}
)
job_id = response.json()["job_id"]
# Step 2: Poll for status (or wait for webhook)
while True:
status_response = requests.get(
f"https://aigc-compliance-api-production.up.railway.app/comply/async/{job_id}",
headers={"Authorization": "Bearer your-api-key"}
)
status_data = status_response.json()
if status_data["status"] == "completed":
processed_url = status_data["result"]["processed_file_url"]
break
elif status_data["status"] == "failed":
raise Exception(status_data["error"])
time.sleep(1) # Poll every second
Best Practice: Use Webhooks
# Submit with webhook - no polling needed!
response = requests.post(
"https://aigc-compliance-api-production.up.railway.app/comply/async",
headers={"Authorization": "Bearer your-api-key"},
files={"file": open("image.jpg", "rb")},
data={
"region": "EU",
"webhook_url": "https://your-server.com/webhook" # We notify you when done
}
)
# Your server receives POST webhook when processing completes โ
Additional Endpoints
GET /health
Service health check and status information.
Example Request
curl -X GET https://aigc-compliance-api-production.up.railway.app/health
Response (Success - 200)
{
"status": "healthy",
"timestamp": "2025-09-19T10:30:00Z",
"version": "1.0.0",
"services": {
"image_processor": "operational",
"c2pa_handler": "operational",
"metadata_injector": "operational",
"redis": "connected"
}
}
GET /download/{filename}
Download processed files by filename. No authentication required.
Example Request
curl -X GET https://aigc-compliance-api-production.up.railway.app/download/processed-image.jpg
POST /api/register/register
User registration endpoint to create new accounts and get API keys.
Request Body
{
"email": "john@company.com",
"password": "SecurePass123!",
"first_name": "John",
"last_name": "Doe",
"company_name": "Your Company",
"plan": "free"
}
Response (Success - 201)
{
"success": true,
"message": "User registered successfully",
"user_id": "uuid-here",
"api_key": "your-api-key-here"
}
POST /api/login
User login endpoint to authenticate and retrieve API key.
Request Body
{
"email": "john@company.com",
"password": "SecurePass123!"
}
Response (Success - 200)
{
"success": true,
"message": "Login successful",
"api_key": "your-api-key-here",
"user_id": "uuid-here"
}
GET /api/usage
Get usage statistics for the authenticated user. Requires API key authentication.
Example Request
curl -X GET https://aigc-compliance-api-production.up.railway.app/api/usage \ -H "Authorization: Bearer your-api-key"
Response (Success - 200)
{
"user_id": "uuid-here",
"email": "john@company.com",
"plan": "professional",
"api_calls_used": 1250,
"api_calls_limit": 50000,
"remaining_calls": 48750,
"usage_percentage": 2.5,
"reset_date": "2025-11-01T00:00:00Z"
}
POST /api/cancel-subscription
Cancel active subscription. Requires API key authentication.
Request Body
{
"reason": "No longer needed" // optional
}
Response (Success - 200)
{
"success": true,
"message": "Subscription cancelled successfully",
"effective_date": "2025-11-01T00:00:00Z"
}
DELETE /api/user
Delete user account and all associated data. Requires API key authentication. This action is irreversible.
Example Request
curl -X DELETE https://aigc-compliance-api-production.up.railway.app/api/user \ -H "Authorization: Bearer your-api-key"
Response (Success - 200)
{
"success": true,
"message": "User account deleted successfully",
"deleted_user": {
"user_id": "uuid-here",
"email": "john@company.com"
},
"invalidated_keys": 1
}
POST /api/checkout/create-session
Create Stripe checkout session for subscription purchase.
Request Body
{
"plan": "professional",
"success_url": "https://yoursite.com/success",
"cancel_url": "https://yoursite.com/cancel"
}
Response (Success - 200)
{
"success": true,
"checkout_url": "https://checkout.stripe.com/...",
"session_id": "cs_test_...",
"message": "Checkout session created"
}
Legacy Endpoint (URL-based)
POST /v1/tag
DEPRECATED Process an image via URL. Use /comply for new integrations.
Request Body
{
"image_url": "https://example.com/ai-image.jpg",
"compliance_regions": ["EU"]
}
Response (Success - 200)
{
"status": "success",
"region_applied": "EU",
"file_hash": "a1b2c3d4e5f6...",
"download_url": "https://aigc-compliance-api-production.up.railway.app/download/...",
"processing_time_ms": 45
}
File Download
Use the download_url from the response to retrieve your compliance-ready image.
Download Example
# Download processed file curl -O "https://aigc-compliance-api-production.up.railway.app/download/processed_eu_20250917_123456_a1b2c3d4.png" # Or with custom filename curl -o "my-compliant-image.png" \ "https://aigc-compliance-api-production.up.railway.app/download/processed_eu_20250917_123456_a1b2c3d4.png"
Important: Download URLs expire after 7 days. Save files to your storage immediately after processing.
Watermark Customization
For CN region compliance, customize watermarks based on your subscription plan:
Plan Features
| Feature | Free | Starter | Professional | Enterprise |
|---|---|---|---|---|
| Custom Text | โ | โ (10 chars) | โ (20 chars) | โ (50 chars) |
| Logo Upload | โ | โ | โ (100KB) | โ (200KB) |
| Position Control | bottom-right only | bottom-right only | bottom-right, bottom-left | All positions |
| Default Text | "AIGC" | "AIGC" | "AIGC" | "AIGC" |
Professional Plan Example with Logo
curl -X POST "https://aigc-compliance-api-production.up.railway.app/comply" \ -H "Authorization: Bearer your-api-key" \ -F "file=@image.jpg" \ -F "region=CN" \ -F "watermark_text=Company Name" \ -F "logo_file=@logo.png" \ -F "watermark_position=bottom-left"
Security Validation
The API enforces strict watermark validation:
- Forbidden patterns: transparent, invisible, hidden, script tags
- Content filtering: Profanity and inappropriate content blocked
- Plan enforcement: Features strictly limited by subscription tier
Rate Limiting & Monitoring
All API responses include rate limiting headers to help you monitor your usage:
Rate Limit Headers
X-RateLimit-Limit: 10000 # Total calls allowed this month X-RateLimit-Remaining: 9995 # Calls remaining this month X-RateLimit-Reset: 2025-10-01T00:00:00Z # When limit resets X-RateLimit-Window: monthly # Rate limit window type
Usage Monitoring
# Check remaining quota curl -I https://aigc-compliance-api-production.up.railway.app/comply \ -H "Authorization: Bearer your-api-key"
Code Examples
# Basic compliance request curl -X POST \ https://aigc-compliance-api-production.up.railway.app/comply \ -H "Authorization: Bearer your-api-key" \ -F "file=@ai-generated-image.jpg" \ -F "region=EU" # Advanced request with all options curl -X POST \ https://aigc-compliance-api-production.up.railway.app/comply \ -H "Authorization: Bearer your-api-key" \ -F "file=@ai-generated-image.jpg" \ -F "region=CN" \ -F "include_base64=true" \ -F "metadata_level=detailed" \ -F "save_to_disk=true"
import requests
# Basic Python example
def make_compliant(image_path, region="EU"):
url = "https://aigc-compliance-api-production.up.railway.app/comply"
headers = {"Authorization": "Bearer your-api-key"}
with open(image_path, 'rb') as f:
files = {'file': f}
data = {'region': region}
response = requests.post(url, headers=headers, files=files, data=data)
return response.json()
# Advanced example with error handling
import requests
from typing import Dict, Optional
class AIGCComplianceClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://aigc-compliance-api-production.up.railway.app"
self.headers = {"Authorization": f"Bearer {api_key}"}
def make_compliant(self,
image_path: str,
region: str = "EU",
include_base64: bool = False,
metadata_level: str = "basic") -> Dict:
"""
Make an image compliant with regional requirements.
Args:
image_path: Path to image file
region: "EU" or "CN"
include_base64: Include base64 encoded result
metadata_level: "basic" or "detailed"
Returns:
API response as dictionary
"""
url = f"{self.base_url}/comply"
with open(image_path, 'rb') as f:
files = {'file': f}
data = {
'region': region,
'include_base64': str(include_base64).lower(),
'metadata_level': metadata_level
}
response = requests.post(url, headers=self.headers, files=files, data=data)
response.raise_for_status()
return response.json()
def download_file(self, download_url: str, output_path: str):
"""Download processed file from download URL."""
response = requests.get(download_url)
response.raise_for_status()
with open(output_path, 'wb') as f:
f.write(response.content)
# Usage
client = AIGCComplianceClient("your-api-key")
result = client.make_compliant("ai-image.jpg", region="EU", metadata_level="detailed")
client.download_file(result["download_url"], "compliant-image.png")
// Node.js example with form-data
const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
async function makeCompliant(imagePath, region = 'EU') {
const form = new FormData();
form.append('file', fs.createReadStream(imagePath));
form.append('region', region);
const response = await fetch('https://aigc-compliance-api-production.up.railway.app/comply', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
...form.getHeaders()
},
body: form
});
return await response.json();
}
// Browser example (requires proxy to avoid CORS)
class AIGCComplianceClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://aigc-compliance-api-production.up.railway.app';
}
async makeCompliant(file, region = 'EU', options = {}) {
const formData = new FormData();
formData.append('file', file);
formData.append('region', region);
if (options.includeBase64) {
formData.append('include_base64', 'true');
}
if (options.metadataLevel) {
formData.append('metadata_level', options.metadataLevel);
}
const response = await fetch(`${this.baseUrl}/comply`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`
},
body: formData
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
return await response.json();
}
}
// Usage
const client = new AIGCComplianceClient('your-api-key');
const fileInput = document.querySelector('#image-upload');
const file = fileInput.files[0];
client.makeCompliant(file, 'EU', { metadataLevel: 'detailed' })
.then(result => {
console.log('Compliance result:', result);
// Download file automatically
const a = document.createElement('a');
a.href = result.download_url;
a.download = 'compliant-image.png';
a.click();
})
.catch(error => console.error('Error:', error));
apiKey = $apiKey;
}
public function makeCompliant($imagePath, $region = 'EU', $options = []) {
$url = $this->baseUrl . '/comply';
$postFields = [
'file' => new CURLFile($imagePath),
'region' => $region
];
if (isset($options['include_base64'])) {
$postFields['include_base64'] = $options['include_base64'] ? 'true' : 'false';
}
if (isset($options['metadata_level'])) {
$postFields['metadata_level'] = $options['metadata_level'];
}
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $this->apiKey
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API Error: HTTP {$httpCode}");
}
return json_decode($response, true);
}
public function downloadFile($downloadUrl, $outputPath) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $downloadUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 60
]);
$fileContent = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("Download Error: HTTP {$httpCode}");
}
file_put_contents($outputPath, $fileContent);
}
}
// Usage
$client = new AIGCComplianceClient('your-api-key');
try {
$result = $client->makeCompliant(
'ai-generated-image.jpg',
'EU',
['metadata_level' => 'detailed']
);
echo "Processing successful!\n";
echo "Download URL: " . $result['download_url'] . "\n";
// Download the processed file
$client->downloadFile($result['download_url'], 'compliant-image.png');
echo "File downloaded successfully!\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
Advanced Integration Examples
Complete examples showcasing the new API capabilities:
React Component with Watermark Customization
import React, { useState } from 'react';
const ImageProcessor = ({ apiKey }) => {
const [file, setFile] = useState(null);
const [region, setRegion] = useState('CN');
const [watermarkText, setWatermarkText] = useState('');
const [watermarkPosition, setWatermarkPosition] = useState('bottom-right');
const [logoFile, setLogoFile] = useState(null);
const [processing, setProcessing] = useState(false);
const [result, setResult] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
setProcessing(true);
const formData = new FormData();
formData.append('file', file);
formData.append('region', region);
if (watermarkText) formData.append('watermark_text', watermarkText);
if (watermarkPosition) formData.append('watermark_position', watermarkPosition);
if (logoFile) formData.append('logo_file', logoFile);
try {
const response = await fetch('https://aigc-compliance-api-production.up.railway.app/comply', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiKey}` },
body: formData
});
const result = await response.json();
setResult(result);
} catch (error) {
console.error('Processing failed:', error);
} finally {
setProcessing(false);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="file" onChange={(e) => setFile(e.target.files[0])} required />
<select value={region} onChange={(e) => setRegion(e.target.value)}>
<option value="EU">EU (C2PA)</option>
<option value="CN">CN (Watermark)</option>
</select>
{region === 'CN' && (
<>
<input
type="text"
placeholder="Custom watermark text"
value={watermarkText}
onChange={(e) => setWatermarkText(e.target.value)}
/>
<select value={watermarkPosition} onChange={(e) => setWatermarkPosition(e.target.value)}>
<option value="bottom-right">Bottom Right</option>
<option value="bottom-left">Bottom Left</option>
<option value="top-right">Top Right (Enterprise)</option>
<option value="top-left">Top Left (Enterprise)</option>
</select>
<input
type="file"
accept="image/png,image/jpeg"
onChange={(e) => setLogoFile(e.target.files[0])}
placeholder="Logo file (Professional+)"
/>
</>
)}
<button type="submit" disabled={!file || processing}>
{processing ? 'Processing...' : 'Process Image'}
</button>
{result && (
<div>
<h4>Success!</h4>
<p>Processing time: {result.processing_time_ms}ms</p>
<a href={result.download_url} download>Download Result</a>
</div>
)}
</form>
);
};
Python Client with Health Monitoring
import requests
import time
from typing import Optional, Dict, Any
class AIGCComplianceClient:
def __init__(self, api_key: str, base_url: str = "https://aigc-compliance-api-production.up.railway.app"):
self.api_key = api_key
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({"Authorization": f"Bearer {api_key}"})
def check_health(self) -> Dict[str, Any]:
"""Check API health status"""
response = requests.get(f"{self.base_url}/health")
return response.json()
def process_with_retry(self, image_path: str, region: str, **kwargs) -> Dict[str, Any]:
"""Process image with automatic retry on failure"""
max_retries = 3
for attempt in range(max_retries):
try:
# Check health before processing
health = self.check_health()
if health.get("status") != "healthy":
raise Exception(f"API unhealthy: {health}")
return self.process_image(image_path, region, **kwargs)
except Exception as e:
if attempt == max_retries - 1:
raise e
print(f"Attempt {attempt + 1} failed: {e}")
time.sleep(2 ** attempt) # Exponential backoff
def process_image(self, image_path: str, region: str, **kwargs) -> Dict[str, Any]:
"""Process image for compliance"""
files = {'file': open(image_path, 'rb')}
data = {'region': region, **kwargs}
try:
response = self.session.post(f"{self.base_url}/comply", files=files, data=data)
response.raise_for_status()
return response.json()
finally:
files['file'].close()
# Usage example
client = AIGCComplianceClient("your-api-key")
# Check health
health = client.check_health()
print(f"API Status: {health['status']}")
# Process with custom watermark (Professional plan)
result = client.process_with_retry(
image_path="image.jpg",
region="CN",
watermark_text="My Company",
logo_file=open("logo.png", "rb"),
watermark_position="bottom-left"
)
SDKs & Libraries
Official SDKs for Python, Node.js, Java, PHP, and more:
Python SDK
pip install aigc-compliance
Node.js SDK
npm install @aigc-compliance/sdk
PHP SDK
composer require aigc-compliance/php-sdk
Java SDK
<dependency> <groupId>com.aigc-compliance</groupId> <artifactId>aigc-compliance-sdk</artifactId> <version>1.0.0</version> </dependency>
Go SDK
go get github.com/aigc-compliance/go-sdk
Webhooks (Enterprise)
Get real-time notifications when processing completes. Available for Pro and Enterprise plans.
Webhook Payload
{
"event": "compliance.completed",
"timestamp": "2025-09-17T12:34:56Z",
"data": {
"file_hash": "sha256:a1b2c3d4e5f6789...",
"region": "EU",
"status": "success",
"download_url": "https://aigc-compliance-api-production.up.railway.app/download/...",
"processing_time_ms": 127,
"metadata": { ... }
}
}
Configure webhook endpoints in your dashboard or contact support for API-based webhook management.
C2PA Content Credentials (EU Region)
Our API uses the official c2pa-python 0.25.0 library from the Content Authenticity Initiative (CAI) to provide real C2PA-compliant metadata injection for EU AI Act compliance.
โ C2PA Implementation Status
- Library: Official c2pa-python 0.25.0 from CAI
- Signing: ES256 (ECDSA P-256) cryptographic algorithm
- Timestamping: DigiCert Timestamp Authority integration
- Verification: Manifests validated with CAI Reader
- Membership: Official CAI member
What is C2PA?
C2PA (Coalition for Content Provenance and Authenticity) is an industry standard for content authenticity and provenance. It embeds cryptographically signed metadata (called "Content Credentials") directly into media files.
How to Use C2PA in Your API Calls
Simply set region=EU in your request - C2PA is automatic:
curl -X POST https://aigc-compliance-api-production.up.railway.app/comply \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@image.jpg" \
-F "region=EU"
# Response includes C2PA info:
{
"success": true,
"metadata": {
"c2pa_signed": true,
"region_specific_data": {
"c2pa_info": {
"c2pa_compliant": true,
"c2pa_version": "2.0",
"signed": true,
"algorithm": "es256",
"timestamp": "2025-10-25T12:32:10+00:00"
}
}
}
}
Verifying C2PA Content Credentials
Online Tools
- verify.contentauthenticity.org - Official CAI verification
- c2pa.org/verify - C2PA alliance tool
Developer Verification
# Install c2pa-python
pip install c2pa-python==0.25.0
# Verify an image
from c2pa import Reader
reader = Reader("processed_image.jpg")
manifest = reader.get_active_manifest()
if manifest:
print(f"โ Valid C2PA manifest")
print(f"Creator: {manifest['claim_generator']}")
else:
print("โ No C2PA manifest")
Technical Specifications
| Specification | Value |
|---|---|
| C2PA Version | 2.0 |
| Library | c2pa-python 0.25.0 (official CAI) |
| Algorithm | ES256 (ECDSA P-256) |
| Format | JUMBF (JPEG Universal Metadata Box) |
Learn More: Full C2PA Guide | CAI Official Site
Rate Limits
- Free Plan: 100 API calls total
- Starter: 10,000 API calls/month
- Professional: 50,000 API calls/month
- Enterprise: 500,000 API calls/month
Error Codes Reference
Complete list of error codes and their meanings:
| Code | Error Type | Description | Resolution |
|---|---|---|---|
| 400 | INVALID_REGION | Unsupported compliance region | Use "EU" or "CN" |
| 400 | INVALID_FILE_FORMAT | Unsupported image format | Use PNG, JPG, JPEG, or WebP |
| 401 | UNAUTHORIZED | Invalid or missing API key | Check Authorization header |
| 403 | FORBIDDEN | API key lacks permissions | Upgrade plan or contact support |
| 413 | FILE_TOO_LARGE | File exceeds 10MB limit | Compress image or use lower resolution |
| 429 | RATE_LIMIT_EXCEEDED | Monthly quota exhausted | Wait for reset or upgrade plan |
| 500 | INTERNAL_ERROR | Server processing error | Retry request or contact support |
Best Practices
๐ Security
- Never expose API keys in client-side code
- Use server-side proxy endpoints for browser applications
- Rotate API keys regularly (quarterly recommended)
- Monitor rate limit headers to avoid 429 errors
โก Performance
- Compress images before upload (max 10MB)
- Use optimal image formats (PNG for graphics, JPEG for photos)
- Implement retry logic with exponential backoff
- Cache download URLs for up to 7 days
๐ Monitoring
- Track rate limit headers:
X-RateLimit-Remaining - Monitor processing times via
processing_time_ms - Set up alerts for quota usage (>80% recommended)
- Log file hashes for audit trails
๐ Regional Compliance
- EU (Europe): Visible watermark "AI Generated" + C2PA metadata โ Complies with EU AI Act Article 52 (mandatory from 2026)
- CN (China): Visible watermark + metadata labeling โ Complies with CAC Deepfake Regulation (mandatory since 2023)
- Dual-layer compliance: User-facing (visible watermark) + Technical (C2PA/metadata verification)
- Test with both regions if targeting global markets
- Verify compliance metadata in API responses
- Customize watermark text per plan limits (Free: "AI Generated", Starter: 10 chars, Professional: 20 chars, Enterprise: 50 chars)
Enterprise Features
Advanced capabilities for large-scale deployments:
๐ Batch Processing
Process up to 100 images in a single request
POST /v1/batch
{
"images": [
{"url": "https://example.com/img1.jpg", "region": "EU"},
{"url": "https://example.com/img2.jpg", "region": "CN"}
]
}
๐ก Webhook Integration
Real-time notifications for async processing
POST /v1/webhooks
{
"url": "https://your-domain.com/webhook",
"events": ["compliance.completed", "batch.finished"]
}
๐ Custom Metadata
Inject custom compliance metadata
POST /comply
{
"file": "...",
"region": "EU",
"custom_metadata": {
"internal_id": "IMG-2025-001",
"department": "Marketing",
"approval_status": "approved"
}
}
๐ Advanced Analytics
Detailed usage analytics and compliance reports
GET /v1/analytics
{
"period": "monthly",
"metrics": ["processing_volume", "compliance_rate", "error_rate"]
}
Contact our sales team for enterprise pricing and custom integrations.
Frequently Asked Questions
Q: How long are download URLs valid?
A: Download URLs expire after 7 days. You should download and store files immediately after processing.
Q: What image formats are supported?
A: We support PNG, JPG, JPEG, and WebP formats up to 10MB per file.
Q: Can I process the same image multiple times?
A: Yes, but each processing request counts toward your monthly quota.
Q: Do you store processed images permanently?
A: No, images are automatically deleted after 30 days for security and privacy.
Q: How do I verify compliance metadata?
A: Use C2PA verification tools for EU compliance or our metadata validation endpoint.
Q: What's the difference between EU and CN processing?
A: EU uses C2PA metadata injection, while CN adds visible/invisible watermarks and content labels.