Enhanced Campaign Creation API Documentation
Documents a public POST endpoint for creating marketing campaigns with location targeting, creator requirements, milestones, video specs, and timeline management.
What this file does
Documents a public POST endpoint for creating marketing campaigns with location targeting, creator requirements, milestones, video specs, and timeline management.
When to use it
- Building a campaign creation API with rich optional fields
- Implementing milestone-based reward validation against budget
- Defining location targeting with Global, Country, City, and Radius types
- Creating a public endpoint that requires no authentication
Assumes this stack
Enhanced Campaign Creation API Documentation
Overview
The Enhanced Campaign Creation API provides a comprehensive endpoint for creating marketing campaigns with advanced features including location targeting, creator requirements, milestone-based rewards, video specifications, and timeline management.
Base URL: https://adx-web-backend.up.railway.app
API Version: v2
Endpoints
1. POST /api/v2/campaigns
Create a new enhanced campaign with comprehensive features and advanced targeting options.
Request
Method: POST
URL: /api/v2/campaigns
Headers:
Content-Type: application/json
Authentication: Not required - This is a public endpoint. No authentication token is needed.
Request Body
The request body must be a JSON object with the following structure:
Required Fields
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
title | string | ✅ | 5-100 chars, no <>{}[] | Campaign title |
description | string | ✅ | 10-500 chars, no <>{}[] | Campaign description |
budget | number | ✅ | 100-10,000,000 | Total campaign budget |
currency | string | ✅ | ₹, $, €, £ | Currency symbol |
type | string | ✅ | fashion, tech, travel, food, lifestyle, beauty | Campaign category |
platforms | array | ✅ | 1-8 items, valid platform names | Target social media platforms |
created_at | string | ✅ | ISO 8601 datetime | Campaign creation timestamp |
location_targeting | object | ✅ | See LocationTargeting | Location targeting settings |
timeline | object | ✅ | See Timeline | Campaign timeline |
Location Targeting (Required)
{
"type": "Global" | "Country" | "City" | "Radius",
"country": "string (required if type is Country or City)",
"city": "string (required if type is City)",
"radius_km": "number (required if type is Radius, 1-1000)",
"target_language": "string (optional)",
"latitude": "number (optional)",
"longitude": "number (optional)",
"address": "string (optional)",
"regions": ["string"] (optional, array of region names)
}
Timeline (Required)
{
"start_date": "ISO 8601 datetime (required, must be future date)",
"end_date": "ISO 8601 datetime (required, must be after start_date)",
"duration_days": "integer (required, >= 1, must match date difference)",
"posting_schedule": "string (optional, e.g., 'Flexible', 'Daily', 'Weekly')"
}
Optional Fields
| Field | Type | Description |
|---|---|---|
summary | string | Campaign summary |
full_description | string | Full campaign description |
content_type | string | Video, Image, Story, Reel, Post |
number_of_posts | integer | Number of posts required (>= 1) |
posting_schedule | string | Posting schedule description |
creative_instructions | string | Creative brief and instructions |
key_messages | array | List of key messages to convey |
requirements | array | List of campaign requirements |
video_specifications | object | Video content specifications |
creator_requirements | object | Creator requirements and demographics |
max_applicants | integer | Maximum number of applicants (>= 1) |
application_deadline | string | ISO 8601 datetime (must be before timeline.start_date) |
auto_close_when_full | boolean | Auto close when max applicants reached (default: false) |
application_instructions | string | Instructions for applicants |
milestones | array | Campaign milestones (must have valid UUID IDs) |
brand_name | string | Brand name |
contact_person | string | Contact person name |
deliverables | array | List of deliverables |
tags | array | Campaign tags |
poster_url | string | URL to campaign poster image |
verification_required | boolean | Enable verification system (default: true) |
analytics_integration | boolean | Enable analytics tracking (default: true) |
target_audience | string | Target audience summary text |
end_date | string | ISO 8601 datetime (alternative to timeline.end_date) |
Video Specifications (Optional)
{
"min_length": "integer (>= 1, seconds)",
"max_length": "integer (>= 1, > min_length, seconds)",
"quality": "HD720" | "HD1080" | "UHD4K",
"platforms": ["string"] (array of platform names)
}
Creator Requirements (Optional)
{
"min_followers": "integer (>= 0, optional)",
"max_followers": "integer (>= 0, > min_followers, optional)",
"interests": ["string"] (array of interest names),
"talent_types": ["string"] (array of talent type names),
"demographics": {
"age_range": {
"min": "integer (13-100)",
"max": "integer (13-100, > min)"
},
"gender": "string (optional)",
"location": "string (optional)"
},
"age_range": {
"min": "integer (13-100)",
"max": "integer (13-100, > min)"
},
"location": "string (optional)"
}
Milestones (Optional)
[
{
"id": "UUID string (required, valid UUID format)",
"title": "string (1-100 chars, required)",
"description": "string (1-500 chars, required)",
"due_date": "ISO 8601 datetime (required, must be within campaign timeline)",
"reward_amount": "number (> 0, required)",
"deliverables": ["string"] (array, at least 1 item required)
}
]
Valid Platform Values:
InstagramYouTubeFacebookTwitterTikTokLinkedInSnapchatPinterest
Valid Campaign Types:
fashiontechtravelfoodlifestylebeauty
Valid Content Types:
VideoImageStoryReelPost
Complete Request Example
{
"title": "Summer Fashion Campaign 2024",
"description": "Looking for creative influencers to showcase our latest summer collection",
"budget": 50000.0,
"currency": "₹",
"type": "fashion",
"platforms": ["Instagram", "YouTube"],
"created_at": "2024-01-15T10:30:00Z",
"location_targeting": {
"type": "Country",
"country": "India",
"city": "",
"radius_km": null,
"target_language": "English",
"latitude": null,
"longitude": null,
"address": "",
"regions": []
},
"timeline": {
"start_date": "2024-06-01T00:00:00Z",
"end_date": "2024-07-01T00:00:00Z",
"duration_days": 30,
"posting_schedule": "Flexible"
},
"summary": "Fashion campaign for summer collection with Instagram and YouTube promotion",
"full_description": "Complete campaign description with all details...",
"content_type": "Video",
"number_of_posts": 3,
"posting_schedule": "Flexible",
"creative_instructions": "Create engaging video content showcasing summer outfits with natural lighting and outdoor settings",
"key_messages": [
"Summer vibes",
"Trendy fashion",
"Comfortable and stylish"
],
"requirements": [
"Must show product clearly",
"Include brand hashtags",
"Tag @brandname"
],
"video_specifications": {
"min_length": 30,
"max_length": 180,
"quality": "HD1080",
"platforms": ["Instagram", "YouTube"]
},
"creator_requirements": {
"min_followers": 10000,
"max_followers": null,
"interests": ["Fashion", "Lifestyle"],
"talent_types": ["Fashion Influencer", "Lifestyle Blogger"],
"demographics": {
"age_range": {
"min": 18,
"max": 35
},
"gender": "All",
"location": "India"
},
"age_range": {
"min": 18,
"max": 35
},
"location": "India"
},
"max_applicants": 50,
"application_deadline": "2024-05-25T23:59:59Z",
"auto_close_when_full": true,
"application_instructions": "Please submit your portfolio and previous work samples. Include links to your social media profiles.",
"milestones": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"title": "Content Submission",
"description": "Submit initial content drafts",
"due_date": "2024-06-15T23:59:59Z",
"reward_amount": 10000.0,
"deliverables": ["Video draft", "Image selection"]
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"title": "Final Content",
"description": "Submit final approved content",
"due_date": "2024-06-25T23:59:59Z",
"reward_amount": 25000.0,
"deliverables": ["Final video", "Social media posts"]
},
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"title": "Campaign Completion",
"description": "Campaign goes live and metrics tracked",
"due_date": "2024-07-01T23:59:59Z",
"reward_amount": 15000.0,
"deliverables": ["Analytics report", "Engagement metrics"]
}
],
"brand_name": "Fashion Co",
"contact_person": "John Doe",
"deliverables": [
"3 Instagram posts",
"2 YouTube videos",
"1 Instagram Story series"
],
"tags": ["summer", "fashion", "influencer", "lifestyle"],
"poster_url": "https://cdn.yourapp.com/campaigns/poster-abc123.jpg",
"verification_required": true,
"analytics_integration": true,
"target_audience": "Location: Country - India\nLanguage: English\nAge Range: 18-35\nGender: All\nInterests: Fashion, Lifestyle",
"end_date": "2024-07-01T00:00:00Z"
}
Minimal Request Example
{
"title": "Simple Campaign",
"description": "This is a simple campaign description with minimum required fields",
"budget": 5000.0,
"currency": "₹",
"type": "lifestyle",
"platforms": ["Instagram"],
"created_at": "2024-01-15T10:30:00Z",
"location_targeting": {
"type": "Global",
"country": null,
"city": null,
"radius_km": null,
"target_language": null,
"latitude": null,
"longitude": null,
"address": null,
"regions": []
},
"timeline": {
"start_date": "2024-06-01T00:00:00Z",
"end_date": "2024-06-15T00:00:00Z",
"duration_days": 14,
"posting_schedule": null
}
}
Response
Status Code: 201 Created
Response Structure:
{
"success": true,
"data": {
"campaign_id": "string",
"status": "draft",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"message": "Campaign created successfully"
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the request was successful (always true for 201) |
data.campaign_id | string | Unique campaign identifier (database ID as string) |
data.status | string | Campaign status (draft for new campaigns) |
data.created_at | datetime | ISO 8601 timestamp of campaign creation |
data.updated_at | datetime | ISO 8601 timestamp of last update (initially same as created_at) |
data.message | string | Success message |
Example Response:
{
"success": true,
"data": {
"campaign_id": "123456789",
"status": "draft",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"message": "Campaign created successfully"
}
}
Validation Rules
Field-Level Validation
| Field | Validation Rule | Error Message |
|---|---|---|
title | 5-100 characters, no <>{}[] | "Title cannot contain <, >, {, }, [, ]" |
description | 10-500 characters, no <>{}[] | "Description cannot contain <, >, {, }, [, ]" |
budget | 100-10,000,000 | "budget must be between 100 and 10000000" |
currency | Must be one of: ₹, $, €, £ | "Input should be '₹', '$', '€' or '£'" |
type | Must be valid campaign type | "Input should be 'fashion', 'tech', 'travel', 'food', 'lifestyle' or 'beauty'" |
platforms | 1-8 items, valid platform names | "Invalid platform: {platform}" |
location_targeting.type | Must be Global, Country, City, or Radius | "Input should be 'Global', 'Country', 'City' or 'Radius'" |
location_targeting.country | Required if type is Country or City | "country is required when type is Country or City" |
location_targeting.city | Required if type is City | "city is required when type is City" |
location_targeting.radius_km | Required if type is Radius, 1-1000 | "radius_km is required when type is Radius" |
timeline.start_date | Must be future date | "timeline start_date must be in the future" |
timeline.end_date | Must be after start_date | "end_date must be after start_date" |
timeline.duration_days | Must match date difference | "duration_days must match the difference between start_date and end_date" |
creator_requirements.age_range.min | 13-100 | "creator_requirements.age_range.min must be between 13 and 100" |
creator_requirements.age_range.max | 13-100, > min | "creator_requirements.age_range.max must be greater than min" |
milestones[].id | Valid UUID format | "milestone id must be a valid UUID format" |
milestones[].due_date | Must be within campaign timeline | "Milestone {id} due_date must be within campaign timeline" |
Business Logic Validation
| Rule | Error Message |
|---|---|
| Total milestone rewards exceed budget | "Total milestone rewards cannot exceed campaign budget" |
| Application deadline not before timeline start | "application_deadline must be before timeline.start_date" |
| Duplicate milestone IDs | "Milestone IDs must be unique" |
| Maximum 8 platforms | "Maximum 8 platforms allowed" |
Error Responses
400 Bad Request - Business Logic Validation
{
"detail": {
"error": "Validation failed",
"details": [
{
"field": "budget",
"message": "Insufficient wallet balance. Required: 50000, Available: 30000"
}
]
}
}
422 Unprocessable Entity - Input Validation
{
"detail": [
{
"type": "string_too_short",
"loc": ["body", "title"],
"msg": "String should have at least 5 characters",
"input": "Hi"
},
{
"type": "value_error",
"loc": ["body", "title"],
"msg": "Title cannot contain <, >, {, }, [, ]",
"input": "Campaign <Test>"
}
]
}
500 Internal Server Error
{
"detail": "Internal server error occurred while creating campaign"
}
2. GET /api/v2/campaigns/health
Health check endpoint for the Campaign APIs v2 service.
Request
Method: GET
URL: /api/v2/campaigns/health
Headers:
(No headers required)
Response
Status Code: 200 OK
Response Structure:
{
"status": "healthy",
"service": "campaign_apis_v2",
"timestamp": "2024-01-15T10:30:00.123456"
}
Usage Examples
cURL Examples
Create Campaign (Minimal)
curl -X POST 'https://adx-web-backend.up.railway.app/api/v2/campaigns' \
-H 'Content-Type: application/json' \
-d '{
"title": "Summer Fashion Campaign",
"description": "Looking for creative influencers to showcase our latest summer collection",
"budget": 50000.0,
"currency": "₹",
"type": "fashion",
"platforms": ["Instagram", "YouTube"],
"created_at": "2024-01-15T10:30:00Z",
"location_targeting": {
"type": "Country",
"country": "India",
"city": null,
"radius_km": null,
"target_language": "English",
"latitude": null,
"longitude": null,
"address": null,
"regions": []
},
"timeline": {
"start_date": "2024-06-01T00:00:00Z",
"end_date": "2024-07-01T00:00:00Z",
"duration_days": 30,
"posting_schedule": "Flexible"
}
}'
Create Campaign (Full Example)
curl -X POST 'https://adx-web-backend.up.railway.app/api/v2/campaigns' \
-H 'Content-Type: application/json' \
-d '{
"title": "Tech Review Campaign",
"description": "Comprehensive tech review campaign for new smartphone",
"budget": 75000.0,
"currency": "₹",
"type": "tech",
"platforms": ["YouTube", "Instagram"],
"created_at": "2024-01-15T10:30:00Z",
"location_targeting": {
"type": "Global",
"country": null,
"city": null,
"radius_km": null,
"target_language": "English",
"latitude": null,
"longitude": null,
"address": null,
"regions": []
},
"timeline": {
"start_date": "2024-06-01T00:00:00Z",
"end_date": "2024-07-01T00:00:00Z",
"duration_days": 30,
"posting_schedule": "Flexible"
},
"video_specifications": {
"min_length": 120,
"max_length": 600,
"quality": "HD1080",
"platforms": ["YouTube"]
},
"creator_requirements": {
"min_followers": 50000,
"interests": ["Technology", "Gadgets"],
"age_range": {
"min": 18,
"max": 45
}
},
"milestones": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"title": "Unboxing Video",
"description": "Submit unboxing and first impressions video",
"due_date": "2024-06-15T23:59:59Z",
"reward_amount": 25000.0,
"deliverables": ["Unboxing video", "First impressions"]
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"title": "Full Review",
"description": "Submit comprehensive review video",
"due_date": "2024-06-30T23:59:59Z",
"reward_amount": 50000.0,
"deliverables": ["Full review video", "Performance benchmarks"]
}
]
}'
JavaScript/TypeScript Examples
Using Fetch API
interface CampaignRequest {
title: string;
description: string;
budget: number;
currency: "₹" | "$" | "€" | "£";
type: "fashion" | "tech" | "travel" | "food" | "lifestyle" | "beauty";
platforms: string[];
created_at: string;
location_targeting: {
type: "Global" | "Country" | "City" | "Radius";
country?: string | null;
city?: string | null;
radius_km?: number | null;
target_language?: string | null;
latitude?: number | null;
longitude?: number | null;
address?: string | null;
regions?: string[];
};
timeline: {
start_date: string;
end_date: string;
duration_days: number;
posting_schedule?: string | null;
};
// ... optional fields
}
async function createCampaign(
campaignData: CampaignRequest
): Promise<{ success: boolean; data: { campaign_id: string; status: string; created_at: string; updated_at: string; message: string } }> {
const headers: HeadersInit = {
'Content-Type': 'application/json',
};
const response = await fetch(
'https://adx-web-backend.up.railway.app/api/v2/campaigns',
{
method: 'POST',
headers,
body: JSON.stringify(campaignData),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail?.error || error.detail || 'Failed to create campaign');
}
return await response.json();
}
// Usage
const campaignData: CampaignRequest = {
title: "Summer Fashion Campaign 2024",
description: "Looking for creative influencers to showcase our latest summer collection",
budget: 50000.0,
currency: "₹",
type: "fashion",
platforms: ["Instagram", "YouTube"],
created_at: new Date().toISOString(),
location_targeting: {
type: "Country",
country: "India",
city: null,
radius_km: null,
target_language: "English",
latitude: null,
longitude: null,
address: null,
regions: []
},
timeline: {
start_date: "2024-06-01T00:00:00Z",
end_date: "2024-07-01T00:00:00Z",
duration_days: 30,
posting_schedule: "Flexible"
}
};
createCampaign(campaignData)
.then(result => console.log('Campaign created:', result))
.catch(error => console.error('Error:', error));
Using Axios
import axios from 'axios';
const api = axios.create({
baseURL: 'https://adx-web-backend.up.railway.app',
headers: {
'Content-Type': 'application/json',
},
});
export const createCampaign = async (
campaignData: CampaignRequest
) => {
try {
const response = await api.post('/api/v2/campaigns', campaignData);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(
error.response?.data?.detail?.error ||
error.response?.data?.detail ||
'Failed to create campaign'
);
}
throw error;
}
};
export const checkHealth = async () => {
try {
const response = await api.get('/api/v2/campaigns/health');
return response.data;
} catch (error) {
throw new Error('Health check failed');
}
};
Key Notes
-
No Authentication Required: This endpoint is public and does not require authentication. Campaigns are created without user validation.
-
Milestone Rewards: If milestones are included, the total of all milestone reward amounts must not exceed the campaign budget.
-
Date Validation:
- All milestone
due_datevalues must be within the campaign timeline (betweentimeline.start_dateandtimeline.end_date) application_deadlinemust be beforetimeline.start_datetimeline.start_datemust be in the future
- All milestone
-
Platform Values: Valid platform strings are:
Instagram,YouTube,Facebook,Twitter,TikTok,LinkedIn,Snapchat,Pinterest
-
Content Type Options:
Video,Image,Story,Reel,Post
-
Campaign Status Flow:
- New campaigns start as
draft - Can transition to:
pending→active→completedorcancelled
- New campaigns start as
-
All Data is Dynamic: All campaign data is stored dynamically from the request payload. No static or hardcoded values are used.
-
Location Targeting:
- If
typeisCountryorCity,countryis required - If
typeisCity,cityis required - If
typeisRadius,radius_kmis required (1-1000)
- If
-
Milestone IDs: Must be valid UUID format (e.g.,
550e8400-e29b-41d4-a716-446655440001) -
Age Range Validation:
- Minimum age: 13
- Maximum age: 100
- Max must be greater than min
Testing
You can test the API using:
- cURL: Use the examples provided above
- Postman: Import the request examples
- JavaScript/TypeScript: Use the provided code examples
- Python: Use the
requestslibrary with similar structure
Testing Checklist
- Minimal required fields only
- Full payload with all optional fields
- Invalid field values (validation errors)
- Milestone rewards exceed budget
- Invalid dates (past dates, wrong order)
- Invalid milestone IDs (non-UUID format)
- Invalid platform names
- Health check endpoint
Support
For issues or questions:
- Check the validation error messages for field-specific issues
- Ensure all required fields are provided
- Verify date formats are ISO 8601
- Confirm platform and type values are from the valid lists
Changelog
Version 2.0
- Enhanced request payload structure with comprehensive fields
- Location targeting with multiple types (Global, Country, City, Radius)
- Creator requirements with demographics
- Video specifications
- Milestone-based reward system
- Timeline management
- Dynamic data storage (no static values)
- Updated response format matching specification
- Public endpoint (no authentication required)
What's inside
2 endpoints, 2 request examples, 2 code examples, validation rules, error responses, testing checklist, changelog
Change this for your project
- Replace
https://adx-web-backend.up.railway.appwith your own base URL - Replace
550e8400-e29b-41d4-a716-446655440001with your own UUID generation logic - Replace
Fashion CoandJohn Doewith your own brand and contact defaults
Where it goes
Keep in docs/ or alongside the feature. Agents read it to implement against a defined contract.
Worth borrowing
- Separating field-level validation from business logic validation in a single table
- Providing both minimal and full request examples to show optionality
- Including a testing checklist that mirrors the validation rules
Related Documents
GPU Selection Guide for Large Language Models (LLMs)
Guides GPU selection for LLM inference, fine-tuning, and training by mapping model sizes, precision levels, and budgets to VRAM requirements.
Community AI Agent Skills Discovery Sources
Catalogs 50+ platforms, repositories, directories, and communities for discovering and sharing AI agent skills across multiple coding tools.
ReleaseKit - Technical Requirements Document
Specifies a Go library and CLI for release automation with conventional commit parsing, validation checks, and workflow orchestration.
api_llm Specification
Defines a workspace of thin HTTP API clients for major LLM providers with no abstraction layer and explicit developer control.