API Triggered Campaigns
API-Triggered Campaigns allow your system to trigger marketing communications to opted-in subscribers with a single API call. When an event happens in your system (match starts, creator goes live, product restocked), you send one API request and Optimove handles:
- Audience Resolution: Queries Preference Centre for subscribed users
- Fan-Out: Creates individual user events for all subscribers
- Orchestration: Applies frequency caps, quiet hours, scheduling rules
- Delivery: Sends via configured channels (push, email, SMS)
- Reporting: Tracks in Mission Control
Key Concept: You send 1 API call → Optimove sends to N subscribers.
Prerequisites
What You Need
- API Credentials (found in Optimove Personalize (formerly Opti-X) Admin UI → Developer Tools → API Keys):
x-api-key: Your API authentication keyx-brand-key: Your brand API key
- Event Generator ID(s) (provided by your marketing team):
- Created in Optimove Personalize Smart Campaigns
- Format: UUID (e.g.,
00000000-abcd-abcd-abcd-000000000000) - This ID is stable — if your marketing team updates the Event Generator configuration, the ID stays the same
- Preference Centre Topics keys (configured by your marketing team):
- Format: UUID (e.g.,
00000000-abcd-abcd-abcd-000000000000) - Users must opt-in to topics for delivery
- Format: UUID (e.g.,
Preference Centre Topic Creation
Important: If your use case requires creating topics dynamically (e.g., new teams, new creators, new product categories added frequently), you can use the Preference Centre API to create topics programmatically instead of manually creating them in Optimove Settings.
When to use dynamic topic creation:
- Sports: New teams/leagues added mid-season
- Streaming: New creators join your platform daily
- Retail: New product categories or brands launched regularly
- Any scenario where topics are created based on user-generated or external data
For more information:
- Preference Centre Integration Guide - Complete setup guide
Critical: Coordinate with Your Marketing Team
BEFORE implementing, align with your marketing team on each Event Generator you'll be triggering:
1. Which Event Generator(s) You'll Call
Each Event Generator has a unique ID and usually represents a specific type of event (e.g., "Match About to Start", "Goal Scored", "Creator Goes Live").
What you need from marketing:
- Event Generator ID (UUID format) - you'll use this in the API endpoint path
Example:
Event Generator: "Match Start Notifications"
Event Generator ID: 00000000-abcd-abcd-abcd-000000000000
2. Payload Schema (Context Fields) - PER Event Generator
CRITICAL: Each Event Generator requires its own payload schema. You and your marketing team must agree on the exact field names and types for the context object for each Event Generator.
Why this matters:
- Marketing uses these fields as Activity Tags in message templates
- Templates are built for a specific Event Generator's event type
- Field name mismatches = blank template fields = failed campaigns
- Each Event Generator may need completely different fields
Example - Multiple Event Generators with Different Schemas:
// Event Generator 1: "Match Start Notifications"
// ID: 00000000-abcd-abcd-abcd-000000000000
// Endpoint: POST /event-generators/00000000-abcd-abcd-abcd-000000000000/run
{
"topic_key": "00000000-abcd",
"context": {
"match_id": "string",
"match_name": "string",
"start_time": "ISO 8601",
"venue": "string",
"url": "string"
}
}
// Event Generator 2: "Goal Scored Notifications"
// ID: 11111111-xyz-xyz-xyz-111111111111
// Endpoint: POST /event-generators/11111111-xyz-xyz-xyz-111111111111/run
{
"topic_key": "00000000-abcd",
"context": {
"team_name": "string",
"player_name": "string",
"minute": "integer",
"score": "string",
"match_id": "string",
"url": "string"
}
}Notice: Different Event Generators = Different Event Generator IDs = Different payload schemas.
You call the same endpoint structure but with different IDs: POST /event-generators/{different_id}/run
You can use it in reverse approach as well and unite different event types under one Event Generator if they have the same context schema
{
"message": "string",
}
Pro Tip: Create a shared document with your marketing team listing all event types and their payload schemas. Update this document whenever schemas change.
API Specification
Base URLs
- Production:
https://opti-x.optimove.net/smart-campaigns/v1
Authentication
Headers:
x-api-key: <your-api-key>
x-brand-key: <your-brand-key>
Content-Type: application/json
- Find your keys in: Optimove Personalize Admin UI → Developer Tools → API Keys
Endpoint 1: Trigger Smart Campaign Execution
Request
POST {base_url}/event-generators/{event_generator_id}/run
Triggers an API-triggered Smart Campaign execution. Returns immediately with an execution ID; actual processing happens asynchronously.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
event_generator_id | string (UUID) | Yes | The Event Generator ID from Optimove Personalize Admin UI. This ID is stable — if your marketing team updates the Event Generator configuration, the ID remains the same. |
Request Body:
{
"topic_key": "00000000-abcd",
"context": {
"event_id": "abc123",
"event_name": "Arsenal vs Chelsea",
"start_time": "2026-02-05T20:00:00Z",
"url": "https://example.com/event/abc123"
}
}Body Fields:
| Field | Type | Required | Description |
|---|---|---|---|
topic_key | string | Yes | Preference Centre topic identifier. Topics are managed in Preference Centre or via Preference Centre API. |
context | object | Yes | Free-form JSON containing your event data. This payload is forwarded to notification templates for placeholder substitution. Ensure field names match what your marketing team configured. |
Response (202 Accepted)
{
"execution_id": "exec-abc-123-xyz",
"status": "queued"
}Response Fields:
| Field | Type | Description |
|---|---|---|
execution_id | string | Unique identifier for this execution. Use this to query execution status. |
status | string | Current execution status. Always queued on successful request acceptance. |
Status Values:
queued: Request accepted and enqueued for processingprocessing: Worker is processing the executionpublished: Execution completed successfully (events published to delivery pipeline)failed: Execution failed (check status endpoint for error details)
Important: A202 Acceptedresponse only means the request was validated and queued. It does NOT guarantee successful delivery. Always poll the status endpoint to confirm execution completion.
Error Responses
| HTTP Status | Error Code | Description | Solution |
|---|---|---|---|
| 400 | Bad Request | Invalid request body (missing required fields, invalid JSON) | Validate JSON syntax and ensure all required fields present |
| 401 | Unauthorized | Invalid or missing API key | Verify API keys in Optimove Personalize Admin → Developer Tools |
| 403 | Forbidden | API key does not have permission for this brand | Contact your Customer Success team |
| 404 | Not Found | event_generator_id not found or doesn't belong to your brand | Get correct Event Generator ID from marketing team |
| 422 | Unprocessable Entity | Event Generator exists but is not type "API Triggered (Preference Center)" | Verify Event Generator is configured for API-triggered campaigns |
| 429 | Too Many Requests | Rate limit exceeded (500 req/s per brand) | Implement exponential backoff, check Retry-After header |
| 500 | Internal Server Error | Server-side issue | Retry with exponential backoff. If persists >5min, contact support |
Endpoint 2: Get Execution Status
Request
GET {base_url}/executions/{execution_id}/status
Retrieves the current status and details of an execution.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
execution_id | string | Yes | The execution ID returned from the run endpoint |
Request Headers:
x-api-key: <your-api-key>
x-brand-key: <your-brand-key>
Response (200 OK)
{
"execution_id": "exec-abc-123-xyz",
"status": "published",
"created_at": "2026-01-16T12:00:00Z",
"updated_at": "2026-01-16T12:00:05Z",
"event_generator_id": "00000000-abcd-abcd-abcd-000000000000",
"topic_key": "event_reminders+NFL",
"audience_size": 1250
}Response Fields:
| Field | Type | Description |
|---|---|---|
execution_id | string | Execution identifier |
status | string | Current status (queued, processing, published, failed) |
created_at | string (ISO 8601) | When the execution was created |
updated_at | string (ISO 8601) | When the execution status was last updated |
event_generator_id | string (UUID) | The Event Generator ID used for this execution |
topic_key | string | The topic key used |
audience_size | integer (optional) | Number of users in resolved audience (available after resolution completes) |
error_code | string (optional) | Error code if status is failed |
error_message | string (optional) | Human-readable error message if status is failed |
Error Responses
| HTTP Status | Description | Solution |
|---|---|---|
| 401 | Invalid or missing API key | Verify API keys |
| 403 | API key does not have permission for this execution's brand | Contact Customer Success |
| 404 | Execution ID not found | Verify execution_id is correct |
| 500 | Server error | Retry with exponential backoff |
Execution Lifecycle
End-to-End Flow:
- Client calls
POST /event-generators/{id}/run - API validates and returns
202 Acceptedwithexecution_id - Worker asynchronously:
- Resolves audience using
topic_keyfrom Preference Centre - Publishes one event per user in the audience
- Updates execution status to
publishedorfailed
- Resolves audience using
- Client polls
GET /executions/{id}/statusuntil terminal status
sequenceDiagram
autonumber
participant Client as Your System
participant API as Optimove API
participant SC as Smart Campaigns Service
participant PC as Preference Centre
participant Events as Event Publishing
participant Delivery as Campaign Delivery
Note over Client: Event occurs<br/>Match starts, Goal scored
Client->>API: POST /event-generators/id/run<br/>topic_key + context payload
API->>API: Authenticate & validate
API->>SC: Create execution
SC->>SC: Generate execution_id<br/>Status: queued
API-->>Client: 202 Accepted<br/>execution_id + status
Note over Client: Response received
rect rgb(240, 248, 255)
Note over SC,Events: Async Processing
SC->>PC: Query: Who subscribed to topic_key?
PC-->>SC: Return: List of customer IDs
SC->>SC: Apply rate limiting + batching
SC->>Events: Publish N user events<br/>with context payload
SC->>SC: Update status: published
end
rect rgb(255, 250, 240)
Note over Events,Delivery: Campaign Execution
Events->>Delivery: User events trigger campaign
Delivery->>Delivery: Apply frequency caps<br/>Check quiet hours<br/>Render templates
Delivery->>Delivery: Send to channels<br/>Push, Email, SMS
end
Note over Delivery: 127,450 notifications sent
Rate Limiting
Limits:
- 500 requests/second per brand
- When exceeded, API returns
429 Too Many Requests - Check
Retry-Afterheader for wait time (seconds)
Example Implementations
Example 1: Sports Event Reminder (Full Flow)
Scenario: NFL match starting
# Step 1: Trigger execution
curl -X POST "https://opti-x.optimove.net/smart-campaigns/v1/event-generators/00000000-abcd-abcd-abcd-000000000000/run" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-brand-key: YOUR_BRAND_KEY" \
-H "Content-Type: application/json" \
-d '{
"topic_key": "0000-abcd", //e.g. event reminders
"context": {
"match_id": "nfl-2025-001",
"match_name": "San Francisco 49ers vs Kansas City Chiefs",
"league": "NFL",
"start_time": "2025-10-12T18:00:00Z",
"venue": "Levi'\''s Stadium",
"url": "https://example.com/nfl/49ers-chiefs"
}
}'
# Response:
# {
# "execution_id": "exec-abc-123-xyz",
# "status": "queued"
# }
# Step 2: Poll for status
curl -X GET "https://opti-x.optimove.net/smart-campaigns/v1/executions/exec-abc-123-xyz/status" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-brand-key: YOUR_BRAND_KEY"
# Response after processing:
# {
# "execution_id": "exec-abc-123-xyz",
# "status": "published",
# "created_at": "2025-10-12T17:45:00Z",
# "updated_at": "2025-10-12T17:45:12Z",
# "event_generator_id": "00000000-abcd-abcd-abcd-000000000000",
# "topic_key": "event_reminders+NFL",
# "audience_size": 127450
# }What happened:
- API accepted request and returned execution_id
- Worker queried Preference Centre: "Who subscribed to
event_reminders?" - Got 127,450 opted-in customer IDs
- Created 127,450 individual user events
- Trigger fired → Templates populated with context fields
- Push notifications sent to all subscribers
- Results appear in Mission Control
FAQ
Q: Can I schedule campaigns for future delivery?
A: Not in V1. API-Triggered Campaigns execute immediately.
Q: What happens if I send the same event twice?
A: Two separate executions will be created. No automatic deduplication in V1.
Q: What are the rate limits?
A: 500 requests/second per brand. Contact Customer Success if you need higher limits.
Q: Can I use this for transactional messages?
A: No. API-Triggered Smart Campaigns respect frequency caps and user preferences. For transactional messages (receipts, password resets), use Transactional APIs instead.
Updated about 4 hours ago