REST API
Complete guide to the AIARCO Offers REST API. Authentication, request parameters, response schema, and server-side examples.
Fetch contextually matched ads from any server-side environment using HTTP requests.
Authentication
Every request must include your channel API key in the X-AIARCO-API-Key header:
X-AIARCO-API-Key: aiarco_YOUR_CHANNEL_KEY
Get your API key from publishers.ads.aiarco.com → Channels → copy the key.
Base URL
https://ads-api.aiarco.com
Endpoints
POST /api/v1/offers
The primary endpoint. Accepts a JSON body with the user's query, context, and optional typed signals for improved targeting.
Request Body
| Field | Type | Default | Description |
|---|---|---|---|
query | string | "" | User's search query or intent text. Primary matching field. |
context | string | "" | Page context or category (e.g. "shopping", "technology"). |
placement | string | "sponsored_result" | Ad placement type. |
user_id | string | "" | Stable user identifier (hash, not PII). Used for frequency capping. |
session_id | string | "" | Session identifier for continuity across requests. |
locale | string | "en" | User locale (e.g. "en", "fr", "de"). |
device | string | "desktop" | Device type: "desktop", "mobile", or "tablet". |
geo | string | "" | ISO 3166-1 alpha-2 country code (e.g. "US", "AU"). |
limit | integer | 1 | Number of ads to return (1–8). |
signals | Signal[]? | null | Typed intent/context signals. See Signal Collection. |
Example Request
curl -X POST https://ads-api.aiarco.com/api/v1/offers \
-H "Content-Type: application/json" \
-H "X-AIARCO-API-Key: aiarco_YOUR_KEY" \
-d '{
"query": "best noise cancelling headphones 2025",
"context": "electronics",
"device": "mobile",
"geo": "US",
"limit": 3,
"user_id": "usr_abc123",
"session_id": "sess_xyz789"
}'Response
{
"offers": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Sony WH-1000XM5 Wireless Headphones",
"content": "Industry-leading noise cancelling with 30-hour battery life.",
"cta": "Shop Now",
"clickUrl": "https://ads-api.aiarco.com/api/v1/clicks/a1b2c3d4-...",
"source": "aiarco",
"ad_type": "sponsored_result",
"brand": {
"name": "Sony",
"url": "https://sony.com",
"iconUrl": "https://example.com/sony-icon.png"
},
"product": {
"title": "WH-1000XM5",
"category": "Electronics > Headphones"
},
"price": {
"amount": 348.0,
"currency": "USD",
"originalPrice": 399.99,
"discount": 13
},
"rating": {
"value": 5,
"scale": 5,
"count": 12483
}
}
]
}Do not cache offer responses. Each response creates unique impression records. Caching breaks tracking and revenue attribution.
GET /api/v1/offers
Same as POST but accepts parameters as query strings. Useful for simple integrations or testing.
GET /api/v1/offers?query=running+shoes&context=shopping&limit=2&geo=US
X-AIARCO-API-Key: aiarco_YOUR_KEYInline Signals
You can send typed intent signals directly in the offers request for improved targeting. This is equivalent to calling POST /api/v1/signals separately but saves an extra round-trip.
{
"query": "noise cancelling headphones under $300",
"context": "electronics",
"user_id": "usr_abc123",
"signals": [
{
"category": "purchase_intent",
"confidence": 0.9,
"subject": "noise cancelling headphones",
"attributes": { "budget": "under $300" }
},
{
"category": "price_sensitivity",
"confidence": 0.8,
"subject": "headphones",
"iab": {
"type": "content",
"version": "2.2",
"ids": ["607"]
}
}
]
}Server-Side Examples
Python
import requests
response = requests.post(
"https://ads-api.aiarco.com/api/v1/offers",
headers={
"Content-Type": "application/json",
"X-AIARCO-API-Key": "aiarco_YOUR_KEY",
},
json={
"query": user_query,
"context": page_context,
"limit": 2,
"user_id": hashed_user_id,
},
)
offers = response.json().get("offers", [])
for offer in offers:
print(f"{offer['title']} — {offer['clickUrl']}")Node.js
const response = await fetch("https://ads-api.aiarco.com/api/v1/offers", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-AIARCO-API-Key": "aiarco_YOUR_KEY",
},
body: JSON.stringify({
query: userQuery,
context: pageContext,
limit: 2,
user_id: hashedUserId,
}),
});
const { offers } = await response.json();
offers.forEach((offer) => {
console.log(`${offer.title} — ${offer.clickUrl}`);
});Response Headers
All offer responses include Cache-Control: no-store. Respect this header — do not cache offer responses at any layer (CDN, browser, or application).
Use Woven Offers to inject ads directly into LLM system prompts for AI-native monetization.