Developer guide
Highlight items in the menu and send events
Your server sends the menu context and Reach tells you which item to highlight. It then sends a VIEW when the item is seen and a CLICK when it is chosen. Base URL: https://adv.api.waithero.com/api/v1. The key goes in the x-api-key header, never in the browser.
The key field below is a visual simulation for the try-it panels on this page. In production everything is handled through the API, from your server.
It is only for the visual try-it panels below. In production the key never lives in the browser.
Overview
Find what to highlight
Ask for campaigns matching the city, restaurant and dish.
Send a VIEW
When a campaign becomes visible.
Send a CLICK
When the user taps it.
Restaurant categories
GET /restaurant-categories. Keep each category id: you need it for restaurantCategoryIds.
| Field | Type | Required | Description |
|---|---|---|---|
| search | string | No | Matches inside the name. |
| language | string | No | Language code, for example it or en. |
| page | integer | No | From 1. Default 1. |
| limit | integer | No | From 1 to 50. Default 20. |
curl "https://adv.api.waithero.com/api/v1/restaurant-categories?search=pizza&language=it"
Try GET /restaurant-categories
Fetch campaigns
POST /client/campaigns/search. Only location is required: an address, or areaLat and areaLon. Without products you only get HOMEPAGE campaigns.
| Field | Type | Required | Description |
|---|---|---|---|
| restaurantCategoryIds | integer[] | No | Category IDs, or send names instead. |
| restaurantCategoryNames | string[] | No | Category names, for example Pizza. |
| address | string | No | Address typed as text. |
| areaLat / areaLon | number | No | Coordinates: send both. |
| products | Product[] | No | productName and categoryName are required on the product. referenceId optional. |
Each campaign gives you id, type (HOMEPAGE, SUGGESTION, HIGHLIGHT), advisor, promotedProduct, homepage, and matchedProductReferenceIds.
curl -X POST "https://adv.api.waithero.com/api/v1/client/campaigns/search" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"address":"Milano","restaurantCategoryNames":["Pizza"],"products":[{"referenceId":"sku-123","productName":"Margherita","categoryName":"Pizza"}]}'Try POST /client/campaigns/search
Enter your API key at the top of the page to try this request.
VIEW and CLICK events
POST /events with idAdCampaign and an eventType of VIEW or CLICK. If you showed more than one, send them together with POST /events/batch.
| Field | Type | Required | Description |
|---|---|---|---|
| idAdCampaign | integer | Yes | The id search gave you. |
| eventType | VIEW | CLICK | Yes | The event you are recording. |
| idUser | integer | No | End-user id, if you want attribution. |
The response tells you how much was charged (amount) and what is left (remainingBudget). The batch returns a results[] with ok or error for each campaign.
curl -X POST "https://adv.api.waithero.com/api/v1/events" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{ "idAdCampaign": 42, "eventType": "VIEW" }'Full example
const BASE = "https://adv.api.waithero.com/api/v1";
const headers = { "Content-Type": "application/json", "x-api-key": process.env.CAMPAIGNS_API_KEY };
const categories = await fetch(`${BASE}/restaurant-categories?search=pizza`, { headers }).then((r) => r.json());
const { campaigns } = await fetch(`${BASE}/client/campaigns/search`, {
method: "POST", headers,
body: JSON.stringify({
restaurantCategoryIds: categories.data.map((c) => c.id),
areaLat: 45.4642, areaLon: 9.19,
products: [{ referenceId: "sku-123", productName: "Margherita", categoryName: "Pizza" }]
})
}).then((r) => r.json());
for (const campaign of campaigns) {
await fetch(`${BASE}/events`, { method: "POST", headers, body: JSON.stringify({ idAdCampaign: campaign.id, eventType: "VIEW" }) });
}Errors and budget
Every event takes costPerView or costPerClick out of the budget. When the budget runs out, the campaign closes and drops out of searches.
| Status | Meaning |
|---|---|
| 400 | Campaign inactive, outside its dates, or invalid event. |
| 401 | Missing or invalid API key. |
| 402 | Budget is gone. |
| 404 | Campaign not found. |