SSP Bidding API
The SSP (Supply-Side Platform) Bidding API provides endpoints for real-time bidding and ad serving in conversational contexts. This API follows industry standards for programmatic advertising.
Overview
The SSP integration uses a two-phase approach:
- Bidding Phase: Submit bids for ad opportunities in <1000ms>
- Ad Serving Phase: Generate and serve ads after winning auctions in <3000ms>
Base URLs
- Production:
https://app.oncue.ad/api/v1 - Development:
http://localhost:3001/api/v1
Authentication
All SSP endpoints require API key authentication:
X-API-Key: your-api-key-here
Rate Limits
- Bidding: 15 requests per second per API key
- Ad Generation: 15 requests per second per API key
- Click Tracking: No rate limits (user-initiated)
Bidding Endpoint
Submit a bid for an ad slot in a conversational context.
POST /api/v1/ssp/bid
Performance Requirements
- Response Time: <1000ms> (critical for auction participation)
- Rate Limit: 15 requests/second
- Timeout: 1000ms
Request Body
{
"countryCode": "US",
"messages": [
{
"role": "user",
"content": "I'm looking for running shoes for my daily jogs"
},
{
"role": "assistant",
"content": "I can help you find the perfect running shoes. What's your budget range?"
}
]
}
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
countryCode | string | Yes | ISO 3166-1 alpha-2 country code (e.g., "US", "GB") |
messages | array | Yes | Array of conversation messages |
messages[].role | string | Yes | Either "user" or "assistant" |
messages[].content | string | Yes | Message content |
Response
{
"bid": 2.50,
"bidId": "550e8400-e29b-41d4-a716-446655440000"
}
Response Fields
| Field | Type | Description |
|---|---|---|
bid | number | CPM bid amount in USD (e.g., 2.50 = $2.50 CPM) |
bidId | string | Unique identifier for this bid (expires in 5 minutes) |
Example Request
curl -X POST "https://app.oncue.ad/api/v1/ssp/bid" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-d '{
"countryCode": "US",
"messages": [
{
"role": "user",
"content": "I need running shoes for my daily jogs"
},
{
"role": "assistant",
"content": "I can help you find the perfect running shoes. What is your budget range?"
}
]
}'
Example Response
{
"bid": 2.50,
"bidId": "550e8400-e29b-41d4-a716-446655440000"
}
Ad Generation Endpoint
Retrieve ad content after winning an auction.
GET /api/v1/ssp/ad/{bidId}
Performance Requirements
- Response Time: <3000ms>
- Rate Limit: 15 requests/second
- Timeout: 3000ms
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bidId | string | Yes | The bid ID from the winning bid response |
Response
{
"adText": "Get the best running shoes for your daily workout. Premium quality, 30% off!",
"redirectUrl": "https://app.oncue.ad/api/v1/click/track123-xyz456-abc789"
}
Response Fields
| Field | Type | Description |
|---|---|---|
adText | string | Text content of the ad |
redirectUrl | string | Cue tracking URL that redirects to advertiser |
imageUrl | string | Optional image URL for banner ads |
nativeAd | object | Optional native ad components |
Example Request
curl -X GET "https://app.oncue.ad/api/v1/ssp/ad/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: your-api-key-here"
Example Response
{
"adText": "Get the best running shoes for your daily workout. Premium quality, 30% off!",
"redirectUrl": "https://app.oncue.ad/api/v1/click/track123-xyz456-abc789"
}
Click Tracking
All ad URLs returned by the SSP API are Cue tracking URLs that:
- Log comprehensive click analytics
- Update campaign metrics in real-time
- Redirect users to the advertiser's destination
Tracking URL Format
https://app.oncue.ad/api/v1/click/{trackingId}
Analytics Data Collected
- Click timestamp
- User agent (browser/device info)
- Referrer URL
- Anonymized IP address
- Campaign and impression IDs
- Bid amount and auction details
Error Responses
Bidding Errors
No matching campaigns:
null
Invalid request:
{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}
Rate limit exceeded:
{
"statusCode": 429,
"message": "Too Many Requests",
"error": "Rate Limit Exceeded"
}
Ad Generation Errors
Bid expired or not found:
{
"statusCode": 404,
"message": "Bid not found or expired",
"error": "Not Found"
}
Campaign not found:
{
"statusCode": 404,
"message": "Campaign not found",
"error": "Not Found"
}
Best Practices
Performance Optimization
- Timeout Handling: Set appropriate timeouts for your HTTP clients
- Connection Pooling: Reuse HTTP connections for better performance
- Retry Logic: Implement exponential backoff for transient failures
- Caching: Cache API keys and configuration data
Error Handling
- Graceful Degradation: Handle cases where no ads are available
- Logging: Log all API interactions for debugging
- Monitoring: Track response times and error rates
- Fallbacks: Have backup content when ads fail to load
Security
- API Key Protection: Never expose API keys in client-side code
- HTTPS Only: Always use HTTPS for API requests
- Rate Limiting: Respect rate limits to avoid being blocked
- Input Validation: Validate all input parameters
Testing
Test Environment
Use the development base URL for testing:
http://localhost:3001/api/v1
Test Bid Request
curl -X POST "http://localhost:3001/api/v1/ssp/bid" \
-H "Content-Type: application/json" \
-H "X-API-Key: test-api-key" \
-d '{
"countryCode": "US",
"messages": [
{
"role": "user",
"content": "I want to buy a laptop"
},
{
"role": "assistant",
"content": "I can help you find the perfect laptop. What will you be using it for?"
}
]
}'
Test Ad Generation
# Replace {bidId} with actual bid ID from previous response
curl -X GET "http://localhost:3001/api/v1/ssp/ad/{bidId}" \
-H "X-API-Key: test-api-key"
Integration Examples
JavaScript/Node.js
class CueSSP {
constructor(apiKey, baseUrl = 'https://app.oncue.ad/api/v1') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async submitBid(countryCode, messages) {
const response = await fetch(`${this.baseUrl}/ssp/bid`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey
},
body: JSON.stringify({ countryCode, messages })
});
if (!response.ok) {
throw new Error(`Bid failed: ${response.status}`);
}
return await response.json();
}
async generateAd(bidId) {
const response = await fetch(`${this.baseUrl}/ssp/ad/${bidId}`, {
headers: {
'X-API-Key': this.apiKey
}
});
if (!response.ok) {
throw new Error(`Ad generation failed: ${response.status}`);
}
return await response.json();
}
}
// Usage
const cue = new CueSSP('your-api-key');
const bid = await cue.submitBid('US', [
{ role: 'user', content: 'I need running shoes' },
{ role: 'assistant', content: 'I can help you find running shoes' }
]);
if (bid) {
const ad = await cue.generateAd(bid.bidId);
console.log('Ad generated:', ad);
}
Python
import requests
import json
class CueSSP:
def __init__(self, api_key, base_url='https://app.oncue.ad/api/v1'):
self.api_key = api_key
self.base_url = base_url
self.headers = {
'Content-Type': 'application/json',
'X-API-Key': api_key
}
def submit_bid(self, country_code, messages):
response = requests.post(
f'{self.base_url}/ssp/bid',
headers=self.headers,
json={'countryCode': country_code, 'messages': messages}
)
if response.status_code == 200:
return response.json()
return None
def generate_ad(self, bid_id):
response = requests.get(
f'{self.base_url}/ssp/ad/{bid_id}',
headers={'X-API-Key': self.api_key}
)
if response.status_code == 200:
return response.json()
return None
# Usage
cue = CueSSP('your-api-key')
bid = cue.submit_bid('US', [
{'role': 'user', 'content': 'I need running shoes'},
{'role': 'assistant', 'content': 'I can help you find running shoes'}
])
if bid:
ad = cue.generate_ad(bid['bidId'])
print('Ad generated:', ad)
Migration from Legacy API
If you're migrating from the legacy /ad-serving/request endpoint, see the Migration Guide for detailed instructions.
Support
For SSP integration support:
- Email: support@oncue.ad
- Documentation: https://docs.oncue.ad
- Status Page: https://status.oncue.ad